win-ssh-askpass 1.05 (GANAware)GUI ssh-agent for cygwin.
http://www.ganaware.jp/archives/2006/04/winsshaskpass_1.html
win-ssh-askpass バージョンアップについてあれこれ (GANAware)このwin-ssh-askpassは、ssh-agent起動時に得た環境変数情報をWindowsのユーザ環境変数に登録してくれ、次回起動するコマンドプロンプトでもパスフレーズを聞かれなくするという物です。UNIXだとx11-ssh-askpassとか、ssh-askpass-gnomeというGUIバージョンも存在しますが、これのWindows版という所ですね。ずいぶん久しぶりに win-ssh-askpass をバージョンアップしました。
http://www.ganaware.jp/archives/2006/04/winsshaskpass_2.html
但し、win-ssh-agentはcygwinを使っており、cygwin配下でunix domain socketを使った通信を行っています。unix domain socketを使わず実装されているmsysGitでは動かないのです。他に、puttyのpagent/plinkを使った方法もありますが私が使いたい条件
- OpenSSH for windows
- msysGit付属のbashではなく、コマンドプロンプト
- cygwinは使いたくない
という事で、win-ssh-askpass-1.05のcygwin依存を無くすパッチを書いてみました。
気を付ける所は
- setenv/putenvの置き換え
- fork/execからsystemへ
以下パッチ
diff -u win-ssh-askpass-1.05.orig/agent.cpp win-ssh-askpass-1.05/agent.cpp
--- win-ssh-askpass-1.05.orig/agent.cpp 2006-04-02 10:42:24.000000000 +0900
+++ win-ssh-askpass-1.05/agent.cpp 2009-01-06 17:21:35.953125000 +0900
@@ -2,8 +2,10 @@
#include <stdlib.h>
#include <string.h>
#include <string>
+#ifdef __CYGWIN__
#include <sys/cygwin.h>
#include <sys/wait.h>
+#endif
#include <unistd.h>
#include <list>
#include <stdarg.h>
@@ -56,6 +58,7 @@
// run ssh-add
int run_ssh_add(const char *i_identityFile)
{
+#ifdef __CYGWIN__
pid_t childPID = fork();
setenv("SSH_ASKPASS", getAskpassPath().c_str(), 1);
verbose("export SSH_ASKPASS=%s\n", getAskpassPath().c_str());
@@ -95,6 +98,25 @@
else
return -1;
}
+#else
+ std::string str;
+
+ str = "SSH_ASKPASS=";
+ str += getAskpassPath().c_str();
+ putenv(str.c_str());
+ verbose("export SSH_ASKPASS=%s\n", getAskpassPath().c_str());
+
+ str = "DISPLAY=localhost:0";
+ putenv(str.c_str());
+ verbose("exec ssh-add %s\n", i_identityFile ? i_identityFile : "");
+ if (i_identityFile && !i_identityFile[0])
+ i_identityFile = NULL;
+ str = "ssh-add ";
+ if (i_identityFile) str += i_identityFile;
+ str += " < NUL 2> NUL";
+ verbose(str.c_str());
+ system(str.c_str());
+#endif
}
// http://sourceware.org/ml/cygwin/2006-02/msg00289.html
@@ -118,6 +140,7 @@
/* Convert POSIX to Win32 where necessary */
if (!strcmp(var, "PATH") ||
!strcmp(var, "LD_LIBRARY_PATH")) {
+#ifdef __CYGWIN__
winpathlist = (char *)
malloc(cygwin_posix_to_win32_path_list_buf_size(val) + 1);
if (winpathlist) {
@@ -125,12 +148,19 @@
SetEnvironmentVariable(var, winpathlist);
free(winpathlist);
}
+#else
+ SetEnvironmentVariable(var, val);
+#endif
} else if (!strcmp(var, "HOME") ||
!strcmp(var, "TMPDIR") ||
!strcmp(var, "TMP") ||
!strcmp(var, "TEMP")) {
+#ifdef __CYGWIN__
cygwin_conv_to_win32_path(val, winpath);
SetEnvironmentVariable(var, winpath);
+#else
+ SetEnvironmentVariable(val, winpath);
+#endif
} else {
SetEnvironmentVariable(var, val);
}
@@ -144,7 +174,11 @@
void run_program(char **i_argv)
{
char win32_pathname[1024];
+#ifdef __CYGWIN__
cygwin_conv_to_win32_path(i_argv[0], win32_pathname);
+#else
+ strcpy(win32_pathname, i_argv[0]);
+#endif
setup_win_environ();
if (i_argv[1])
@@ -386,7 +420,7 @@
NULL, NULL, g_hInst, this);
// show tasktray icon
- std::memset(&m_ni, 0, sizeof(m_ni));
+ memset(&m_ni, 0, sizeof(m_ni));
m_ni.cbSize = sizeof(m_ni);
m_ni.uID = ID_TaskTrayIcon;
m_ni.hWnd = m_hwndTaskTray;
@@ -513,7 +547,13 @@
verbose("DISPLAY=%s\n", getenv("DISPLAY"));
std::string askpassPath(getAskpassPath());
+#ifdef __CYGWIN__
setenv("SSH_ASKPASS", askpassPath.c_str(), 1);
+#else
+ std::string str("SSH_ASKPASS=");
+ str += askpassPath;
+ putenv(str.c_str());
+#endif
writeRegistry(HKEY_CURRENT_USER, "Environment", "SSH_AGENT_PID",
getenv("SSH_AGENT_PID"));
verbose("export SSH_AGENT_PID=%s\n", getenv("SSH_AGENT_PID"));
diff -u win-ssh-askpass-1.05.orig/misc.cpp win-ssh-askpass-1.05/misc.cpp
--- win-ssh-askpass-1.05.orig/misc.cpp 2002-09-23 03:32:39.000000000 +0900
+++ win-ssh-askpass-1.05/misc.cpp 2009-01-06 17:18:43.656250000 +0900
@@ -1,5 +1,7 @@
#include "misc.h"
+#ifdef __CYGWIN__
#include <sys/cygwin.h>
+#endif
// instance
HINSTANCE g_hInst = NULL;
@@ -74,9 +76,16 @@
// get the path of win-ssh-askpass.exe
std::string getSelfPath()
{
+#ifdef __CYGWIN__
char win32_pathname[1024];
GetModuleFileName(NULL, win32_pathname, NUMBER_OF(win32_pathname));
char posix_pathname[1024];
cygwin_conv_to_posix_path(win32_pathname, posix_pathname);
return posix_pathname;
+#else
+ char win32_pathname[1024], *ptr = win32_pathname;
+ GetModuleFileName(NULL, win32_pathname, NUMBER_OF(win32_pathname));
+ while (*ptr++) if (*ptr == '\\') *ptr = '/';
+ return win32_pathname;
+#endif
}
これを適応すると、mingw32だけでビルド出来る様になります(mingw32-make)。なお、cygwinでビルドすればこれまで通りのモジュールが出来上がります。ビルド出来たら、win-ssh-agentを起動します。すると
の様に入力ダイアログが表示されます。ここにパスフレーズを入力すれば、後は次回から起動するコマンドプロンプトで
と環境変数が引き継がれる事になります。
「Big Sky :: Windowsでもssh-agentとssh-addを使ってパスフレーズ入力を省略する。」で書いた、setxがあればwin-ssh-agentを使わなくても美味く行くのですが、コマンドプロンプトが出ないので少しカッコよくなりました。
これをWindowsのスタートアップに入れておけば初回にパスフレーズを入力した後は、sshパスフレーズを聞かれる事無くsshが行える様になります。
win-ssh-agent++
よろしければどうぞ。
というか私くらいしか、必要ないか...