diff options
author | Werner Koch <wk@gnupg.org> | 2007-06-19 11:11:11 +0200 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2007-06-19 11:11:11 +0200 |
commit | 540f9164c01dbbd1f8fc9abcd2ee67dbf6e1ee10 (patch) | |
tree | 298058ec8adf7c7c059ce7db127334a9ddb49bec /agent | |
parent | jnlib/ (diff) | |
download | gnupg2-540f9164c01dbbd1f8fc9abcd2ee67dbf6e1ee10.tar.xz gnupg2-540f9164c01dbbd1f8fc9abcd2ee67dbf6e1ee10.zip |
Made percent_escape more general.
Added regression tests support to jnlib.
W32 changes.
Diffstat (limited to 'agent')
-rw-r--r-- | agent/ChangeLog | 6 | ||||
-rw-r--r-- | agent/gpg-agent.c | 31 | ||||
-rw-r--r-- | agent/w32main.c | 154 |
3 files changed, 170 insertions, 21 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog index e23cd99a9..19564556e 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -5,10 +5,14 @@ 2007-06-18 Werner Koch <wk@g10code.com> + * w32main.c (build_argv): New. + (WinMain): Use it. + * command.c (cmd_killagent) [W32]: New. (cmd_getinfo): New. * gpg-agent.c (get_agent_ssh_socket_name): New. - + (no_force_standard_socket) New. + (create_server_socket): Use it. * Makefile.am (gpg_agent_res_ldflags): Pass windows option to ld. 2007-06-14 Werner Koch <wk@g10code.com> diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 419f3769a..8907e9234 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -93,6 +93,7 @@ enum cmd_and_opt_values oMinPassphraseLen, oUseStandardSocket, oNoUseStandardSocket, + oNoReuseStandardSocket, oIgnoreCacheForSigning, oAllowMarkTrusted, @@ -130,6 +131,7 @@ static ARGPARSE_OPTS opts[] = { { oUseStandardSocket, "use-standard-socket", 0, N_("use a standard location for the socket")}, { oNoUseStandardSocket, "no-use-standard-socket", 0, "@"}, + { oNoReuseStandardSocket, "no-reuse-standard-socket", 0, "@"}, { oPinentryProgram, "pinentry-program", 2 , N_("|PGM|use PGM as the PIN-Entry program") }, @@ -186,6 +188,10 @@ static char *socket_name; /* Name of the communication socket used for ssh-agent-emulation. */ static char *socket_name_ssh; +/* If set to true and a standard socket is requested, we won't try to + bind to a socket which is already in use. */ +static int no_reuse_standard_socket; + /* Default values for options passed to the pinentry. */ static char *default_display; static char *default_ttyname; @@ -215,7 +221,7 @@ static pid_t parent_pid = (pid_t)(-1); static char *create_socket_name (int use_standard_socket, char *standard_name, char *template); -static int create_server_socket (int is_standard_name, const char *name); +static int create_server_socket (int is_standard_name, char *name); static void create_directories (void); static void agent_init_default_ctrl (ctrl_t ctrl); @@ -621,6 +627,7 @@ main (int argc, char **argv ) case oUseStandardSocket: standard_socket = 1; break; case oNoUseStandardSocket: standard_socket = 0; break; + case oNoReuseStandardSocket: no_reuse_standard_socket = 1; break; case oKeepTTY: opt.keep_tty = 1; break; case oKeepDISPLAY: opt.keep_display = 1; break; @@ -715,7 +722,7 @@ main (int argc, char **argv ) #define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) filename = make_filename (opt.homedir, "gpg-agent.conf", NULL ); - filename_esc = percent_escape (filename); + filename_esc = percent_escape (filename, NULL); printf ("gpgconf-gpg-agent.conf:%lu:\"%s\n", GC_OPT_FLAG_DEFAULT, filename_esc); @@ -1226,10 +1233,10 @@ create_socket_name (int use_standard_socket, /* Create a Unix domain socket with NAME. IS_STANDARD_NAME indicates - whether a non-random socket is used. Returns the filedescriptor or + whether a non-random socket is used. Returns the file descriptor or terminates the process in case of an error. */ static int -create_server_socket (int is_standard_name, const char *name) +create_server_socket (int is_standard_name, char *name) { struct sockaddr_un *serv_addr; socklen_t len; @@ -1257,14 +1264,16 @@ create_server_socket (int is_standard_name, const char *name) #ifdef HAVE_W32_SYSTEM rc = _w32_sock_bind (fd, (struct sockaddr*) serv_addr, len); - if (is_standard_name && rc == -1 ) + if (is_standard_name && rc == -1 && errno == WSAEADDRINUSE + && !no_reuse_standard_socket) { remove (name); - rc = bind (fd, (struct sockaddr*) serv_addr, len); + rc = _w32_sock_bind (fd, (struct sockaddr*) serv_addr, len); } #else rc = bind (fd, (struct sockaddr*) serv_addr, len); - if (is_standard_name && rc == -1 && errno == EADDRINUSE) + if (is_standard_name && rc == -1 && errno == EADDRINUSE + && !no_reuse_standard_socket) { remove (name); rc = bind (fd, (struct sockaddr*) serv_addr, len); @@ -1272,9 +1281,15 @@ create_server_socket (int is_standard_name, const char *name) #endif if (rc == -1) { + /* We use gpg_strerror here because it allows us to get strings + for some W32 socket error codes. */ log_error (_("error binding socket to `%s': %s\n"), - serv_addr->sun_path, strerror (errno)); + serv_addr->sun_path, + gpg_strerror (gpg_error_from_errno (errno))); + close (fd); + if (is_standard_name && no_reuse_standard_socket) + *name = 0; /* Inhibit removal of the socket by cleanup(). */ agent_exit (2); } diff --git a/agent/w32main.c b/agent/w32main.c index 5fccb7ea2..176050220 100644 --- a/agent/w32main.c +++ b/agent/w32main.c @@ -1,5 +1,6 @@ /* w32main.c - W32 main entry pint and taskbar support for the GnuPG Agent * Copyright (C) 2007 Free Software Foundation, Inc. + * Copyright 1996, 1998 Alexandre Julliard * * This file is part of GnuPG. * @@ -37,6 +38,136 @@ static HINSTANCE glob_hinst; static HWND glob_hwnd; +/* Build an argv array from the command in CMDLINE. RESERVED is the + number of args to reserve before the first one. This code is based + on Alexandre Julliard's LGPLed wine-0.9.34/dlls/kernel32/process.c + and modified to fit into our framework. The function returns NULL + on error; on success an arry with the argiments is returned. This + array has been allocaqted using a plain malloc (and not the usual + xtrymalloc). */ +static char ** +build_argv (char *cmdline_arg, int reserved) +{ + int argc; + char **argv; + char *cmdline, *s, *arg, *d; + int in_quotes, bs_count; + + cmdline = malloc (strlen (cmdline_arg) + 1); + if (!cmdline) + return NULL; + strcpy (cmdline, cmdline_arg); + + /* First determine the required size of the array. */ + argc = reserved + 1; + bs_count = 0; + in_quotes = 0; + s = cmdline; + for (;;) + { + if ( !*s || ((*s==' ' || *s=='\t') && !in_quotes)) /* A space. */ + { + argc++; + /* Skip the remaining spaces. */ + while (*s==' ' || *s=='\t') + s++; + if (!*s) + break; + bs_count = 0; + } + else if (*s=='\\') + { + bs_count++; + s++; + } + else if ( (*s == '\"') && !(bs_count & 1)) + { + /* Unescaped '\"' */ + in_quotes = !in_quotes; + bs_count=0; + s++; + } + else /* A regular character. */ + { + bs_count = 0; + s++; + } + } + + argv = malloc (argc * sizeof *argv); + if (!argv) + { + free (cmdline); + return NULL; + } + + /* Now actually parse the command line. */ + argc = reserved; + bs_count = 0; + in_quotes=0; + arg = d = s = cmdline; + while (*s) + { + if ((*s==' ' || *s=='\t') && !in_quotes) + { + /* Close the argument and copy it. */ + *d = 0; + argv[argc++] = arg; + + /* Skip the remaining spaces. */ + do + s++; + while (*s==' ' || *s=='\t'); + + /* Start with a new argument */ + arg = d = s; + bs_count = 0; + } + else if (*s=='\\') + { + *d++ = *s++; + bs_count++; + } + else if (*s=='\"') + { + if ( !(bs_count & 1) ) + { + /* Preceded by an even number of backslashes, this is + half that number of backslashes, plus a '\"' which we + discard. */ + d -= bs_count/2; + s++; + in_quotes = !in_quotes; + } + else + { + /* Preceded by an odd number of backslashes, this is + half that number of backslashes followed by a '\"'. */ + d = d - bs_count/2 - 1; + *d++ ='\"'; + s++; + } + bs_count=0; + } + else /* A regular character. */ + { + *d++ = *s++; + bs_count = 0; + } + } + + if (*arg) + { + *d = 0; + argv[argc++] = arg; + } + argv[argc] = NULL; + + return argv; +} + + + /* Our window message processing function. */ static LRESULT CALLBACK wndw_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) @@ -155,24 +286,23 @@ w32_setup_taskbar (void) /* The main entry point for the Windows version. We save away all GUI - related stuff, parse the commandline and finally call the real + related stuff, parse the command line and finally call the real main. */ int WINAPI WinMain (HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int showcmd) { - /* Fixme: We need a parser for the command line. Should be - available in some CRT code - need to see whether we can find a - GNU version. For nopw we call gpg-agent with a couple of fixed arguments - */ - char *argv[] = { "gpg-agent.exe", "--daemon", "-v", "--debug-all", NULL }; + char **argv; + int argc; + /* We use the GetCommandLine function because that also includes the + program name in contrast to the CMDLINE arg. */ + argv = build_argv (GetCommandLineA (), 0); + if (!argv) + return 2; /* Can't do much about a malloc failure. */ + for (argc=0; argv[argc]; argc++) + ; glob_hinst = hinst; - return w32_main (DIM(argv)-1, argv); + return w32_main (argc, argv); } - - - - - |