Ter um programa "lembre-se" de algo é fácil: escreva-o em um arquivo em algum lugar e depois leia-o mais tarde. É assim que todas as configurações / preferências funcionam. (Por falar nisso, é como os arquivos funcionam ).
(Eles podem ser armazenados como um arquivo em ~/.config/
no disco; um arquivo na RAM em /run
; um armazenamento de configurações abstratas como o GConf ou o Registro do Windows; isso varia.)
Em ambos os seus exemplos , os programas / serviços relevantes lembram não os detalhes de autenticação, mas apenas o fato de que a autenticação obteve êxito recentemente (e que a ação foi finalmente permitida) - em outras palavras, uma autorização.
-
Ao montar um disco via GUI, o pedido de montagem é enviado para UDisks , o qual solicita o polkit para confirmação. ("Ei, o usuário X está tentando montar o disco Y, isso é permitido?")
Como o polkit é um serviço de execução permanente, ele rastreia autenticações recentes inteiramente dentro da própria memória do processo, em uma lista vinculada (um GList). Você pode pesquisar seu
src/polkitbackend
para as palavrastemporary_authorization
.Se você estivesse implementando o mesmo recurso, um exemplo simplificado seria:
authorizations = list() ... authorizations.append({user: "niyasc", action: "mount drive", expires: time.now() + 3600})
Seu programa também pode usar o polkit .
-
O
sudo , por outro lado, é uma ferramenta única, por isso armazena as mesmas informações externamente - como arquivos em
(/var)/run/sudo/ts
. O registro de data e hora "last-modified" do arquivo é comparado para ver se é recente o suficiente e atualizado após cada uso.# ls -l /run/sudo/ts total 4 -rw------- 1 root grawity 80 Jul 29 12:15 /run/sudo/ts/grawity
O algoritmo em ambos os casos é, aproximadamente:
def check_authorization(user) { if has_old_authorization(user) { expires = read_authorization(user); if expires > time.now() { return true; } } success = ask_for_authentication(user); if success { store_authorization(user, expires=time.now()+3600); } return success; }
Existem outros métodos para "lembrar autenticação", mas todos eles se resumem a armazenar um monte de bytes em um arquivo:
-
Muitos aplicativos baseados em rede (por exemplo, clientes de e-mail, como o Thunderbird ou o Outlook), na verdade, armazenam o nome de usuário & própria senha diretamente no disco. Um exemplo simplificado seria o arquivo ~ / .netrc:
machine imap.example.com login [email protected] password foobar
Geralmente ele é criptografado antes de ser armazenado (o aplicativo pode usar recursos do SO, como o GNOME-Keyring, ou pode suportar uma "senha mestra"), mas no final é apenas um dado que pode ser armazenado em um arquivo .
-
Muitos aplicativos baseados em web usam cookies para lembrar o fato de que você está logado. Após o login, o servidor pede ao seu navegador para lembrar algo como "session_id = SGVsbG8gd29ybGQh", e para enviá-lo de volta a cada visita seguinte. Os navegadores geralmente têm um banco de dados baseado em texto ou baseado em SQLite de todos cookies emitidos por todos os sites (o "cookie jar").
O servidor também tem um banco de dados de 'sessão' que contém informações sobre cada cookie emitido, de modo que quando ele recebe o mesmo "session_id = SGVsbG8gd29ybGQh" ele sabe que você está niyasc:
SESSION_ID USERNAME ISSUED EXPIRES SGVsbG8gd29ybGQh niyasc Jul 29, 11:47 Aug 29, 11:47 6kJnRcg4KBAPrMJ4 fred Jun 14, 22:13 Sep 14, 22:13 ...
-
Alguns protocolos de rede, como Kerberos ou SAML, usam uma forma de cookies chamados "tickets" ou "tokens", que eles mesmos têm informações sobre quando foram emitidos e para quem . (Eles também são assinados digitalmente pelo serviço de autenticação como prova.) Isso também permite que o servidor de 'autenticação' e o de 'aplicativo' sejam separados para aumentar a segurança.
-
No entanto, outros protocolos, como SSH ou SSL / TLS, usam assinaturas digitais - em vez de ter uma senha, o cliente tem um par de chaves privado (geralmente RSA ou [EC] DSA), que também é armazenado como um arquivo. no disco - por exemplo o arquivo
~/.ssh/id_rsa
.Para cada conexão, o servidor envia um "desafio" (uma série de bytes aleatórios); o cliente assina com sua chave privada; o servidor verifica a assinatura e verifica se ela está assinada por uma das chaves "permitidas".