Emacs / CVS / OpenSSH:防止密码弹出窗口

8
我在我的Ubuntu netbook上使用GNU Emacs全屏模式编辑受版本控制的文件,当我按下C-x v v提交最新更改时,会弹出一个OpenSSH弹出窗口,要求我输入存储库所在服务器的密码。
不幸的是,由于全屏模式,弹出窗口不会置于最前面,我无法输入密码。但它仍然以某种方式是模态的,因此我也无法返回emacs,比如退出全屏模式(或做其他任何事情,如C-g)。我基本上被困住了。
作为一个emacs用户,我发现弹出窗口的想法令人讨厌;-) 所以理想情况下,我希望在minibuffer中询问ssh密码。我该如何调整我的设置以使这种情况发生?(我更喜欢每次键入密码而不是存储一个密钥对在~/.ssh/中。)

您已经添加了悬赏,但您从未回复过人们第一次提出的任何建议。我们不知道您是否尝试过那些解决方案。 - phils
@phils: 说得好(虽然我回答过另一个问题)。你自己的答案是个不错的提示,但并不完全符合我的问题。我认为sanityinc的回答是正确的方向,你也对它评论了很多(感谢你),但它并不是一个“解决方案”。 - Thomas
6个回答

7

在启动emacs之前(或在另一个shell中),您可以使用ssh-agent


原作者更喜欢使用输入密码来代替基于密钥的身份验证。然而,我认为ssh-agent和密钥对是更好的解决方案。 - stsquad

1

尝试在您的环境中以某种方式进行设置:

export CVS_RSH='ssh -o PreferredAuthentications="password"'

这样做可以停止尝试公钥身份验证,也会抑制图形ssh-askpass的显示。这是通过指定CVS将用于连接到远程服务器的SSH命令来实现的。请注意,这将适用于在设置环境变量的上下文中运行的所有CVS命令。

您还可以考虑在~/.ssh/config中进行设置。您可以为每个主机单独设置选项。 这里有一个大致显示如何设置的页面, 尽管是强制使用公钥身份验证。请注意,这将影响您用户帐户的所有SSH使用,而不仅仅是CVS。这可能正是您要寻找的,因为您似乎更喜欢避免公钥身份验证。以下是您将添加到~/.ssh/config中的示例块:

Host cvs

  Hostname cvs.your.corp
  User yourCVSusername
  PreferredAuthentications password

或者,您可以将Host cvs更改为Host cvs.your.corp,如果您现有的访问方式使用FQDN而不仅仅是主机名。

最后,您可以通过这一行来设置您的~/.ssh/config文件(或将其添加到现有文件的顶部):

PreferredAuthentications password

这将使偏好应用于所有连接到远程主机的SSH连接。

祝你好运。我希望这能让你摆脱模态对话框的困扰。


同样的解决方案适用于CVS,只需要设置CVS_RSH环境变量而不是SVN_SSH变量即可。我更新了答案以反映这一点。请注意,第二个解决方案,修改~/.ssh/config文件,将适用于所有使用SSH的程序,即使它们不支持像CVS_RSHSVN_RSH这样的环境变量。 - justis
@thomas 是的,第二个对我来说肯定有效。如果远程SSH主机禁用密码验证,则您可能需要使用“PreferredAuthentications keyboard-interactive”。 - justis
1
弹出窗口的原因是因为您的客户端和远程主机已确定publickey是您们都最喜欢的方法。然后,它看到SSH_TTY没有值,而SSH_ASKPASS有值或默认值存在且可执行。因此,它会在X11环境中弹出一个窗口,而不是写入不存在的终端。 - justis
我刚意识到在你的~/.ssh/config中设置PubkeyAuthentication no也可以起作用。 - justis
“CVS_RSH”技巧不起作用,因为它将整个字符串视为可执行文件。您仍然可以通过更改~/.ssh/config中的值来解决此问题。但我仍然不确定SSH_TTY会去哪里。虽然我不使用emacs,但我对SSH有一定了解,并正在尝试帮助解决这个问题。 - justis
显示剩余3条评论

1

这可能是ssh-askpass程序触发的,我认为它会查看DISPLAY环境变量来决定如何请求密码。如果设置了,它会弹出一个图形窗口,如果没有,则会询问TTY。

如果vcs子系统检测到用户请求密码(很可能),那么您可以为子进程取消设置$DISPLAY:

(setenv "DISPLAY" nil)

这可能会有其他负面影响,因此请查看“man ssh-askpass”,以防那里有任何有用的东西。

(免责声明:我个人使用基于ssh-agent的解决方案,强烈推荐。)


你可以使用建议或钩子将其应用于必要的代码。我看到定义了 vc-before-checkin-hookvc-checkin-hook(之后),但我猜您需要为更多内容执行此操作,而不仅仅是提交?仅针对 C-x v v 的情况,以下建议将涵盖它:(defadvice vc-next-action (around my-ssh-prompt-fix-for-vc-next-action activate) (let ((backup (getenv "DISPLAY"))) (setenv "DISPLAY" nil) ad-do-it (setenv "DISPLAY" backup))) - phils
如果运行cvs的环境会影响到它,那么另一个选项是覆盖cvs命令。vc-cvs-command硬编码“cvs”作为命令并将其传递给vc-do-command,因此一种选择是编写一个包装脚本来执行修改后的真实命令的操作(在Emacs之外)。但这可能会影响非Emacs调用cvs,因此您可以将包装器命名为“cvs”以外的其他名称,并针对vc-do-command创建一些before advice将其command参数的值更改为匹配时为“cvs”。 - phils
或者,您可以采用我在“vc-do-command”上的第一条评论中提供的建议方法,而不是使用“vc-next-action”? - phils
全局设置 DISPLAYnil 可以防止弹出窗口。但是,现在我还需要一种方法将 ssh-askpass 请求密码重定向到 minibuffer。目前,它只会在 *vc* 缓冲区中打印“权限被拒绝”并中止。 - Thomas

1

你可以让ssh通过现有连接复用所有新的连接到服务器。这意味着只要你已经打开了一个ssh连接(比如在shell中),对于同一远程主机的新连接将不会要求输入密码。我经常使用这种方法。

Host *
    ControlPath ~/.ssh/master-%r@%h:%p
    ControlMaster auto
    ServerAliveInterval 30

在 ~/.ssh/config 中进行设置。


很酷的技巧,但不完全是我在这里寻找的。但还是很好知道! - Thomas

1

在研究我的主要答案时(如上所述),我发现了适用于emacs的psvn。有关更多详细信息,请参见此SO问题/答案:SVN for Emacs:如何设置作者名称并保存密码?

我认为您可能也会喜欢了解psvn,但我认为关于在SSH上设置PreferredAuthentications值的内容更直接适用于您最初提出的问题。


1

我在这里推测,因为我既不使用CVS也不使用Emacs中的vc,但是我认为Emacs正在调用适当的程序执行提交,并且密码提示是完全外部于Emacs的。因此,我怀疑您想要做的第一件事是找出从您的shell而不是Emacs进行无GUI提交所需的选项,然后修改vc-checkin-switches(或定义vc-cvs-checkin-switches)以匹配(请参见defun vc-switches)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接