Mining Bits and Knowledge
Dobrando o Gnome Keyring Com o Python – Parte 1
27/10/10
| This post is also available in English |
A um tempo atrás eu criei uma série de posts sobre como usar o Gnome Keyring e a sua biblioteca para o Python. Devido a alguns contratempos não tive tempo de postá-los em português, agora que estou um pouco mais disponível estou reescrevendo-os para o português. Desculpe-me pela demora.
Nos últimos dias eu me ocupei principalmente com o desenvolvimento do meu projeto Tiamat. Durante esse trabalho me deparei com a necessidade de armazenar senhas para acesso remoto de hosts via SSH e Telnet. Eu nem hesitei, apenas uma palavra veio a minha mente: Gnome Keyring. Ele é simples, seguro e possui bibliotecas de binding para o Python. Então o que faltava?! Saber como usá-la. Antes de começar a trabalhar com ele, eu gostaria de discutir um pouco sobre a forma como certas aplicações armazenam nossas senhas.
É muito comum encontrar aplicações que armazenam senhas de forma “incorreta” e “insegura”. É fácil encontrar clientes IM (Internet Messengers), e-mail, dentre outros, que armazenam nossas senhas em arquivos de configuração oculto na pasta home do usuário. Algumas vezes esse arquivo de configuração que contém as senhas recebem uma “pequena proteção”, é aplicada uma senha sobre a senha. Isso quer dizer que é usando um algoritmo reversível que “ofusca” a senha. Isso simplesmente não é correto, é uma falsa segurança. A senha não é nem mesmo encriptada. Com um pequeno esforço de “força bruta” é possível descobrir a senha armazenada.
Um exemplo perfeito é o Pidgin, o famoso cliente de bate-papo. Ele armazena sua senha em /home/<nome_do_usuario>/.purple/accounts.xml. Você não acredita? Pode conferir aqui. Ainda não consegue acreditar ne?! O time de desenvolvedores inclusive se pronunciou sobre isso aqui. Vou citar o primeiro parágrafo (tradução livre):
Dobrando o Gnome Keyring Com o Python – Parte 2
07/12/10
| This post is also available in English |
No nosso último post nós começamos a introduzir como o Gnome Keyring funciona. Eu mostrei como criar um chaveiro (keyring) e seus itens utilizando o Seahorse, agora irei mostrar como fazer a mesma coisa usando o Python. Para tornar a interação entre o GNome Keyring e o Python nós precisamos da biblioteca python-gnomekeyring instalada. Vamos começar a dobrar…
Explorando o Gnome Keyring
Como o primeiro passo irei mostrar como “explorar” o Gnome Keyring. A melhor forma de começar é ter certeza que o Daemon do Gnome keyring Daemon está disponível utilizando o método is_available. Para buscar por chaveiros existentes nós utilizaremos o método list_keyring_names_sync. Se você testar isto a partir de uma console Python você receberá uma mensagem recorrente: “g_set_application_name not set”. Um exemplo:
>>> import gnomekeyring as gk >>> gk.list_keyring_names_sync() ** (process:1737): WARNING **: g_set_application_name not set. ['login', 'MyKeyring', 'session'] >>>
Isto acontece porque o daemon requer informações sobre a aplicação que está tentando acessar as informações do Gnome Keyring. Como estamos utilizando uma console Python nós não possuímos nenhum nome de aplciação. Para resolver isso, é possível importar a biblioteca gobject e utilizar o método set_application_name. Abaixo, segue um exemplo simples de listagem dos chaveiros:
Dobrando o Gnome Keyring Com o Python – Parte 3
29/12/10
| This post is also available in English |
No ultimo post Eu mostrei como criar chaveiros usando o Python e mencionei as “pequenas diferenças” com o processo de armazenamento de senhas pelo SeaHorse. Bem, acontece que, quando começamos a cavar mais fundo, essa diferença se mostrai um pouco maior. Usando o SeaHorse todo chaveiro é criado a flag “Update if Exists” com o valor False, com isso é possível criar itens idênticos no chaveiro. Essa não é uma abordagem muito segura e pode resultar em um chaveiro inconsistente. Mas ao utilizarmos a flag “Update if Exists” com o valor True, algo inesperado acontece:
#!/usr/bin/env python
import gnomekeyring as gk
import glib
APP_NAME = 'MyApp'
KEYRING_NAME = 'MyKeyring'
glib.set_application_name(APP_NAME)
keyrings = gk.list_keyring_names_sync()
# If this keyring already exist, let's remove it
if KEYRING_NAME in keyrings:
# Gnome Keyring Daemon may ask for a password here
gk.delete_sync(KEYRING_NAME)
# If anyone asks, the password is 'mypasswd'
gk.create_sync(KEYRING_NAME, 'mypasswd')
id = gk.item_create_sync(KEYRING_NAME, gk.ITEM_GENERIC_SECRET, 'magnun@Neptune:22', {'application':APP_NAME}, 'passwd', True)
print 'New host added (key=%i)'%(key)
id = gk.item_create_sync(KEYRING_NAME, gk.ITEM_GENERIC_SECRET, 'guest@Neptune:22', {'application':APP_NAME}, 'passwd', True)
print 'New host added (key=%i)'%(key)
id = gk.item_create_sync(KEYRING_NAME, gk.ITEM_GENERIC_SECRET, 'magnun@Jupiter:22', {'application':APP_NAME}, 'passwd', True)
print 'New host added (id=%i)'%(id)
Salve esse código como my_keyring_creator.py e execute-o.
Dobrando o Gnome Keyring Com o Python – Parte 4
24/01/11
| This post is also available in English |
Mantendo o assunto anterior, hoje vou escrever um pouco sobre a segurança do Gnome Keyring. Conforme apresentado no último post o Gnome Keyring é responsável por armazenar informações sensíveis em bases de dados encriptadas chamadas keyrings. Eu mostrei como criar um Keyring e armazenar alguns dados. Mas agora eu pergunto, essas informações estão seguras? Elas podem ou não estar, depende de você.
Existe uma discussão recorrente sobre o comportamento do Gnome Keyring. Quando fazemos log-on, o Gerenciado de Sessão “destranca” o chaveiro padrão com sua senha de logon para evitar muitos popups perguntando se você quer permitir que uma certa aplicação acesse o Gnome Keyring. Muitas pessoas encaram isso como uma falha de segurança, Eu não concordo totalmente. O Gnome Keyring também utiliza o nome da aplicação para confirmar as permissões. Vamos ver um exemplo, vou supor que estamos desenvolvendo uma certa aplicação chamada ‘MyApp’ e que ela irá criar um chaveiro simples. O trecho de código a seguir cuida disso:
Dobrando o Gnome Keyring Com o Python – Parte 5
31/01/11
| This post is also available in English |
Segundo a linha do meu último post, existe uma “falha de segurança” no Gnome Keyring. Ainda bem que há um mecanismo que nos traz um pouco de paz. A API do Gnome Keyring (ligbnome-keyring) nós provê uma forca de “trancar” uma chaveiro específico usando os métodos: set_lock_on_idle and set_lock_timeout.
De acordo com a documentação da API do Gnome Keyring (disponível somente em C) o método set_lock_on_idle recebe um valor booleano (True of False), o qual define se um chaveiro específico deveria ou não ser “trancado” após um tempo de inatividade. O método set_lock_timeout define após quantos segundos o chaveiro seria considerado como inativo. Uma vez que não consegui encontrar nenhuma exemplo de uso e eu não muito menos ajuda com a comunidade/desenvolvedores eu imagino que a utilização correta para esse método ser algo assim:
Dobrando o Gnome Keyring Com o Python – Parte 6
01/02/11
| This post is also available in English |
Continuando a partir do último post, irei mostrar como podemos implementar uma “wrapper class” para mudar o comportamento do Gnome Keyring. Esta não é a forma mais segura, uma vez que armazenamos a senha do chaveiro em uma variável. Mas essa abordagem é muito melhor do que deixar o chaveiro aberto para várias outras aplicações consultarem os seus dados.
Primeiramente temos que criar um a classe para gerenciar o chaveiro. Ela será responsável por:
- consulstar os keyrings existentes;
- criar chaveiros;
- deletar chaveiros;
- alterar o keyring default;
- trancar todos os chaveiros.
Após isso, precisamos de uma classe para “envolver” o chaveiros. Uma vez que o chaveiro possui diversas funcionalidades e não é minha intenção recriar todas elas eu irei mostrar somente as essenciais. Desta forma, minha classe estará apta a:
- tranchar o chaveiro;
- destrancar o chaveiro;
- mostrar se o chaveiro está ou não trancado;
- listar o identificador dos itens que compõem o chaveiro;
- dar acesso ao GnomeKeyringInfo;
- mudar a senha do chaveiro;
- listar os atributos dos itens que compõem o chaveiro;
- retornar a senha dos itens que compõem o chaveiro.
Dobrando o Gnome Keyring Com o Python – Parte 7
15/02/11
| This post is also available in English |
Alguns posts atrás eu falei sobre duas formas de resolver um problema com o Python & Gnome Keyring. A primeira forma (apresentada aqui) propôs criar uma classe que “envolve” a libgnome-keyring e a cada requisição ela destranca e tranca o chaveiro. Essa não é a forma mais perfeita e permitia a exploração de algumas falhas de segurança. A segunda solução, e também a mais elegante, é criar uma outra classe para “envolver” libgnome-keyring e adiciona a funcionalidade de temporizador de inatividade.
Neste post eu irei mostrar um exemplo de implementação. O código apresentado aqui está baseado na último código que postei. Eu alterei somente algumas linhas adicionando uma janela GTK para simular uma aplicação. Vamos ver o código:





