niy*_*asc 4 linux password-management authentication
在 linux 中,一些应用程序能够在一段时间内记住身份验证。例如,
当我们提供密码来挂载分区时,文件管理器会记住一段时间的身份验证。如果我们在安装第一个分区后立即安装另一个分区,它不会要求输入密码。
终端应用程序,如果我们执行某些任务sudo并提供密码,sudo如果在一段时间内执行,它不会要求下一步操作。
这个功能是如何实现的?如何让我的应用程序记住 root 身份验证?
让程序“记住”某些东西很容易:将它写入某个文件中,然后稍后再读回来。这就是所有设置/首选项的工作方式。(就此而言,这是常规文件的工作方式。)
(它们可能存储为~/.config/磁盘上的文件;RAM 中的文件/run;抽象设置存储,如 GConf 或 Windows 注册表;它会有所不同。)
在您的两个示例中,相关程序/服务不记得身份验证详细信息,而只记住最近身份验证成功的事实(并且最终允许该操作)——换句话说,授权。
当通过 GUI 挂载磁盘时,挂载请求被发送到UDisks,然后请求polkit确认。(“嘿,用户 X 正在尝试挂载磁盘 Y,是否允许?”)
由于 polkit 是一个永久运行的服务,它在一个链表(一个 GList)中完全在进程自己的内存中跟踪最近的身份验证。你可以搜索它src/polkitbackend的词temporary_authorization。
如果您正在实现相同的功能,一个简化的例子是:
authorizations = list()
...
authorizations.append({user: "niyasc",
action: "mount drive",
expires: time.now() + 3600})
Run Code Online (Sandbox Code Playgroud)
您的程序也可以使用 polkit。
另一方面,sudo是一个一次性工具,因此它在外部存储相同的信息——作为(/var)/run/sudo/ts. 比较文件的“上次修改”时间戳以查看它是否足够新,并在每次使用后更新。
# ls -l /run/sudo/ts
total 4
-rw------- 1 root grawity 80 Jul 29 12:15 /run/sudo/ts/grawity
Run Code Online (Sandbox Code Playgroud)
两种情况下的算法大致是:
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;
}
Run Code Online (Sandbox Code Playgroud)还有其他“记住身份验证”的方法,但所有这些都归结为在文件中存储一堆字节:
许多基于网络的应用程序(例如 Thunderbird 或 Outlook 等邮件客户端)实际上将用户名和密码本身直接存储在磁盘上。一个简化的例子是 ~/.netrc 文件:
machine imap.example.com
login niyasc@example.com
password foobar
Run Code Online (Sandbox Code Playgroud)
通常它在存储之前被加密(应用程序可能会使用诸如 GNOME-Keyring 之类的操作系统工具,或者它可能支持“主密码”),但最终它只是可以存储在文件中的一段数据。
许多基于Web的应用程序使用 cookie 来记住您已登录的事实。登录后,服务器会要求您的浏览器记住诸如“session_id=SGVsbG8gd29ybGQh”之类的内容,并在下次访问时将其发回。浏览器通常具有所有网站发布的所有 cookie 的基于文本或 SQLite 的数据库(“cookie jar”)。
服务器还有一个“会话”数据库,其中包含有关每个发出的 cookie 的信息,因此当它收到相同的“session_id=SGVsbG8gd29ybGQh”时,它知道您是 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
...
Run Code Online (Sandbox Code Playgroud)某些网络协议(例如 Kerberos 或 SAML)使用一种称为“票证”或“令牌”的 cookie 形式,这些 cookie本身具有关于何时发行以及为谁发行的信息。(它们也由身份验证服务进行数字签名作为证明。)这还允许“身份验证”服务器和“应用程序”服务器分开以提高安全性。
然而其他协议,如 SSH 或 SSL/TLS,使用数字签名——客户端根本没有密码,而是有一个私钥对(通常是 RSA 或 [EC]DSA),它也作为文件存储在磁盘上——例如~/.ssh/id_rsa文件。
对于每个连接,服务器都会发送一个“挑战”(一系列随机字节);客户端使用其私钥对其进行签名;然后服务器验证签名并检查它是否由“允许的”密钥之一签名。