我在 Debian Stretch 机器上使用 Subversion 客户端(版本 1.9.5 r1770682,从默认软件包存储库安装),我只有 SSH 访问权限。我正在通过 HTTPS 连接到 Subversion 存储库,并希望避免每次执行svn up
或svn ci
命令时都必须重新输入密码。我还想避免将密码以明文形式存储在磁盘上。
SVN书建议我应该能够使用GPG-Agent作为缓存密码的一种手段。尽管svn --version
报告GPG-Agent身份验证凭据缓存应该可用,但我在使其工作时遇到了一些麻烦。
关于 GPG,我创建了一个 GPG 密钥对,将export GPG_TTY=$(tty)
添加到我的.profile
文件中,并通过加密和解密一段文本来验证 GPG 的工作原理。
关于 Subversion,在我的.subversion/config
文件中,我设置了以下内容:
$ grep '^[^#]' < .subversion/config
[auth]
password-stores = gpg-agent
[helpers]
[tunnels]
[miscellany]
[auto-props]
[working-copy]
在我的.subversion/servers
文件中,我设置了以下内容:
$ grep '^[^#]' < .subversion/servers
[groups]
[global]
store-passwords = yes
store-plaintext-passwords = no
但是,当我执行svn
命令时,不会缓存任何密码。有人对我可能做错了什么有任何建议吗?有没有人成功地使用GPG-Agent来缓存HTTPS密码?(也许此凭据缓存仅用于SVN + SSH连接?
任何帮助将不胜感激。
我终于找到了解决问题的方法,从上面的 Roman 的建议开始,再次研究它。Subversion 客户端的 GPG-Agent 认证源代码中find_gpg_agent_socket
函数的注释确实解释了:
如果设置了
$GPG_AGENT_INFO
,则优先,否则将使用$GNUPGHOME
。(...
作为参考
GPG_AGENT_INFO
由3个分隔字段组成。套接字的路径,gpg-agent 进程的 pid,最后是代理使用的协议版本。
GPG-Agent套接字的路径可以通过在命令行上调用gpgconf --list-dirs agent-socket
轻松找到。$GPG_AGENT_INFO
变量的另外两个段不被 Subversion 客户端使用,因此不必设置。
因此,我在.profile
文件的末尾添加了以下代码:
export GPG_TTY=$(tty)
export GPG_AGENT_INFO=`gpgconf --list-dirs agent-socket | tr -d 'n' && echo -n ::`
这会将$GPG_TTY
变量设置为当前终端,将$GPG_AGENT_INFO
变量设置为 GPG-Agent 套接字,后跟两个冒号字符(即 Subversion 源代码所期望的格式)。
Subversion 似乎将存储库的身份验证设置缓存在~/.subversion/auth
中,所以我发现有必要在正确使用 GPG-Agent 之前清除该目录:
rm -rf ~/.subversion/auth
启动新会话后,您应该能够验证是否正确设置了$GPG_AGENT_INFO
变量:echo $GPG_AGENT_INFO
应输出类似/run/user/1000/gnupg/S.gpg-agent::
的内容(其中1000
是当前用户的 uid)。
执行 Subversion 命令(例如svn up
)时,您的密码将在第一次被提示:
Updating '.':
Enter your Subversion password for <https://example.com:443> Subversion Repository
Password for 'username': :
At revision 123.
之后一段时间内对同一存储库执行第二个 Subversion 命令时,Subversion 应使用 GPG-Agent 缓存的密码:
Updating '.':
At revision 123.
编辑:我的印象是,当第一次使用存储库时(即,当它尚未存在于Subversion的缓存中时),密码只有在输入两次后才能由GPG-Agent正确保存。
这个线程似乎给出了一个提示:https://groups.google.com/forum/#!topic/subversion_users/WS8Cr7mAovQ
我在 Ubuntu 上运行 Xfce,我遇到了同样的问题。显然,原因是未设置$GPG_AGENT_INFO
环境变量。手动运行/etc/X11/Xsession.d/90gpg 代理脚本(设置此变量)确实对我有帮助。