From e65f330f97ebfd51d73be353766e925d58e04d74 Mon Sep 17 00:00:00 2001 From: BetzF Date: Thu, 1 Feb 2018 16:12:47 +0100 Subject: [PATCH 01/10] Added debug target --- Makefile | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 2c45f85..62952e9 100644 --- a/Makefile +++ b/Makefile @@ -12,10 +12,14 @@ DOCS = README.md COPYING COPYING.PuTTY OBJS = $(SRCS:.c=.o) DEPS = $(OBJS:.o=.d) -.PHONY: clean all install uninstall cscope +.PHONY: clean all debug install uninstall cscope +all: CFLAGS += -O2 all: $(PROGRAM) +debug: CFLAGS += -O0 -DDEBUG -g +debug: $(PROGRAM) + clean: rm -f cscope.out $(PROGRAM) $(OBJS) $(DEPS) @@ -34,7 +38,8 @@ $(PROGRAM): $(OBJS) $(CC) $(LDFLAGS) $(LOADLIBES) $^ $(LDLIBS) -o $@ CC = gcc -CFLAGS = -O2 -Werror -Wall -Wextra -MMD +CFLAGS = -Werror -Wall -Wextra -MMD + CSCOPE = $(firstword $(shell which cscope mlcscope 2>/dev/null) false) cscope: cscope.out From eedc63ca0d996567ceaf026e881df51645554d3e Mon Sep 17 00:00:00 2001 From: BetzF Date: Thu, 1 Feb 2018 16:13:33 +0100 Subject: [PATCH 02/10] Added CMD to shell options --- main.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 53 insertions(+), 13 deletions(-) diff --git a/main.c b/main.c index 48217f9..77ea3dd 100755 --- a/main.c +++ b/main.c @@ -33,7 +33,8 @@ for (fd = 0; fd < FD_SETSIZE; ++fd) \ if (FD_ISSET(fd, set)) -typedef enum {BOURNE, C_SH, FISH} shell_type; + +typedef enum {BOURNE, C_SH, FISH, CMD} shell_type; struct fd_buf { int recv, send; @@ -89,9 +90,27 @@ cleanup_signal(int sig) // Create a temporary path for the socket. static void -create_socket_path(char* sockpath, size_t len) +create_socket_path(const shell_type opt_sh, char* sockpath, size_t len) { - char tempdir[] = "/tmp/ssh-XXXXXX"; + char *tempdir; + + if (opt_sh == CMD) { + tempdir = malloc(strlen(getenv("TEMP")) + 12); + if(tempdir == NULL) { + fprintf(stderr, "Memory allocation failed"); + return; + } + + snprintf(tempdir, strlen(getenv("TEMP")) + 12, "%s/ssh-XXXXXX", getenv("TEMP")); + } else { + tempdir = malloc(strlen("/tmp/ssh-XXXXXX") + 1); + if(tempdir == NULL) { + fprintf(stderr, "Memory allocation failed"); + return; + } + + snprintf(tempdir, strlen("/tmp/ssh-XXXXXX") + 1, "/tmp/ssh-XXXXXX"); + } if (!mkdtemp(tempdir)) cleanup_warn("mkdtemp"); @@ -294,7 +313,7 @@ do_agent_loop(int sockfd) // Quote and escape a string for shell eval. // Caller must free the result. static char * -shell_escape(const char *s) +shell_escape(const char *s, const shell_type opt_sh) { // The pessimistic growth is *4, when every character is ' mapped to '\''. // (No need to be clever.) Add room for outer quotes and terminator. @@ -304,7 +323,8 @@ shell_escape(const char *s) return NULL; char c, *out = mem; - *out++ = '\''; // open the string + if (opt_sh != CMD) + *out++ = '\''; // open the string for (c = *s++; c; c = *s++) { if (c == '\'') { *out++ = '\''; // close, @@ -315,7 +335,8 @@ shell_escape(const char *s) else *out++ = c; // plain copy } - *out++ = '\''; // close the string + if (opt_sh != CMD) + *out++ = '\''; // close the string *out++ = '\0'; // terminate return mem; } @@ -350,6 +371,10 @@ output_unset_env(const shell_type opt_sh) printf("set -e SSH_AUTH_SOCK;\n"); printf("set -e SSH_PAGEANT_PID;\n"); break; + case CMD: + printf("set SSH_AUTH_SOCK=\n"); + printf("set SSH_PAGEANT_PID=\n"); + break; } } @@ -373,6 +398,11 @@ output_set_env(const shell_type opt_sh, const int p_set_pid_env, const char *esc if (p_set_pid_env) printf("set -x SSH_PAGEANT_PID %d;\n", pid); break; + case CMD: + printf("set SSH_AUTH_SOCK=%s\n", escaped_sockpath); + if (p_set_pid_env) + printf("set SSH_PAGEANT_PID=%d\n", pid); + break; } } @@ -386,6 +416,8 @@ parse_shell_option(const char *shell_name) } else if (!strcasecmp(shell_name, "sh") || !strcasecmp(shell_name, "bourne")) { return BOURNE; + } else if (!strcasecmp(shell_name, "cmd")) { + return CMD; } else { errx(1, "unrecognized shell \"%s\"", shell_name); } @@ -432,7 +464,7 @@ main(int argc, char *argv[]) return 0; case 'v': - printf("ssh-pageant 1.4\n"); + printf("ssh-pageant 1.4-merl1\n"); printf("Copyright (C) 2009-2014 Josh Stone\n"); printf("License GPLv3+: GNU GPL version 3 or later" " .\n"); @@ -498,8 +530,12 @@ main(int argc, char *argv[]) if (kill(pid, SIGTERM) < 0) err(1, "kill(%d)", pid); output_unset_env(opt_sh); - if (!opt_quiet) - printf("echo ssh-pageant pid %d killed;\n", pid); + if (!opt_quiet) { + if (opt_sh == CMD) + printf("echo ssh-pageant pid %d killed\n", pid); + else + printf("echo ssh-pageant pid %d killed;\n", pid); + } return 0; } @@ -516,7 +552,7 @@ main(int argc, char *argv[]) int p_sock_reused = opt_reuse && reuse_socket_path(sockpath); if (!p_sock_reused) { if (!sockpath[0]) - create_socket_path(sockpath, sizeof(sockpath)); + create_socket_path(opt_sh, sockpath, sizeof(sockpath)); sockfd = open_auth_socket(sockpath); } @@ -543,13 +579,17 @@ main(int argc, char *argv[]) if (pid < 0) cleanup_warn("fork"); if (pid > 0) { - char *escaped_sockpath = shell_escape(sockpath); + char *escaped_sockpath = shell_escape(sockpath, opt_sh); if (!escaped_sockpath) cleanup_warn("shell_escape"); output_set_env(opt_sh, p_set_pid_env, escaped_sockpath, pid); free(escaped_sockpath); - if (p_set_pid_env && !opt_quiet) - printf("echo ssh-pageant pid %d;\n", pid); + if (p_set_pid_env && !opt_quiet) { + if (opt_sh == CMD) + printf("echo ssh-pageant pid %d\n", pid); + else + printf("echo ssh-pageant pid %d;\n", pid); + } if (p_daemonize) return 0; } From 0c75adb22f78908d2f48732dfa634cbb32529777 Mon Sep 17 00:00:00 2001 From: BetzF Date: Thu, 1 Feb 2018 17:31:35 +0100 Subject: [PATCH 03/10] Added .stackdump and vim tempfiles (*.*~) to .gitignore --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index c246a72..4d439a9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ /*.exe /*.o /cscope.out +/*.stackdump +*~ From d4999d07778b637c37a992174c2fcca97625c950 Mon Sep 17 00:00:00 2001 From: BetzF Date: Thu, 1 Feb 2018 17:34:18 +0100 Subject: [PATCH 04/10] Update to cmd TEMP folder and output * Modified "-S cmd" to use windows users temp folder * Modified "-S cmd" output to print commands to globally set and delete the environment variables See: https://stackoverflow.com/questions/13222724/command-line-to-remove-an-environment-variable-from-the-os-level-configuration#13222794 --- main.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/main.c b/main.c index 77ea3dd..14a1aee 100755 --- a/main.c +++ b/main.c @@ -95,13 +95,13 @@ create_socket_path(const shell_type opt_sh, char* sockpath, size_t len) char *tempdir; if (opt_sh == CMD) { - tempdir = malloc(strlen(getenv("TEMP")) + 12); + tempdir = malloc(strlen(getenv("USERNAME")) + strlen("C:\\Users\\\\AppData\\Local\\Temp") + 12); if(tempdir == NULL) { fprintf(stderr, "Memory allocation failed"); return; } - snprintf(tempdir, strlen(getenv("TEMP")) + 12, "%s/ssh-XXXXXX", getenv("TEMP")); + snprintf(tempdir,strlen(getenv("USERNAME")) + strlen("C:\\Users\\\\AppData\\Local\\Temp") + 12, "C:\\Users\\%s\\AppData\\Local\\Temp\\ssh-XXXXXX", getenv("USERNAME")); } else { tempdir = malloc(strlen("/tmp/ssh-XXXXXX") + 1); if(tempdir == NULL) { @@ -372,8 +372,9 @@ output_unset_env(const shell_type opt_sh) printf("set -e SSH_PAGEANT_PID;\n"); break; case CMD: - printf("set SSH_AUTH_SOCK=\n"); - printf("set SSH_PAGEANT_PID=\n"); + printf("set SSH_AUTH_SOCK= & setx SSH_AUTH_SOCK "" & REG delete HKCU\Environment /F /V SSH_AUTH_SOCK\n"); + printf("set SSH_PAGEANT_PID= & setx SSH_PAGEANT_PID "" & REG delete HKCU\Environment /F /V SSH_PAGEANT_PID\n"); + break; } } @@ -399,9 +400,9 @@ output_set_env(const shell_type opt_sh, const int p_set_pid_env, const char *esc printf("set -x SSH_PAGEANT_PID %d;\n", pid); break; case CMD: - printf("set SSH_AUTH_SOCK=%s\n", escaped_sockpath); + printf("set SSH_AUTH_SOCK=%s & setx SSH_AUTH_SOCK %s\n", escaped_sockpath, escaped_sockpath); if (p_set_pid_env) - printf("set SSH_PAGEANT_PID=%d\n", pid); + printf("set SSH_PAGEANT_PID=%d & setx SSH_PAGEANT_PID %d\n", pid, pid); break; } } @@ -454,7 +455,7 @@ main(int argc, char *argv[]) printf(" -v, --version Display version information.\n"); printf(" -c Generate C-shell commands on stdout.\n"); printf(" -s Generate Bourne shell commands on stdout.\n"); - printf(" -S SHELL Generate shell command for \"bourne\", \"csh\", or \"fish\".\n"); + printf(" -S SHELL Generate shell command for \"bourne\", \"csh\", \"fish\", or \"cmd\".\n"); printf(" -k Kill the current %s.\n", program_invocation_short_name); printf(" -d Enable debug mode.\n"); printf(" -q Enable quiet mode.\n"); From d1f683c5b0d9506ccff2c02b8ee7a0349ce1451e Mon Sep 17 00:00:00 2001 From: BetzF Date: Thu, 1 Feb 2018 18:31:08 +0100 Subject: [PATCH 05/10] Add missing escapes \" --- main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 14a1aee..3f849e1 100755 --- a/main.c +++ b/main.c @@ -372,8 +372,8 @@ output_unset_env(const shell_type opt_sh) printf("set -e SSH_PAGEANT_PID;\n"); break; case CMD: - printf("set SSH_AUTH_SOCK= & setx SSH_AUTH_SOCK "" & REG delete HKCU\Environment /F /V SSH_AUTH_SOCK\n"); - printf("set SSH_PAGEANT_PID= & setx SSH_PAGEANT_PID "" & REG delete HKCU\Environment /F /V SSH_PAGEANT_PID\n"); + printf("set SSH_AUTH_SOCK= & setx SSH_AUTH_SOCK \"\" & REG delete HKCU\Environment /F /V SSH_AUTH_SOCK\n"); + printf("set SSH_PAGEANT_PID= & setx SSH_PAGEANT_PID \"\" & REG delete HKCU\Environment /F /V SSH_PAGEANT_PID\n"); break; } From 487d09949b82c715c4932b5536ad75091fcb168b Mon Sep 17 00:00:00 2001 From: BetzF Date: Thu, 1 Feb 2018 18:54:51 +0100 Subject: [PATCH 06/10] Redirect messages of setx and reg to NUL --- main.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/main.c b/main.c index 3f849e1..1ae449b 100755 --- a/main.c +++ b/main.c @@ -372,8 +372,10 @@ output_unset_env(const shell_type opt_sh) printf("set -e SSH_PAGEANT_PID;\n"); break; case CMD: - printf("set SSH_AUTH_SOCK= & setx SSH_AUTH_SOCK \"\" & REG delete HKCU\Environment /F /V SSH_AUTH_SOCK\n"); - printf("set SSH_PAGEANT_PID= & setx SSH_PAGEANT_PID \"\" & REG delete HKCU\Environment /F /V SSH_PAGEANT_PID\n"); + // REG delete seems not to be necessary in Win10 but in Win7 and bellow: + // https://stackoverflow.com/questions/13222724/command-line-to-remove-an-environment-variable-from-the-os-level-configuration + printf("set SSH_AUTH_SOCK= & setx SSH_AUTH_SOCK \"\" > NUL & REG delete HKCU\Environment /F /V SSH_AUTH_SOCK > NUL 2>&1\n"); + printf("set SSH_PAGEANT_PID= & setx SSH_PAGEANT_PID \"\" > NUL & REG delete HKCU\Environment /F /V SSH_PAGEANT_PID > NUL 2>&1\n"); break; } @@ -400,9 +402,9 @@ output_set_env(const shell_type opt_sh, const int p_set_pid_env, const char *esc printf("set -x SSH_PAGEANT_PID %d;\n", pid); break; case CMD: - printf("set SSH_AUTH_SOCK=%s & setx SSH_AUTH_SOCK %s\n", escaped_sockpath, escaped_sockpath); + printf("set SSH_AUTH_SOCK=%s & setx SSH_AUTH_SOCK %s > NUL\n", escaped_sockpath, escaped_sockpath); if (p_set_pid_env) - printf("set SSH_PAGEANT_PID=%d & setx SSH_PAGEANT_PID %d\n", pid, pid); + printf("set SSH_PAGEANT_PID=%d & setx SSH_PAGEANT_PID %d > NUL\n", pid, pid); break; } } From 8fcb6e152fd4cb2606346014ec0521f335137be9 Mon Sep 17 00:00:00 2001 From: BetzF Date: Thu, 1 Feb 2018 19:34:16 +0100 Subject: [PATCH 07/10] Add explanation on how to run at windows startup --- README.md | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a1fb050..0fc86b3 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,34 @@ It may be possible to share a Cygwin socket with external tools like both runtimes. Use `cygpath --windows {path}` to help normalize paths for system-wide use. +3. Alternative: run ssh-pageant at Windows start and set environment variables. + + Create a batch file with the following content: + + @echo off + REM This BAT is intented to be run from cmd or at windows startup. + REM It starts ssh-pageant and sets the environment variables. By doing so all + REM newly started shells should inherit the environment variables and there is + REM no need to run ssh-pageant in every new shell + SET FN=%TEMP%\ssh-agent-init.bat + ssh-pageant -S cmd %* > %FN% + call %FN% + del %FN% + + Now just add this batchfile to you windows startup folder. + + To explain: + + * To work around the missing eval in CMD a temporary batch file is populated with the output of `ssh-pageant`. + After execution it will be deleted again. + + The batchfile is a modified version of [Russell Davis solution for charade](http://russelldavis.blogspot.co.uk/2011/02/using-charade-to-proxy-cygwin-ssh-agent.html). + + * `%*` is an alias for "all arguments" so additional arguments can be passed to + `ssh-pageant` (e.g. `-k`). + + Tested and confirmed to work with Windows 10, cmd.exe, GitBash and Msys2 bash. + ## Options `ssh-pageant` aims to be compatible with `ssh-agent` options, with a few extras: @@ -88,7 +116,7 @@ system-wide use. -v, --version Display version information. -c Generate C-shell commands on stdout. -s Generate Bourne shell commands on stdout. - -S SHELL Generate shell command for "bourne", "csh", or "fish". + -S SHELL Generate shell command for "bourne", "csh", "fish" or "cmd". -k Kill the current ssh-pageant. -d Enable debug mode. -q Enable quiet mode. From 383392476d0f103cde35fd05c5a9b6ebc209841f Mon Sep 17 00:00:00 2001 From: BetzF Date: Thu, 1 Feb 2018 19:43:24 +0100 Subject: [PATCH 08/10] Corrected startup how to --- README.md | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0fc86b3..654a2b6 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,10 @@ It may be possible to share a Cygwin socket with external tools like both runtimes. Use `cygpath --windows {path}` to help normalize paths for system-wide use. -3. Alternative: run ssh-pageant at Windows start and set environment variables. +3. **Alternative**: run ssh-pageant at Windows start and set environment variables. + + In this scenario there is no need for additions to .bashrc or a custom sock + path, though you can still use it. Create a batch file with the following content: @@ -95,13 +98,14 @@ system-wide use. To explain: - * To work around the missing eval in CMD a temporary batch file is populated with the output of `ssh-pageant`. - After execution it will be deleted again. + * To work around the missing eval in CMD a temporary batch file is + populated with the output of `ssh-pageant`. After execution it will be + deleted again. The batchfile is a modified version of [Russell Davis solution for charade](http://russelldavis.blogspot.co.uk/2011/02/using-charade-to-proxy-cygwin-ssh-agent.html). * `%*` is an alias for "all arguments" so additional arguments can be passed to - `ssh-pageant` (e.g. `-k`). + `ssh-pageant` (e.g. `-k` or `-a`). Tested and confirmed to work with Windows 10, cmd.exe, GitBash and Msys2 bash. From 60c0daeab60de4c49b3356c93e1a34a6a4ce27d4 Mon Sep 17 00:00:00 2001 From: BetzF Date: Thu, 1 Feb 2018 19:46:25 +0100 Subject: [PATCH 09/10] Updated Version History --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 654a2b6..8ed2da6 100644 --- a/README.md +++ b/README.md @@ -147,11 +147,12 @@ To uninstall, just remove the copied files: ## Version History -* 2014-11-23: 1.4 - MSYS support and more robust socket paths. -* 2013-06-23: 1.3 - Allow reusing existing sockets via `-r`/`--reuse`. -* 2012-11-24: 1.2 - Mirror the exit status of child processes. -* 2011-06-12: 1.1 - Fixed SID issues. -* 2010-09-20: 1.0 - Initial release. +* 2018-02-01: 1.4-merl1 - Added cmd support and how to add to windows startup. +* 2014-11-23: 1.4 - MSYS support and more robust socket paths. +* 2013-06-23: 1.3 - Allow reusing existing sockets via `-r`/`--reuse`. +* 2012-11-24: 1.2 - Mirror the exit status of child processes. +* 2011-06-12: 1.1 - Fixed SID issues. +* 2010-09-20: 1.0 - Initial release. ## Contributions From 27013b6c4827545d11dc0635583cb961372de537 Mon Sep 17 00:00:00 2001 From: BetzF Date: Thu, 1 Feb 2018 20:02:07 +0100 Subject: [PATCH 10/10] Add missing escape --- main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index 1ae449b..b72c052 100755 --- a/main.c +++ b/main.c @@ -372,10 +372,10 @@ output_unset_env(const shell_type opt_sh) printf("set -e SSH_PAGEANT_PID;\n"); break; case CMD: - // REG delete seems not to be necessary in Win10 but in Win7 and bellow: + // REG delete because setx does not do proper clean up: // https://stackoverflow.com/questions/13222724/command-line-to-remove-an-environment-variable-from-the-os-level-configuration - printf("set SSH_AUTH_SOCK= & setx SSH_AUTH_SOCK \"\" > NUL & REG delete HKCU\Environment /F /V SSH_AUTH_SOCK > NUL 2>&1\n"); - printf("set SSH_PAGEANT_PID= & setx SSH_PAGEANT_PID \"\" > NUL & REG delete HKCU\Environment /F /V SSH_PAGEANT_PID > NUL 2>&1\n"); + printf("set SSH_AUTH_SOCK= & setx SSH_AUTH_SOCK \"\" > NUL & REG delete HKCU\\Environment /F /V SSH_AUTH_SOCK > NUL 2>&1\n"); + printf("set SSH_PAGEANT_PID= & setx SSH_PAGEANT_PID \"\" > NUL & REG delete HKCU\\Environment /F /V SSH_PAGEANT_PID > NUL 2>&1\n"); break; }