From 0cfbfd6186c7b28a355069ebb89b9739908318c6 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 14 Jun 2007 17:05:07 +0000 Subject: [PATCH] A whole bunch of changes to allow building for Windows. See the ChangeLogs for details. --- ChangeLog | 13 ++++ NEWS | 2 + agent/ChangeLog | 45 ++++++++++++ agent/Makefile.am | 30 +++++++- agent/agent.h | 5 +- agent/call-pinentry.c | 8 +- agent/call-scd.c | 6 +- agent/gpg-agent.c | 42 ++++++++--- agent/minip12.c | 31 ++++---- agent/preset-passphrase.c | 52 +++---------- agent/protect-tool.c | 14 +++- agent/trustlist.c | 24 +++++- am/cmacros.am | 10 +++ common/ChangeLog | 33 +++++++++ common/Makefile.am | 4 +- common/estream.c | 29 ++++---- common/homedir.c | 149 ++++++++++++++++++++++++++++++++++++++ common/http.c | 12 ++- common/init.c | 73 +++++++++++++++++++ common/simple-pwquery.c | 49 +++++++++++-- common/simple-pwquery.h | 41 ++++++++++- common/util.h | 16 ++++ configure.ac | 28 +++---- doc/gpgsm.texi | 9 +++ g10/ChangeLog | 21 ++++++ g10/Makefile.am | 2 +- g10/call-agent.c | 2 +- g10/gpg.c | 7 +- g10/gpgv.c | 7 +- g10/keyserver.c | 4 +- g10/misc.c | 37 ---------- g10/openfile.c | 5 +- jnlib/ChangeLog | 4 + jnlib/utf8conv.c | 47 ++++++++++++ jnlib/utf8conv.h | 10 +++ kbx/ChangeLog | 4 + kbx/kbxutil.c | 5 +- keyserver/ChangeLog | 6 ++ keyserver/gpgkeys_hkp.c | 12 +-- scd/ChangeLog | 12 +++ scd/Makefile.am | 2 +- scd/apdu.c | 2 + scd/command.c | 20 ++++- scd/scdaemon.c | 9 ++- scd/scdaemon.h | 1 + sm/ChangeLog | 20 +++++ sm/Makefile.am | 2 +- sm/call-agent.c | 6 +- sm/call-dirmngr.c | 2 +- sm/export.c | 2 +- sm/gpgsm.c | 8 +- sm/import.c | 2 +- sm/qualified.c | 2 +- tools/ChangeLog | 22 ++++++ tools/Makefile.am | 11 ++- tools/gpg-connect-agent.c | 4 + tools/gpgconf-comp.c | 8 +- tools/gpgconf.c | 3 + tools/symcryptrun.c | 18 ++++- 59 files changed, 850 insertions(+), 204 deletions(-) create mode 100644 common/init.c diff --git a/ChangeLog b/ChangeLog index 7029694e0..2ab8d8e72 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2007-06-14 Werner Koch + + * configure.ac [AH_BOTTOM]: Remove the hardwired names of modules. + +2007-06-12 Werner Koch + + * configure.ac [AH_BOTTOM]: Define HTTP_NO_WSASTARTUP. + +2007-06-11 Werner Koch + + * am/cmacros.am (libcommonstd, libcommonpth, libcommonstd_ldadd) + (libcommonpth_ldadd): Add macros. + 2007-06-06 Werner Koch * configure.ac: Add a few notices message so make browsing of the diff --git a/NEWS b/NEWS index 3ffe6fabc..f54779089 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ Noteworthy changes in version 2.0.5 * Fixed bug when using the --p12-charset without --armor. + * Changes required for a port to Windows. + Noteworthy changes in version 2.0.4 (2007-05-09) ------------------------------------------------ diff --git a/agent/ChangeLog b/agent/ChangeLog index 94b7c5a3b..4a0077507 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,48 @@ +2007-06-14 Werner Koch + + * protect-tool.c (main): Setup default socket name for + simple-pwquery. + (MAP_SPWQ_ERROR_IMPL): New. Use map_spwq_error for spqw related + error codes. + * preset-passphrase.c (main): Setup default socket name for + simple-pwquery. + (map_spwq_error): Remove. + (MAP_SPWQ_ERROR_IMPL): New. + + * call-pinentry.c (start_pinentry): Use gnupg_module_name. + * call-scd.c (start_scd): Ditto. + +2007-06-12 Werner Koch + + * taskbar.c: New. + + * trustlist.c (read_one_trustfile): Replace GNUPG_SYSCONFDIR by a + function call. + (read_trustfiles): Ditto. + + * gpg-agent.c (main): Replace some calls by init_common_subsystems. + * preset-passphrase.c (main): Ditto. + * protect-tool.c (main): Ditto. + +2007-06-11 Werner Koch + + * Makefile.am (common_libs): Use libcommonstd macro. + (commonpth_libs): Use libcommonpth macro. + + * protect-tool.c (main) [W32]: Call pth_init. + + * preset-passphrase.c (main) [W32]: Repalce the explicit Winsocket + init by a call to pth_init. + + * trustlist.c (initialize_module_trustlist): New. + * gpg-agent.c (main): Call it. + + * call-pinentry.c (initialize_module_query): Rename to + initialize_module_call_pinentry. + + * minip12.c: Remove iconv.h. Add utf8conf.h. Changed all iconv + calss to use these jnlib wrappers. + 2007-06-06 Werner Koch * minip12.c (enum): Rename CONTEXT to ASNCONTEXT as winnt.h diff --git a/agent/Makefile.am b/agent/Makefile.am index b79423a7c..34883ba20 100644 --- a/agent/Makefile.am +++ b/agent/Makefile.am @@ -23,6 +23,8 @@ bin_PROGRAMS = gpg-agent libexec_PROGRAMS = gpg-protect-tool gpg-preset-passphrase noinst_PROGRAMS = $(TESTS) +EXTRA_DIST = gpg-agent.ico gpg-agent-resource.rc + AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl include $(top_srcdir)/am/cmacros.am @@ -45,15 +47,33 @@ gpg_agent_SOURCES = \ call-scd.c \ learncard.c +if HAVE_W32_SYSTEM +gpg_agent_SOURCES += w32main.c w32main.h +endif -common_libs = ../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a -commonpth_libs = ../jnlib/libjnlib.a ../common/libcommonpth.a ../gl/libgnu.a +common_libs = ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a +commonpth_libs = ../jnlib/libjnlib.a $(libcommonpth) ../gl/libgnu.a pwquery_libs = ../common/libsimple-pwquery.a +if HAVE_W32_SYSTEM +.rc.o: + $(WINDRES) `echo $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) | \ + sed -e 's/-I/--include-dir /g;s/-D/--define /g'` -i $< -o $@ + +gpg_agent_res_ldflags = -Wl,gpg-agent-resource.o +gpg_agent_res_deps = gpg-agent-resource.o +else +gpg_agent_res_ldflags = +gpg_agent_res_deps = +endif + + gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_PTH_CFLAGS) $(PTH_CFLAGS) gpg_agent_LDADD = $(commonpth_libs) \ $(LIBGCRYPT_LIBS) $(LIBASSUAN_PTH_LIBS) $(PTH_LIBS) \ $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) +gpg_agent_LDFLAGS = $(gpg_agent_res_ldflags) +gpg_agent_DEPENDENCIES = $(gpg_agent_res_deps) gpg_protect_tool_SOURCES = \ protect-tool.c \ @@ -61,14 +81,15 @@ gpg_protect_tool_SOURCES = \ minip12.c minip12.h # Needs $(NETLIBS) for libsimple-pwquery.la. -gpg_protect_tool_LDADD = $(pwquery_libs) $(common_libs) \ +gpg_protect_tool_LDADD = $(pwquery_libs) $(common_libs) \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) gpg_preset_passphrase_SOURCES = \ preset-passphrase.c # Needs $(NETLIBS) for libsimple-pwquery.la. -gpg_preset_passphrase_LDADD = $(pwquery_libs) $(common_libs) \ +gpg_preset_passphrase_LDADD = \ + $(pwquery_libs) $(common_libs) \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) @@ -77,6 +98,7 @@ gpg_preset_passphrase_LDADD = $(pwquery_libs) $(common_libs) \ $(PROGRAMS): $(common_libs) $(commonpth_libs) $(pwquery_libs) + # # Module tests # diff --git a/agent/agent.h b/agent/agent.h index 15830de27..b0d27823c 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -215,8 +215,8 @@ gpg_error_t agent_public_key_from_file (ctrl_t ctrl, gcry_sexp_t *result); int agent_key_available (const unsigned char *grip); -/*-- query.c --*/ -void initialize_module_query (void); +/*-- call-pinentry.c --*/ +void initialize_module_call_pinentry (void); void agent_query_dump_state (void); void agent_reset_query (ctrl_t ctrl); int pinentry_active_p (ctrl_t ctrl, int waitseconds); @@ -276,6 +276,7 @@ int agent_get_shadow_info (const unsigned char *shadowkey, /*-- trustlist.c --*/ +void initialize_module_trustlist (void); gpg_error_t agent_istrusted (ctrl_t ctrl, const char *fpr); gpg_error_t agent_listtrusted (void *assuan_context); gpg_error_t agent_marktrusted (ctrl_t ctrl, const char *name, diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 099171c5e..8882e8d55 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -87,7 +87,7 @@ struct entry_parm_s static initialization because Pth emulation code might not be able to do a static init; in particular, it is not possible for W32. */ void -initialize_module_query (void) +initialize_module_call_pinentry (void) { static int initialized; @@ -217,7 +217,7 @@ start_pinentry (ctrl_t ctrl) } if (!opt.pinentry_program || !*opt.pinentry_program) - opt.pinentry_program = GNUPG_DEFAULT_PINENTRY; + opt.pinentry_program = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY); pgmname = opt.pinentry_program; if ( !(pgmname = strrchr (opt.pinentry_program, '/'))) pgmname = opt.pinentry_program; @@ -751,6 +751,9 @@ agent_popup_message_stop (ctrl_t ctrl) ; /* No pid available can't send a kill. */ else if (popup_finished) ; /* Already finished and ready for joining. */ +#ifdef HAVE_W32_SYSTEM +# warning need to implement a kill mechanism for pinentry +#else else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) ) { /* The daemon already died. No need to send a kill. However because we already waited for the process, we need to tell @@ -762,6 +765,7 @@ agent_popup_message_stop (ctrl_t ctrl) else if (pid > 0) kill (pid, SIGKILL); /* Need to use SIGKILL due to bad interaction of SIGINT with Pth. */ +#endif /* Now wait for the thread to terminate. */ rc = pth_join (popup_tid, NULL); diff --git a/agent/call-scd.c b/agent/call-scd.c index a2067a2cb..b62ab97ea 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -300,7 +300,7 @@ start_scd (ctrl_t ctrl) } if (!opt.scdaemon_program || !*opt.scdaemon_program) - opt.scdaemon_program = GNUPG_DEFAULT_SCDAEMON; + opt.scdaemon_program = gnupg_module_name (GNUPG_MODULE_NAME_SCDAEMON); if ( !(pgmname = strrchr (opt.scdaemon_program, '/'))) pgmname = opt.scdaemon_program; else @@ -424,6 +424,9 @@ agent_scd_check_aliveness (void) if (primary_scd_ctx) { pid = assuan_get_pid (primary_scd_ctx); +#ifdef HAVE_W32_SYSTEM +#warning Need to implement an alive test for scdaemon +#else if (pid != (pid_t)(-1) && pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) ) { @@ -454,6 +457,7 @@ agent_scd_check_aliveness (void) xfree (socket_name); socket_name = NULL; } +#endif } if (!pth_mutex_release (&start_scd_lock)) diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index 66b048815..ae878eb86 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -33,9 +33,9 @@ #include #include #ifndef HAVE_W32_SYSTEM -#include -#include -#endif /*HAVE_W32_SYSTEM*/ +# include +# include +#endif /*!HAVE_W32_SYSTEM*/ #include #include #include @@ -47,7 +47,8 @@ #include "i18n.h" #include "sysutils.h" #ifdef HAVE_W32_SYSTEM -#include "../jnlib/w32-afunix.h" +# include "../jnlib/w32-afunix.h" +# include "w32main.h" #endif #include "setenv.h" @@ -408,8 +409,16 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) } +/* The main entry point. For W32 another name is used as the real + entry points needs to be named WinMain and is defined in + w32main.c. */ +#ifdef HAVE_W32_SYSTEM +int +w32_main (int argc, char **argv ) +#else int main (int argc, char **argv ) +#endif { ARGPARSE_ARGS pargs; int orig_argc; @@ -434,6 +443,7 @@ main (int argc, char **argv ) gpg_error_t err; const char *env_file_name = NULL; + set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); /* Please note that we may running SUID(ROOT), so be very CAREFUL @@ -441,8 +451,8 @@ main (int argc, char **argv ) somewhere after the option parsing */ log_set_prefix ("gpg-agent", JNLIB_LOG_WITH_PREFIX|JNLIB_LOG_WITH_PID); - /* Try to auto set the character set. */ - set_native_charset (NULL); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); i18n_init (); @@ -663,8 +673,9 @@ main (int argc, char **argv ) exit (1); } - initialize_module_query (); + initialize_module_call_pinentry (); initialize_module_call_scd (); + initialize_module_trustlist (); /* Try to create missing directories. */ create_directories (); @@ -837,6 +848,7 @@ main (int argc, char **argv ) #ifdef HAVE_W32_SYSTEM pid = getpid (); printf ("set GPG_AGENT_INFO=%s;%lu;1\n", socket_name, (ulong)pid); + w32_setup_taskbar (); #else /*!HAVE_W32_SYSTEM*/ pid = fork (); if (pid == (pid_t)-1) @@ -1029,6 +1041,7 @@ main (int argc, char **argv ) return 0; } + void agent_exit (int rc) { @@ -1048,7 +1061,6 @@ agent_exit (int rc) exit (rc); } - static void agent_init_default_ctrl (ctrl_t ctrl) { @@ -1153,13 +1165,13 @@ get_agent_socket_name (void) /* Create a name for the socket. With USE_STANDARD_SOCKET given as - true using STANDARD_NAME in the home directory or if given has + true using STANDARD_NAME in the home directory or if given as false from the mkdir type name TEMPLATE. In the latter case a unique name in a unique new directory will be created. In both cases check for valid characters as well as against a maximum allowed length for a unix domain socket is done. The function terminates the process in case of an error. Returns: Pointer to an - allcoated string with the absolute name of the socket used. */ + allocated string with the absolute name of the socket used. */ static char * create_socket_name (int use_standard_socket, char *standard_name, char *template) @@ -1303,6 +1315,9 @@ static void create_directories (void) { struct stat statbuf; +#ifdef HAVE_W32_SYSTEM +#warning change it so that it works like in gpg. +#endif const char *defhome = GNUPG_DEFAULT_HOMEDIR; char *home; @@ -1478,7 +1493,7 @@ start_connection_thread_ssh (void *arg) } -/* Connection handler loop. Wait for coecntion requests and spawn a +/* Connection handler loop. Wait for connection requests and spawn a thread after accepting a connection. */ static void handle_connections (int listen_fd, int listen_fd_ssh) @@ -1510,6 +1525,7 @@ handle_connections (int listen_fd, int listen_fd_ssh) ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); #else ev = NULL; + signo = 0; #endif time_ev = NULL; @@ -1522,6 +1538,10 @@ handle_connections (int listen_fd, int listen_fd_ssh) { sigset_t oldsigs; +#ifdef HAVE_W32_SYSTEM + w32_poll_events (); +#endif + if (shutdown_pending) { if (pth_ctrl (PTH_CTRL_GETTHREADS) == 1) diff --git a/agent/minip12.c b/agent/minip12.c index ec51aee85..a551a3cf9 100644 --- a/agent/minip12.c +++ b/agent/minip12.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #ifdef TEST @@ -36,17 +35,13 @@ #endif #include "../jnlib/logging.h" +#include "../jnlib/utf8conv.h" #include "minip12.h" #ifndef DIM #define DIM(v) (sizeof(v)/sizeof((v)[0])) #endif -#ifndef ICONV_CONST -#define ICONV_CONST -#endif - - enum { @@ -532,7 +527,7 @@ decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length, { if (*charsets[charsetidx]) { - iconv_t cd; + jnlib_iconv_t cd; const char *inptr; char *outptr; size_t inbytes, outbytes; @@ -553,22 +548,22 @@ decrypt_block (const void *ciphertext, unsigned char *plaintext, size_t length, } } - cd = iconv_open (charsets[charsetidx], "utf-8"); - if (cd == (iconv_t)(-1)) + cd = jnlib_iconv_open (charsets[charsetidx], "utf-8"); + if (cd == (jnlib_iconv_t)(-1)) continue; inptr = pw; inbytes = strlen (pw); outptr = convertedpw; outbytes = convertedpwsize - 1; - if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes, + if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes, &outptr, &outbytes) == (size_t)-1) { - iconv_close (cd); + jnlib_iconv_close (cd); continue; } *outptr = 0; - iconv_close (cd); + jnlib_iconv_close (cd); log_info ("decryption failed; trying charset `%s'\n", charsets[charsetidx]); } @@ -2167,7 +2162,7 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen, if (charset && pw && *pw) { - iconv_t cd; + jnlib_iconv_t cd; const char *inptr; char *outptr; size_t inbytes, outbytes; @@ -2182,8 +2177,8 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen, goto failure; } - cd = iconv_open (charset, "utf-8"); - if (cd == (iconv_t)(-1)) + cd = jnlib_iconv_open (charset, "utf-8"); + if (cd == (jnlib_iconv_t)(-1)) { log_error ("can't convert passphrase to" " requested charset `%s': %s\n", @@ -2196,18 +2191,18 @@ p12_build (gcry_mpi_t *kparms, unsigned char *cert, size_t certlen, inbytes = strlen (pw); outptr = pwbuf; outbytes = pwbufsize - 1; - if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes, + if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes, &outptr, &outbytes) == (size_t)-1) { log_error ("error converting passphrase to" " requested charset `%s': %s\n", charset, strerror (errno)); gcry_free (pwbuf); - iconv_close (cd); + jnlib_iconv_close (cd); goto failure; } *outptr = 0; - iconv_close (cd); + jnlib_iconv_close (cd); pw = pwbuf; } diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c index 362591171..7ff842565 100644 --- a/agent/preset-passphrase.c +++ b/agent/preset-passphrase.c @@ -111,31 +111,9 @@ my_strusage (int level) -static gpg_error_t -map_spwq_error (int err) -{ - switch (err) - { - case 0: - return 0; - case SPWQ_OUT_OF_CORE: - return gpg_error_from_errno (ENOMEM); - case SPWQ_IO_ERROR: - return gpg_error_from_errno (EIO); - case SPWQ_PROTOCOL_ERROR: - return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); - case SPWQ_ERR_RESPONSE: - return gpg_error (GPG_ERR_INV_RESPONSE); - case SPWQ_NO_AGENT: - return gpg_error (GPG_ERR_NO_AGENT); - case SPWQ_SYS_ERROR: - return gpg_error_from_syserror (); - case SPWQ_GENERAL_ERROR: - default: - return gpg_error (GPG_ERR_GENERAL); - } -} +/* Include the implementation of map_spwq_error. */ +MAP_SPWQ_ERROR_IMPL /* Convert the string SRC into HEX encoding. Caller needs to xfree the returned string. */ @@ -260,23 +238,8 @@ main (int argc, char **argv) set_strusage (my_strusage); log_set_prefix ("gpg-preset-passphrase", 1); - /* Try to auto set the character set. */ - set_native_charset (NULL); - -#ifdef HAVE_W32_SYSTEM - /* Fixme: Need to initialize the Windows sockets: This should be - moved to another place and we should make sure that it won't get - done twice, like when Pth is used too. */ - { - WSADATA wsadat; - if (WSAStartup (0x202, &wsadat) ) - { - log_error ("error initializing socket library: ec=%d\n", - (int)WSAGetLastError () ); - return 2; - } - } -#endif + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); i18n_init (); @@ -307,6 +270,13 @@ main (int argc, char **argv) else usage (1); + /* Tell simple-pwquery about the the standard socket name. */ + { + char *tmp = make_filename (opt_homedir, "S.gpg-agent", NULL); + simple_pw_set_socket (tmp); + xfree (tmp); + } + if (cmd == oPreset) preset_passphrase (keygrip); else if (cmd == oForget) diff --git a/agent/protect-tool.c b/agent/protect-tool.c index d3bcc00b8..9154d4f81 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -160,6 +160,8 @@ my_strusage (int level) } +/* Include the implementation of map_spwq_error. */ +MAP_SPWQ_ERROR_IMPL /* static void */ /* print_mpi (const char *text, gcry_mpi_t a) */ @@ -1033,8 +1035,8 @@ main (int argc, char **argv ) gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); log_set_prefix ("gpg-protect-tool", 1); - /* Try to auto set the character set. */ - set_native_charset (NULL); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); i18n_init (); @@ -1092,6 +1094,13 @@ main (int argc, char **argv ) else if (argc > 1) usage (1); + /* Tell simple-pwquery about the the standard socket name. */ + { + char *tmp = make_filename (opt_homedir, "S.gpg-agent", NULL); + simple_pw_set_socket (tmp); + xfree (tmp); + } + if (opt_prompt) opt_prompt = percent_plus_unescape_string (xstrdup (opt_prompt)); @@ -1194,6 +1203,7 @@ get_passphrase (int promptno, int opt_check) pw = simple_pwquery (NULL, error_msgno == 1? _("does not match - try again"):NULL, _("Passphrase:"), desc, opt_check, &err); + err = map_spwq_error (err); #ifdef ENABLE_NLS if (orig_codeset) diff --git a/agent/trustlist.c b/agent/trustlist.c index b5bafa9cb..10ef02847 100644 --- a/agent/trustlist.c +++ b/agent/trustlist.c @@ -53,7 +53,7 @@ typedef struct trustitem_s trustitem_t; static trustitem_t *trusttable; static size_t trusttablesize; /* A mutex used to protect the table. */ -static pth_mutex_t trusttable_lock = PTH_MUTEX_INIT; +static pth_mutex_t trusttable_lock; @@ -71,6 +71,24 @@ static const char headerblurb[] = "\n"; +/* This function must be called once to initialize this module. This + has to be done before a second thread is spawned. We can't do the + static initialization because Pth emulation code might not be able + to do a static init; in particular, it is not possible for W32. */ +void +initialize_module_trustlist (void) +{ + static int initialized; + + if (!initialized) + { + if (!pth_mutex_init (&trusttable_lock)) + log_fatal ("error initializing mutex: %s\n", strerror (errno)); + initialized = 1; + } +} + + static void @@ -153,7 +171,7 @@ read_one_trustfile (const char *fname, int allow_include, } /* fixme: Should check for trailing garbage. */ - etcname = make_filename (GNUPG_SYSCONFDIR, "trustlist.txt", NULL); + etcname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL); if ( !strcmp (etcname, fname) ) /* Same file. */ log_info (_("statement \"%s\" ignored in `%s', line %d\n"), "include-default", fname, lnr); @@ -303,7 +321,7 @@ read_trustfiles (void) log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err)); } xfree (fname); - fname = make_filename (GNUPG_SYSCONFDIR, "trustlist.txt", NULL); + fname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL); allow_include = 0; } err = read_one_trustfile (fname, allow_include, diff --git a/am/cmacros.am b/am/cmacros.am index 7b449e2c0..47538ac19 100644 --- a/am/cmacros.am +++ b/am/cmacros.am @@ -30,6 +30,10 @@ AM_CPPFLAGS += -DGNUPG_BINDIR="\"$(bindir)\"" \ -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\"" endif + +# If a specific protect tool program has been defined, pass its name +# to cc. Note that these macros should not be used directly but via +# the gnupg_module_name function. if GNUPG_AGENT_PGM AM_CPPFLAGS += -DGNUPG_DEFAULT_AGENT="\"@GNUPG_AGENT_PGM@\"" endif @@ -45,3 +49,9 @@ endif if GNUPG_PROTECT_TOOL_PGM AM_CPPFLAGS += -DGNUPG_DEFAULT_PROTECT_TOOL="\"@GNUPG_PROTECT_TOOL_PGM@\"" endif + + +# Convenience macros +libcommon = ../common/libcommon.a +libcommonpth = ../common/libcommonpth.a + diff --git a/common/ChangeLog b/common/ChangeLog index 3f4675de1..f0381229e 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,36 @@ +2007-06-14 Werner Koch + + * simple-pwquery.h (MAP_SPWQ_ERROR_IMPL): New. + (SPWQ_NO_PIN_ENTRY): New. + * simple-pwquery.c (simple_pw_set_socket): New. + (agent_open): Use it if GPG_AGENT_INFO is not set. + (simple_pwquery): Extended to allow returning of otehyr error codes. + + * util.h (GNUPG_MODULE_NAME_AGENT, GNUPG_MODULE_NAME_PINENTRY) + (GNUPG_MODULE_NAME_SCDAEMON, GNUPG_MODULE_NAME_DIRMNGR) + (GNUPG_MODULE_NAME_PROTECT_TOOL): New. + * homedir.c (gnupg_module_name): New. + (gnupg_bindir): New. + +2007-06-12 Werner Koch + + * homedir.c (gnupg_sysconfdir): New. + (gnupg_libexecdir): New. Taken from g10/misc.c:get_libexecdir. + (gnupg_datadir): New. + (gnupg_libdir): New. + + * http.c (connect_server) [W32]: Do not call init_sockets if + HTTP_NO_WSASTARTUP is defined. + + * init.c: New. + + * estream.c (es_init_do): Init stream lock here because we can't + use a static initialization with W32pth. + +2007-06-11 Werner Koch + + * Makefile.am (t_common_ldadd): Use libcommonstd macro. + 2007-06-06 Werner Koch * Makefile.am: Include am/cmacros.am. diff --git a/common/Makefile.am b/common/Makefile.am index 8f70cdc28..51682306d 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -37,6 +37,7 @@ common_sources = \ openpgpdefs.h \ keyserver.h \ sexp-parse.h \ + init.c \ sexputil.c \ sysutils.c sysutils.h \ homedir.c \ @@ -59,6 +60,7 @@ common_sources = \ pka.c pka.h \ http.c http.h + libcommon_a_SOURCES = $(common_sources) if USE_DNS_SRV libcommon_a_SOURCES += srv.c @@ -83,7 +85,7 @@ libgpgrl_a_SOURCES = \ # module_tests = t-convert -t_common_ldadd = ../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a \ +t_common_ldadd = ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) t_convert_DEPENDENCIES = convert.c libcommon.a diff --git a/common/estream.c b/common/estream.c index 05b1230ad..131ddc232 100644 --- a/common/estream.c +++ b/common/estream.c @@ -109,8 +109,6 @@ typedef pth_mutex_t estream_mutex_t; ((pth_mutex_acquire (&(mutex), 1, NULL) == TRUE) ? 0 : -1) # define ESTREAM_MUTEX_INITIALIZE(mutex) \ pth_mutex_init (&(mutex)) -# define ESTREAM_THREADING_INIT() ((pth_init () == TRUE) ? 0 : -1) - #else typedef void *estream_mutex_t; @@ -119,8 +117,6 @@ typedef void *estream_mutex_t; # define ESTREAM_MUTEX_UNLOCK(mutex) (void) 0 # define ESTREAM_MUTEX_TRYLOCK(mutex) 0 # define ESTREAM_MUTEX_INITIALIZE(mutex) (void) 0 -# define ESTREAM_THREADING_INIT() 0 - #endif /* Memory allocator functions. */ @@ -194,13 +190,9 @@ struct estream_list static estream_list_t estream_list; #ifdef HAVE_PTH -/* Note that we can't use a static initialization with W32Pth; however - W32Pth does an implicit initialization anyway. */ -static estream_mutex_t estream_list_lock -# ifndef _W32_PTH_H - = ESTREAM_MUTEX_INITIALIZER -# endif - ; +/* Note that we can't use a static initialization with W32Pth, thus we + do it in es_init. */ +static estream_mutex_t estream_list_lock; #endif #define ESTREAM_LIST_LOCK ESTREAM_MUTEX_LOCK (estream_list_lock) @@ -308,11 +300,18 @@ es_list_iterate (estream_iterator_t iterator) static int es_init_do (void) { - int err; +#ifdef HAVE_PTH + static int initialized; - err = ESTREAM_THREADING_INIT (); - - return err; + if (!initialized) + { + if (!pth_init ()) + return -1; + if (pth_mutex_init (&estream_list_lock)) + initialized = 1; + } +#endif + return 0; } diff --git a/common/homedir.c b/common/homedir.c index 39d6dce20..654c96bec 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -124,3 +124,152 @@ default_homedir (void) return dir; } + + +/* Return the name of the sysconfdir. This is a static string. This + function is required because under Windows we can't simply compile + it in. */ +const char * +gnupg_sysconfdir (void) +{ +#ifdef HAVE_W32_SYSTEM +#warning get the sysconfdir from somewhere else + return GNUPG_SYSCONFDIR; +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_SYSCONFDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +const char * +gnupg_bindir (void) +{ +#ifdef HAVE_W32_SYSTEM + return gnupg_libexecdir (); +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_BINDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Return the name of the libexec directory. The name is allocated in + a static area on the first use. This function won't fail. */ +const char * +gnupg_libexecdir (void) +{ +#ifdef HAVE_W32_SYSTEM + static int got_dir; + static char dir[MAX_PATH+5]; + + if (!got_dir) + { + char *p; + + if ( !GetModuleFileName ( NULL, dir, MAX_PATH) ) + { + log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0)); + *dir = 0; + } + got_dir = 1; + p = strrchr (dir, DIRSEP_C); + if (p) + *p = 0; + else + { + log_debug ("bad filename `%s' returned for this process\n", dir); + *dir = 0; + } + } + + if (*dir) + return dir; + /* Fallback to the hardwired value. */ +#endif /*HAVE_W32_SYSTEM*/ + + return GNUPG_LIBEXECDIR; +} + +const char * +gnupg_libdir (void) +{ +#ifdef HAVE_W32_SYSTEM +#warning get the libdir from somewhere else + return GNUPG_LIBDIR; +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_LIBDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + +const char * +gnupg_datadir (void) +{ +#ifdef HAVE_W32_SYSTEM +#warning get the datadir from somewhere else + return GNUPG_DATADIR; +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_DATADIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Return the file name of a helper tool. WHICH is one of the + GNUPG_MODULE_NAME_foo constants. */ +const char * +gnupg_module_name (int which) +{ + const char *s, *s2; + +#define X(a,b) do { \ + static char *name; \ + if (!name) \ + { \ + s = gnupg_ ## a (); \ + s2 = DIRSEP_S b EXEEXT_S; \ + name = xmalloc (strlen (s) + strlen (s2) + 1); \ + strcpy (stpcpy (name, s), s2); \ + } \ + return name; \ + } while (0) + + switch (which) + { + case GNUPG_MODULE_NAME_AGENT: +#ifdef GNUPG_DEFAULT_AGENT + return GNUPG_DEFAULT_AGENT; +#else + X(bindir, "gpg-agent"); +#endif + + case GNUPG_MODULE_NAME_PINENTRY: +#ifdef GNUPG_DEFAULT_PINENTRY + return GNUPG_DEFAULT_PINENTRY; +#else + X(bindir, "pinentry"); +#endif + + case GNUPG_MODULE_NAME_SCDAEMON: +#ifdef GNUPG_DEFAULT_SCDAEMON + return GNUPG_DEFAULT_SCDAEMON; +#else + X(bindir, "scdaemon"); +#endif + + case GNUPG_MODULE_NAME_DIRMNGR: +#ifdef GNUPG_DEFAULT_DIRMNGR + return GNUPG_DEFAULT_DIRMNGR; +#else + X(bindir, "dirmngr"); +#endif + + case GNUPG_MODULE_NAME_PROTECT_TOOL: +#ifdef GNUPG_DEFAULT_PROTECT_TOOL + return GNUPG_DEFAULT_PROTECT_TOOL; +#else + X(libexecdir, "gpg-protect-tool"); +#endif + + default: + BUG (); + } +#undef X +} diff --git a/common/http.c b/common/http.c index 4693c33e2..293a96a2b 100644 --- a/common/http.c +++ b/common/http.c @@ -30,6 +30,10 @@ - With HTTP_USE_ESTREAM defined, all I/O is done through estream. - With HTTP_USE_GNUTLS support for https is provided (this also requires estream). + - With HTTP_NO_WSASTARTUP the socket initialization is not done + under Windows. This is useful if the socket layer has already + been initialized elsewhere. This also avoids the installation of + an exit handler to cleanup the socket layer. */ #ifdef HAVE_CONFIG_H @@ -200,7 +204,7 @@ struct http_context_s -#ifdef HAVE_W32_SYSTEM +#if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP) #if GNUPG_MAJOR_VERSION == 1 #define REQ_WINSOCK_MAJOR 1 @@ -244,7 +248,7 @@ init_sockets (void) atexit ( deinit_sockets ); initialized = 1; } -#endif /*HAVE_W32_SYSTEM*/ +#endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/ @@ -1504,7 +1508,9 @@ connect_server (const char *server, unsigned short port, #ifdef HAVE_W32_SYSTEM unsigned long inaddr; - init_sockets(); +#ifndef HTTP_NO_WSASTARTUP + init_sockets (); +#endif /* Win32 gethostbyname doesn't handle IP addresses internally, so we try inet_addr first on that platform only. */ inaddr = inet_addr(server); diff --git a/common/init.c b/common/init.c new file mode 100644 index 000000000..9ac6006c2 --- /dev/null +++ b/common/init.c @@ -0,0 +1,73 @@ +/* init.c - Various initializations + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include + +#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */ +#undef HAVE_PTH +#undef USE_GNU_PTH +#endif + +#ifdef HAVE_W32_SYSTEM +#include +#endif +#ifdef HAVE_PTH +#include +#endif + +#include "estream.h" +#include "util.h" + + +/* This function is to be used early at program startup to make sure + that some subsystems are initialized. This is in particualr + important for W32 to initialize the sockets so that our socket + emulation code used directly as well as in libassuan may be used. + It should best be called before any I/O is done so that setup + required for logging is ready. CAUTION: This might be called while + running suid(root). */ +void +init_common_subsystems (void) +{ + /* Try to auto set the character set. */ + set_native_charset (NULL); + +#ifdef HAVE_W32_SYSTEM + /* For W32 we need to initialize the socket layer. This is becuase + we use recv and send in libassuan as well as at some other + places. If we are building with PTH we let pth_init do it. We + can't do much on error so we ignore them. An error would anyway + later pop up if one of the socket functions is used. */ +# ifdef HAVE_PTH + pth_init (); +# else + { + WSADATA wsadat; + + WSAStartup (0x202, &wsadat); + } +# endif /*!HAVE_PTH*/ +#endif + + /* Initialize the Estream library. */ + es_init (); +} + diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c index f0c1cdc00..217ca69cd 100644 --- a/common/simple-pwquery.c +++ b/common/simple-pwquery.c @@ -1,5 +1,5 @@ /* simple-pwquery.c - A simple password query client for gpg-agent - * Copyright (C) 2002, 2004 Free Software Foundation, Inc. + * Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -68,6 +68,11 @@ #endif +/* Name of the socket to be used if GPG_AGENT_INFO has not been + set. No default socket is used if this is NULL. */ +static char *default_gpg_agent_info; + + @@ -154,9 +159,9 @@ readline (int fd, char *buf, size_t buflen) ; if (n) { - break; /* at least one full line available - that's enough. + break; /* At least one full line available - that's enough. This function is just a simple implementation, so - it is okay to forget about pending bytes */ + it is okay to forget about pending bytes. */ } } @@ -304,6 +309,8 @@ agent_open (int *rfd) *rfd = -1; infostr = getenv ( "GPG_AGENT_INFO" ); + if ( !infostr || !*infostr ) + infostr = default_gpg_agent_info; if ( !infostr || !*infostr ) { #ifdef SPWQ_USE_LOGGING @@ -322,6 +329,9 @@ agent_open (int *rfd) { #ifdef SPWQ_USE_LOGGING log_error ( _("malformed GPG_AGENT_INFO environment variable\n")); + log_debug ( "a='%s'\n", infostr); + log_debug ( "a='%s'\n", strchr ( infostr, PATHSEP_C)); + log_debug ( "a=%td\n", (p-infostr)); #endif return SPWQ_NO_AGENT; } @@ -425,13 +435,34 @@ copy_and_escape (char *buffer, const char *text) } +/* Set the name of the default socket to NAME. */ +int +simple_pw_set_socket (const char *name) +{ + spwq_free (default_gpg_agent_info); + if (name) + { + default_gpg_agent_info = spwq_malloc (strlen (name) + 4 + 1); + if (!default_gpg_agent_info) + return SPWQ_OUT_OF_CORE; + /* We don't know the PID thus we use 0. */ + strcpy (stpcpy (default_gpg_agent_info, name), + PATHSEP_S "0" PATHSEP_S "1"); + } + else + default_gpg_agent_info = NULL; + + return 0; +} + + /* Ask the gpg-agent for a passphrase and present the user with a DESCRIPTION, a PROMPT and optionally with a TRYAGAIN extra text. If a CACHEID is not NULL it is used to locate the passphrase in in the cache and store it under this ID. If OPT_CHECK is true gpg-agent is asked to apply some checks on the passphrase security. If ERRORCODE is not NULL it should point a variable receiving an - errorcode; this errocode might be 0 if the user canceled the + errorcode; this error code might be 0 if the user canceled the operation. The function returns NULL to indicate an error. */ char * simple_pwquery (const char *cacheid, @@ -530,7 +561,15 @@ simple_pwquery (const char *cacheid, #ifdef SPWQ_USE_LOGGING log_info (_("canceled by user\n") ); #endif - *errorcode = 0; /* canceled */ + *errorcode = 0; /* Special error code to indicate Cancel. */ + } + else if (nread > 4 && !memcmp (pw, "ERR ", 4)) + { + switch ( (strtoul (pw+4, NULL, 0) & 0xffff) ) + { + case 85: rc = SPWQ_NO_PIN_ENTRY; break; + default: rc = SPWQ_GENERAL_ERROR; break; + } } else { diff --git a/common/simple-pwquery.h b/common/simple-pwquery.h index ab2724ffa..cb5d9354b 100644 --- a/common/simple-pwquery.h +++ b/common/simple-pwquery.h @@ -41,7 +41,6 @@ #define spwq_secure_malloc(a) gcry_malloc_secure (a) #define spwq_secure_free(a) gcry_free (a) - #endif /*SIMPLE_PWQUERY_IMPLEMENTATION*/ /* End configuration stuff. */ @@ -67,6 +66,11 @@ int simple_pwclear (const char *cacheid); terminated) and return the error code. */ int simple_query (const char *query); +/* Set the name of the standard socket to be used if GPG_AGENT_INFO is + not defined. The use of this function is optional but if it needs + to be called before any other function. Returns 0 on success. */ +int simple_pw_set_socket (const char *name); + #define SPWQ_OUT_OF_CORE 1 #define SPWQ_IO_ERROR 2 #define SPWQ_PROTOCOL_ERROR 3 @@ -74,5 +78,40 @@ int simple_query (const char *query); #define SPWQ_NO_AGENT 5 #define SPWQ_SYS_ERROR 6 #define SPWQ_GENERAL_ERROR 7 +#define SPWQ_NO_PIN_ENTRY 8 + + +/* We often need to map error codes to gpg-error style error codes. + To have a consistent mapping this macro may be used to implemt the + mapping function. */ +#define MAP_SPWQ_ERROR_IMPL \ + static gpg_error_t \ + map_spwq_error (int err) \ + { \ + switch (err) \ + { \ + case 0: \ + return 0; \ + case SPWQ_OUT_OF_CORE: \ + return gpg_error_from_errno (ENOMEM); \ + case SPWQ_IO_ERROR: \ + return gpg_error_from_errno (EIO); \ + case SPWQ_PROTOCOL_ERROR: \ + return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); \ + case SPWQ_ERR_RESPONSE: \ + return gpg_error (GPG_ERR_INV_RESPONSE); \ + case SPWQ_NO_AGENT: \ + return gpg_error (GPG_ERR_NO_AGENT); \ + case SPWQ_SYS_ERROR: \ + return gpg_error_from_syserror (); \ + case SPWQ_NO_PIN_ENTRY: \ + return gpg_error (GPG_ERR_NO_PIN_ENTRY); \ + case SPWQ_GENERAL_ERROR: \ + default: \ + return gpg_error (GPG_ERR_GENERAL); \ + } \ + } +/* End of MAP_SPWQ_ERROR_IMPL. */ + #endif /*SIMPLE_PWQUERY_H*/ diff --git a/common/util.h b/common/util.h index 3b7050132..42df1274f 100644 --- a/common/util.h +++ b/common/util.h @@ -120,6 +120,8 @@ gnupg_copy_time (gnupg_isotime_t d, const gnupg_isotime_t s) strcpy (d, s); } +/*-- init.c --*/ +void init_common_subsystems (void); /*-- signal.c --*/ void gnupg_init_signals (int mode, void (*fast_cleanup)(void)); @@ -170,6 +172,20 @@ char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf); /*-- homedir.c --*/ const char *default_homedir (void); +const char *gnupg_sysconfdir (void); +const char *gnupg_bindir (void); +const char *gnupg_libexecdir (void); +const char *gnupg_libdir (void); +const char *gnupg_datadir (void); + +#define GNUPG_MODULE_NAME_AGENT 1 +#define GNUPG_MODULE_NAME_PINENTRY 2 +#define GNUPG_MODULE_NAME_SCDAEMON 3 +#define GNUPG_MODULE_NAME_DIRMNGR 4 +#define GNUPG_MODULE_NAME_PROTECT_TOOL 5 +const char *gnupg_module_name (int which); + + /*-- gpgrlhelp.c --*/ void gnupg_rl_initialize (void); diff --git a/configure.ac b/configure.ac index 3db35c170..d0c318a87 100644 --- a/configure.ac +++ b/configure.ac @@ -363,31 +363,15 @@ AH_BOTTOM([ the values may be overridden by the make invocations; this is to comply with the GNU coding standards. */ #ifdef HAVE_DRIVE_LETTERS + /* FIXME: We need to use a function to determine these values depending + on the actual installation directory. */ #define GNUPG_BINDIR "c:\\gnupg" #define GNUPG_LIBEXECDIR "c:\\gnupg" #define GNUPG_LIBDIR "c:\\gnupg" #define GNUPG_DATADIR "c:\\gnupg" +#define GNUPG_SYSCONFDIR "c:\\gnupg" #endif -/* Setup the hardwired names of modules. */ -#ifndef GNUPG_DEFAULT_AGENT -#define GNUPG_DEFAULT_AGENT ( GNUPG_BINDIR DIRSEP_S "gpg-agent" EXEEXT_S ) -#endif -#ifndef GNUPG_DEFAULT_PINENTRY -#define GNUPG_DEFAULT_PINENTRY ( GNUPG_BINDIR DIRSEP_S "pinentry" EXEEXT_S ) -#endif -#ifndef GNUPG_DEFAULT_SCDAEMON -#define GNUPG_DEFAULT_SCDAEMON ( GNUPG_BINDIR DIRSEP_S "scdaemon" EXEEXT_S ) -#endif -#ifndef GNUPG_DEFAULT_DIRMNGR -#define GNUPG_DEFAULT_DIRMNGR ( GNUPG_BINDIR DIRSEP_S "dirmngr" EXEEXT_S ) -#endif -#ifndef GNUPG_DEFAULT_PROTECT_TOOL -#define GNUPG_DEFAULT_PROTECT_TOOL \ - ( GNUPG_LIBEXECDIR DIRSEP_S "gpg-protect-tool" EXEEXT_S ) -#endif - - /* Derive some other constants. */ #if !(defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)) #define EXEC_TEMPFILE_ONLY @@ -416,6 +400,11 @@ AH_BOTTOM([ /* Our HTTP code is used in estream mode. */ #define HTTP_USE_ESTREAM 1 +/* Under W32 we do an explicit socket initialization, thus we need to + avoid the on-demand initialization which would also install an atexit + handler. */ +#define HTTP_NO_WSASTARTUP + /* We always include support for the OpenPGP card. */ #define ENABLE_CARD_SUPPORT 1 @@ -460,6 +449,7 @@ AC_PROG_LN_S AC_PROG_RANLIB AC_CHECK_TOOL(AR, ar, :) AC_PATH_PROG(PERL,"perl") +AC_CHECK_TOOL(WINDRES, windres, :) AC_ISC_POSIX gl_EARLY AC_SYS_LARGEFILE diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi index eed673c43..69a7f10d7 100644 --- a/doc/gpgsm.texi +++ b/doc/gpgsm.texi @@ -746,6 +746,15 @@ This content of this file is used to maintain the internal state of the random number generator accross invocations. The same file is used by other programs of this software too. +@item S.gpg-agent +@cindex S.gpg-agent +If this file exists and the environment variable @env{GPG_AGENT_INFO} is +not set, @command{gpgsm} will first try to connect to this socket for +accessing @command{gpg-agent} before starting a new @command{gpg-agent} +instance. Under Windows this socket (which in reality be a plain file +describing a regular TCP litening port) is the standard way of +connecting the @command{gpg-agent}. + @end table diff --git a/g10/ChangeLog b/g10/ChangeLog index 17f19a36b..d87d98ec3 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,24 @@ +2007-06-14 Werner Koch + + * call-agent.c (start_agent): Use gnupg_module_name. + +2007-06-12 Werner Koch + + * openfile.c (copy_options_file): Use gnupg_datadir. + * misc.c (get_libexecdir): Remove. Changed all callers to use + gnupg_libexecdir. + * gpg.c (check_permissions): Use gnupg_libdir. + + * gpg.c (main): Replace some calls by init_common_subsystems. + * gpgv.c (main): Ditto. + +2007-06-11 Werner Koch + + * Makefile.am (needed_libs): Use libcommonstd macro. + + * gpgv.c (main) [W32]: Call pth_init. + * gpg.c (main) [W32]: Call pth_init. + 2007-06-08 Werner Koch * Makefile.am (gpg2_LDADD): Syntax fix. diff --git a/g10/Makefile.am b/g10/Makefile.am index 3313aa6bd..defe80409 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -29,7 +29,7 @@ include $(top_srcdir)/am/cmacros.am AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS) -needed_libs = ../common/libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a +needed_libs = $(libcommon) ../jnlib/libjnlib.a ../gl/libgnu.a bin_PROGRAMS = gpg2 gpgv2 diff --git a/g10/call-agent.c b/g10/call-agent.c index 637669176..f2edfc0f4 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -106,7 +106,7 @@ start_agent (void) } if (!opt.agent_program || !*opt.agent_program) - opt.agent_program = GNUPG_DEFAULT_AGENT; + opt.agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); if ( !(pgmname = strrchr (opt.agent_program, '/'))) pgmname = opt.agent_program; else diff --git a/g10/gpg.c b/g10/gpg.c index cdf52afab..b6776de59 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1147,7 +1147,7 @@ check_permissions(const char *path,int item) if(strchr(path,DIRSEP_C)) tmppath=make_filename(path,NULL); else - tmppath=make_filename(GNUPG_LIBDIR,path,NULL); + tmppath=make_filename(gnupg_libdir (),path,NULL); } else tmppath=xstrdup(path); @@ -1814,6 +1814,9 @@ main (int argc, char **argv ) gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING); log_set_prefix ("gpg", 1); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); + /* Check that the libraries are suitable. Do it right here because the option parsing may need services of the library. */ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) @@ -1939,8 +1942,6 @@ main (int argc, char **argv ) assuan_set_assuan_err_source (GPG_ERR_SOURCE_DEFAULT); - set_native_charset (NULL); /* Try to auto set the character set */ - /* Try for a version specific config file first */ if( default_config ) { diff --git a/g10/gpgv.c b/g10/gpgv.c index 6734ee2f7..73f3be09b 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -122,8 +122,13 @@ main( int argc, char **argv ) set_strusage (my_strusage); log_set_prefix ("gpgv", 1); + + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); + gnupg_init_signals (0, NULL); i18n_init(); + opt.command_fd = -1; /* no command fd */ opt.pgp2_workarounds = 1; opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE; @@ -136,8 +141,6 @@ main( int argc, char **argv ) tty_batchmode(1); disable_dotlock(); - set_native_charset (NULL); /* Try to auto set the character set */ - pargs.argc = &argc; pargs.argv = &argv; pargs.flags= 1; /* do not remove the args */ diff --git a/g10/keyserver.c b/g10/keyserver.c index e195e98df..ee11251b9 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -970,7 +970,7 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, byte *line=NULL; struct exec_info *spawn; const char *scheme; - const char *libexecdir = get_libexecdir (); + const char *libexecdir = gnupg_libexecdir (); assert(keyserver); @@ -996,7 +996,7 @@ keyserver_spawn(enum ks_action action,strlist_t list,KEYDB_SEARCH_DESC *desc, After some more thinking about this we came to the conclusion that it is better to load the helpers from the directory where the program of this process lives. Fortunately Windows provides - a way to retrieve this and our get_libexecdir function has been + a way to retrieve this and our gnupg_libexecdir function has been modified to return just this. Setting the exec-path is not anymore required. set_exec_path(libexecdir); diff --git a/g10/misc.c b/g10/misc.c index 89ad92643..c743da614 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -1224,43 +1224,6 @@ is_valid_mailbox (const char *name) } -/* Return the name of the libexec directory. The name is allocated in - a static area on the first use. This function won't fail. */ -const char * -get_libexecdir (void) -{ -#ifdef HAVE_W32_SYSTEM - static int got_dir; - static char dir[MAX_PATH+5]; - - if (!got_dir) - { - char *p; - - if ( !GetModuleFileName ( NULL, dir, MAX_PATH) ) - { - log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0)); - *dir = 0; - } - got_dir = 1; - p = strrchr (dir, DIRSEP_C); - if (p) - *p = 0; - else - { - log_debug ("bad filename `%s' returned for this process\n", dir); - *dir = 0; - } - } - - if (*dir) - return dir; - /* Fallback to the hardwired value. */ -#endif /*HAVE_W32_SYSTEM*/ - - return GNUPG_LIBEXECDIR; -} - /* Similar to access(2), but uses PATH to find the file. */ int path_access(const char *file,int mode) diff --git a/g10/openfile.c b/g10/openfile.c index 008752fb8..095aad9f4 100644 --- a/g10/openfile.c +++ b/g10/openfile.c @@ -330,7 +330,7 @@ open_sigfile( const char *iname, progress_filter_context_t *pfx ) static void copy_options_file( const char *destdir ) { - const char *datadir = GNUPG_DATADIR; + const char *datadir = gnupg_datadir (); char *fname; FILE *src, *dst; int linefeeds=0; @@ -407,6 +407,9 @@ void try_make_homedir( const char *fname ) { const char *defhome = GNUPG_DEFAULT_HOMEDIR; +#ifdef HAVE_W32_SYSTEM +#warning use a function and not a constant +#endif /* Create the directory only if the supplied directory name * is the same as the default one. This way we avoid to create diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index bb2d06574..81f250791 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,3 +1,7 @@ +2007-06-11 Werner Koch + + * utf8conv.c (jnlib_iconv_open, jnlib_iconv, jnlib_iconv_close): New. + 2007-06-06 Werner Koch * w32help.h: New. diff --git a/jnlib/utf8conv.c b/jnlib/utf8conv.c index 90a319984..ac0f2e2e1 100644 --- a/jnlib/utf8conv.c +++ b/jnlib/utf8conv.c @@ -150,6 +150,7 @@ handle_iconv_error (const char *to, const char *from, int use_fallback) } + int set_native_charset (const char *newset) { @@ -694,3 +695,49 @@ utf8_to_native (const char *string, size_t length, int delim) { return do_utf8_to_native (string, length, delim, use_iconv); } + + + + +/* Wrapper function for iconv_open, required for W32 as we dlopen that + library on that system. */ +jnlib_iconv_t +jnlib_iconv_open (const char *tocode, const char *fromcode) +{ +#ifdef HAVE_W32_SYSTEM + if (load_libiconv ()) + return (jnlib_iconv_t)(-1); +#endif /*HAVE_W32_SYSTEM*/ + + return (jnlib_iconv_t)iconv_open (tocode, fromcode); +} + + +/* Wrapper function for iconv, required for W32 as we dlopen that + library on that system. */ +size_t +jnlib_iconv (jnlib_iconv_t cd, + const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + +#ifdef HAVE_W32_SYSTEM + if (load_libiconv ()) + return 0; +#endif /*HAVE_W32_SYSTEM*/ + + return iconv ((iconv_t)cd, inbuf, inbytesleft, outbuf, outbytesleft); +} + +/* Wrapper function for iconv_close, required for W32 as we dlopen that + library on that system. */ +int +jnlib_iconv_close (jnlib_iconv_t cd) +{ +#ifdef HAVE_W32_SYSTEM + if (load_libiconv ()) + return 0; +#endif /*HAVE_W32_SYSTEM*/ + + return iconv_close ((iconv_t)cd); +} diff --git a/jnlib/utf8conv.h b/jnlib/utf8conv.h index 9e1ce9530..757920cac 100644 --- a/jnlib/utf8conv.h +++ b/jnlib/utf8conv.h @@ -30,4 +30,14 @@ char *native_to_utf8 (const char *string); char *utf8_to_native (const char *string, size_t length, int delim); +/* Silly wrappers, required for W32 portability. */ +typedef void *jnlib_iconv_t; + +jnlib_iconv_t jnlib_iconv_open (const char *tocode, const char *fromcode); +size_t jnlib_iconv (jnlib_iconv_t cd, const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft); +int jnlib_iconv_close (jnlib_iconv_t cd); + + + #endif /*LIBJNLIB_UTF8CONF_H*/ diff --git a/kbx/ChangeLog b/kbx/ChangeLog index 169374d73..4631ffe6a 100644 --- a/kbx/ChangeLog +++ b/kbx/ChangeLog @@ -1,3 +1,7 @@ +2007-06-12 Werner Koch + + * kbxutil.c (main): Replace some calls by init_common_subsystems. + 2007-06-06 Werner Koch * kbxutil.c (i18n_init): Remove. diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index ebc69fa61..3919684e5 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -408,7 +408,10 @@ main( int argc, char **argv ) set_strusage( my_strusage ); gcry_control (GCRYCTL_DISABLE_SECMEM); log_set_prefix ("kbxutil", 1); - set_native_charset (NULL); + + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); + i18n_init (); /* Check that the libraries are suitable. Do it here because diff --git a/keyserver/ChangeLog b/keyserver/ChangeLog index c738b82d5..62c29d77a 100644 --- a/keyserver/ChangeLog +++ b/keyserver/ChangeLog @@ -1,3 +1,9 @@ +2007-06-11 Werner Koch + + * gpgkeys_hkp.c (send_key): Rename eof to r_eof as some Windows + header defines such a symbol. + (main): Likewise. + 2007-06-06 Werner Koch * gpgkeys_ldap.c (send_key, send_key_keyserver): Rename eof to diff --git a/keyserver/gpgkeys_hkp.c b/keyserver/gpgkeys_hkp.c index e393b856c..cb86b26c0 100644 --- a/keyserver/gpgkeys_hkp.c +++ b/keyserver/gpgkeys_hkp.c @@ -93,7 +93,7 @@ append_path(char *dest,const char *src) } int -send_key(int *eof) +send_key(int *r_eof) { CURLcode res; char request[MAX_URL+15]; @@ -117,7 +117,7 @@ send_key(int *eof) { /* i.e. eof before the KEY BEGIN was found. This isn't an error. */ - *eof=1; + *r_eof=1; ret=KEYSERVER_OK; goto fail; } @@ -157,7 +157,7 @@ send_key(int *eof) if(!end) { fprintf(console,"gpgkeys: no KEY %s END found\n",keyid); - *eof=1; + *r_eof=1; ret=KEYSERVER_KEY_INCOMPLETE; goto fail; } @@ -768,16 +768,16 @@ main(int argc,char *argv[]) } else if(opt->action==KS_SEND) { - int eof=0; + int myeof=0; do { set_timeout(opt->timeout); - if(send_key(&eof)!=KEYSERVER_OK) + if(send_key(&myeof)!=KEYSERVER_OK) failed++; } - while(!eof); + while(!myeof); } else if(opt->action==KS_SEARCH) { diff --git a/scd/ChangeLog b/scd/ChangeLog index 2e9024e20..ad517f12a 100644 --- a/scd/ChangeLog +++ b/scd/ChangeLog @@ -1,3 +1,15 @@ +2007-06-12 Werner Koch + + * scdaemon.c (main): Replace some calls by init_common_subsystems. + +2007-06-11 Werner Koch + + * Makefile.am (scdaemon_LDADD): Use libcommonpth macro. + + * command.c (initialize_module_command): New. + * scdaemon.c (main) [W32]: Do not use sigpipe code. + (main): Call initialize_module_command. + 2007-06-06 Werner Koch * app-openpgp.c (do_sign): Fix arithmetic on void*. diff --git a/scd/Makefile.am b/scd/Makefile.am index 448211623..c51da4795 100644 --- a/scd/Makefile.am +++ b/scd/Makefile.am @@ -44,7 +44,7 @@ scdaemon_SOURCES = \ app.c app-common.h app-help.c $(card_apps) -scdaemon_LDADD = ../jnlib/libjnlib.a ../common/libcommonpth.a ../gl/libgnu.a \ +scdaemon_LDADD = ../jnlib/libjnlib.a $(libcommonpth) ../gl/libgnu.a \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_PTH_LIBS) $(PTH_LIBS) \ $(LIBUSB_LIBS) $(GPG_ERROR_LIBS) \ $(LIBINTL) $(DL_LIBS) $(NETLIBS) $(LIBICONV) diff --git a/scd/apdu.c b/scd/apdu.c index 57faa7006..7a29ed70e 100644 --- a/scd/apdu.c +++ b/scd/apdu.c @@ -1337,6 +1337,8 @@ open_pcsc_reader (const char *portstr) int err; unsigned int dummy_status; int sw = SW_HOST_CARD_IO_ERROR; + /* Note that we use the constant and not the fucntion because this + code won't be be used under Windows. */ const char *wrapperpgm = GNUPG_LIBEXECDIR "/gnupg-pcsc-wrapper"; if (access (wrapperpgm, X_OK)) diff --git a/scd/command.c b/scd/command.c index 93df064af..3ffa5afb6 100644 --- a/scd/command.c +++ b/scd/command.c @@ -124,7 +124,7 @@ static struct server_local_s *locked_session; /* While doing a reset we need to make sure that the ticker does not call scd_update_reader_status_file while we are using it. */ -static pth_mutex_t status_file_update_lock = PTH_MUTEX_INIT; +static pth_mutex_t status_file_update_lock; /*-- Local prototypes --*/ @@ -132,6 +132,24 @@ static void update_reader_status_file (void); + +/* This function must be called once to initialize this module. This + has to be done before a second thread is spawned. We can't do the + static initialization because Pth emulation code might not be able + to do a static init; in particular, it is not possible for W32. */ +void +initialize_module_command (void) +{ + static int initialized; + + if (!initialized) + { + if (pth_mutex_init (&status_file_update_lock)) + initialized = 1; + } +} + + /* Update the CARD_REMOVED element of all sessions using the reader given by SLOT to VALUE */ static void diff --git a/scd/scdaemon.c b/scd/scdaemon.c index ea97a392c..4fe0918b6 100644 --- a/scd/scdaemon.c +++ b/scd/scdaemon.c @@ -303,8 +303,9 @@ main (int argc, char **argv ) when adding any stuff between here and the call to INIT_SECMEM() somewhere after the option parsing */ log_set_prefix ("scdaemon", 1|4); - /* Try to auto set the character set. */ - set_native_charset (NULL); + + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); i18n_init (); @@ -522,6 +523,8 @@ main (int argc, char **argv ) log_debug ("... okay\n"); } + initialize_module_command (); + if (gpgconf_list == 2) scd_exit (0); if (gpgconf_list) @@ -586,6 +589,7 @@ main (int argc, char **argv ) pth_attr_t tattr; int fd = -1; +#ifndef HAVE_W32_SYSTEM { struct sigaction sa; @@ -594,6 +598,7 @@ main (int argc, char **argv ) sa.sa_flags = 0; sigaction (SIGPIPE, &sa, NULL); } +#endif /* If --debug-allow-core-dump has been given we also need to switch the working directory to a place where we can actually diff --git a/scd/scdaemon.h b/scd/scdaemon.h index 7e5b9fb9b..e1c5109d5 100644 --- a/scd/scdaemon.h +++ b/scd/scdaemon.h @@ -124,6 +124,7 @@ void scd_exit (int rc); const char *scd_get_socket_name (void); /*-- command.c --*/ +void initialize_module_command (void); void scd_command_handler (ctrl_t, int); void send_status_info (ctrl_t ctrl, const char *keyword, ...) GNUPG_GCC_A_SENTINEL(1); diff --git a/sm/ChangeLog b/sm/ChangeLog index 20c7460be..2833c9f6b 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,23 @@ +2007-06-14 Werner Koch + + * call-agent.c (start_agent): Use gnupg_module_name. + * call-dirmngr.c (start_dirmngr): Ditto. + * export.c (export_p12): Ditto. + * import.c (parse_p12): Ditto. + * gpgsm.c (run_protect_tool): Ditto. + +2007-06-12 Werner Koch + + * gpgsm.c (main): Replace some calls by init_common_subsystems. + (main): Use gnupg_datadir. + * qualified.c (read_list): Use gnupg-datadir. + +2007-06-11 Werner Koch + + * Makefile.am (common_libs): Use libcommaonstd macr. + + * gpgsm.c (main) [W32]: Call pth_init. + 2007-06-06 Werner Koch * qualified.c (gpgsm_not_qualified_warning) [!ENABLE_NLS]: Do not diff --git a/sm/Makefile.am b/sm/Makefile.am index 0fce48a40..7e5c154ac 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -54,7 +54,7 @@ gpgsm_SOURCES = \ common_libs = ../jnlib/libjnlib.a ../kbx/libkeybox.a \ - ../common/libcommon.a ../gl/libgnu.a + $(libcommon) ../gl/libgnu.a gpgsm_LDADD = $(common_libs) \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) \ diff --git a/sm/call-agent.c b/sm/call-agent.c index 153f7b34f..1ac5412be 100644 --- a/sm/call-agent.c +++ b/sm/call-agent.c @@ -94,6 +94,10 @@ start_agent (ctrl_t ctrl) sockname = make_filename (opt.homedir, "S.gpg-agent", NULL); rc = assuan_socket_connect (&ctx, sockname, 0); xfree (sockname); +#ifdef HAVE_W32_SYSTEM +# warning Print a warning if connecting is not possible + /* and offer to fire up the agent. */ +#endif if (rc) { @@ -112,7 +116,7 @@ start_agent (ctrl_t ctrl) } if (!opt.agent_program || !*opt.agent_program) - opt.agent_program = GNUPG_DEFAULT_AGENT; + opt.agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); if ( !(pgmname = strrchr (opt.agent_program, '/'))) pgmname = opt.agent_program; else diff --git a/sm/call-dirmngr.c b/sm/call-dirmngr.c index 5cc34e132..8ce4fd8f1 100644 --- a/sm/call-dirmngr.c +++ b/sm/call-dirmngr.c @@ -172,7 +172,7 @@ start_dirmngr (void) int i; if (!opt.dirmngr_program || !*opt.dirmngr_program) - opt.dirmngr_program = GNUPG_DEFAULT_DIRMNGR; + opt.dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR); if ( !(pgmname = strrchr (opt.dirmngr_program, '/'))) pgmname = opt.dirmngr_program; else diff --git a/sm/export.c b/sm/export.c index 93b74bf7b..6420a2154 100644 --- a/sm/export.c +++ b/sm/export.c @@ -604,7 +604,7 @@ export_p12 (ctrl_t ctrl, const unsigned char *certimg, size_t certimglen, int bad_pass = 0; if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgmname = GNUPG_DEFAULT_PROTECT_TOOL; + pgmname = gnupg_module_name (GNUPG_MODULE_NAME_PROTECT_TOOL); else pgmname = opt.protect_tool_program; diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 71559c326..0136680a8 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -747,8 +747,8 @@ main ( int argc, char **argv) somewhere after the option parsing */ log_set_prefix ("gpgsm", 1); - /* Try to auto set the character set. */ - set_native_charset (NULL); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); /* Check that the libraries are suitable. Do it here because the option parse may need services of the library */ @@ -1310,7 +1310,7 @@ main ( int argc, char **argv) /* Import the standard certificates for a new default keybox. */ char *filelist[2]; - filelist[0] = make_filename (GNUPG_DATADIR, "com-certs.pem", NULL); + filelist[0] = make_filename (gnupg_datadir (),"com-certs.pem", NULL); filelist[1] = NULL; if (!access (filelist[0], F_OK)) { @@ -1853,7 +1853,7 @@ run_protect_tool (int argc, char **argv) int i; if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgm = GNUPG_DEFAULT_PROTECT_TOOL; + pgm = gnupg_module_name (GNUPG_MODULE_NAME_PROTECT_TOOL); else pgm = opt.protect_tool_program; diff --git a/sm/import.c b/sm/import.c index f5e7cf00c..687ef3183 100644 --- a/sm/import.c +++ b/sm/import.c @@ -509,7 +509,7 @@ parse_p12 (ctrl_t ctrl, ksba_reader_t reader, int bad_pass = 0; if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgmname = GNUPG_DEFAULT_PROTECT_TOOL; + pgmname = gnupg_module_name (GNUPG_MODULE_NAME_PROTECT_TOOL); else pgmname = opt.protect_tool_program; diff --git a/sm/qualified.c b/sm/qualified.c index 0eabeeba4..d6d31ae95 100644 --- a/sm/qualified.c +++ b/sm/qualified.c @@ -66,7 +66,7 @@ read_list (char *key, char *country, int *lnr) if (!listname) { - listname = make_filename (GNUPG_DATADIR, "qualified.txt", NULL); + listname = make_filename (gnupg_datadir (), "qualified.txt", NULL); listfp = fopen (listname, "r"); if (!listfp && errno != ENOENT) { diff --git a/tools/ChangeLog b/tools/ChangeLog index a75a2b963..680a96c79 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,25 @@ +2007-06-14 Werner Koch + + * symcryptrun.c (main): Setup default socket name for + simple-pwquery. + (MAP_SPWQ_ERROR_IMPL): New. Use it for all spwq error returns. + +2007-06-12 Werner Koch + + * gpgconf-comp.c (gc_process_gpgconf_conf): Replace + GNUPG_SYSCONFDIR by a function call. + + * gpg-connect-agent.c (main): Replace some calls by + init_common_subsystems. + * gpgconf.c (main): Ditto. + * symcryptrun.c (main): Ditto. + +2007-06-11 Werner Koch + + * symcryptrun.c (main) [W32]: Call pth_init. + * gpgconf.c (main) [W32]: Call pth_init + * gpg-connect-agent.c (main) [W32]: Call pth_init. + 2007-06-06 Werner Koch * Makefile.am (bin_PROGRAMS) [W32]: Do not build gpgparsemail. diff --git a/tools/Makefile.am b/tools/Makefile.am index 5728c4ff9..ed967ecb8 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -50,17 +50,19 @@ endif noinst_PROGRAMS = clean-sat mk-tdata make-dns-cert gpgsplit -common_libs = ../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a +common_libs = ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a pwquery_libs = ../common/libsimple-pwquery.a -gpgsplit_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \ +gpgsplit_LDADD = $(common_libs) \ + $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \ $(ZLIBS) $(LIBINTL) $(LIBICONV) gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c no-libgcrypt.c # jnlib/common sucks in gpg-error, will they, nil they (some compilers # do not eliminate the supposed-to-be-unused-inline-functions). -gpgconf_LDADD = $(common_libs) $(LIBINTL) $(GPG_ERROR_LIBS) $(LIBICONV) +gpgconf_LDADD = $(common_libs) \ + $(LIBINTL) $(GPG_ERROR_LIBS) $(LIBICONV) gpgparsemail_SOURCES = gpgparsemail.c rfc822parse.c rfc822parse.h gpgparsemail_LDADD = @@ -73,7 +75,8 @@ watchgnupg_SOURCES = watchgnupg.c watchgnupg_LDADD = $(NETLIBS) gpg_connect_agent_SOURCES = gpg-connect-agent.c no-libgcrypt.c -gpg_connect_agent_LDADD = $(common_libs) $(LIBASSUAN_LIBS) \ +# FIXME: remove PTH_LIBS (why do we need them at all?) +gpg_connect_agent_LDADD = $(common_libs) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) gpgkey2ssh_SOURCES = gpgkey2ssh.c diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index 219d7d01f..7522ea916 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -274,6 +274,10 @@ main (int argc, char **argv) set_strusage (my_strusage); log_set_prefix ("gpg-connect-agent", 1); + + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); + assuan_set_assuan_err_source (0); i18n_init(); diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index 16fa3ad1a..c09078165 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -2676,9 +2676,13 @@ gc_process_gpgconf_conf (const char *fname, int update, int defaults) int runtime[GC_BACKEND_NR]; int used_components[GC_COMPONENT_NR]; int backend_id, component_id; + char *fname_buffer = NULL; if (!fname) - fname = GNUPG_SYSCONFDIR "/gpgconf.conf"; + { + fname_buffer = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL); + fname = fname_buffer; + } for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++) runtime[backend_id] = 0; @@ -2695,6 +2699,7 @@ gc_process_gpgconf_conf (const char *fname, int update, int defaults) gc_error (0, errno, "can not open global config file `%s'", fname); result = -1; } + xfree (fname_buffer); return result; } @@ -2931,5 +2936,6 @@ gc_process_gpgconf_conf (const char *fname, int update, int defaults) } } + xfree (fname_buffer); return result; } diff --git a/tools/gpgconf.c b/tools/gpgconf.c index c06db5225..fdf97932f 100644 --- a/tools/gpgconf.c +++ b/tools/gpgconf.c @@ -116,6 +116,9 @@ main (int argc, char **argv) set_strusage (my_strusage); log_set_prefix ("gpgconf", 1); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); + i18n_init(); /* Parse the command line. */ diff --git a/tools/symcryptrun.c b/tools/symcryptrun.c index f8de30fd9..bca96e58d 100644 --- a/tools/symcryptrun.c +++ b/tools/symcryptrun.c @@ -238,6 +238,8 @@ my_strusage (int level) __result; })) #endif +/* Include the implementation of map_spwq_error. */ +MAP_SPWQ_ERROR_IMPL /* Unlink a file, and shred it if SHRED is true. */ int @@ -455,6 +457,7 @@ confucius_get_pass (const char *cacheid, int again, int *canceled) pw = simple_pwquery (cacheid, again ? _("does not match - try again"):NULL, _("Passphrase:"), NULL, 0, &err); + err = map_spwq_error (err); #ifdef ENABLE_NLS if (orig_codeset) @@ -911,8 +914,8 @@ main (int argc, char **argv) set_strusage (my_strusage); log_set_prefix ("symcryptrun", 1); - /* Try to auto set the character set. */ - set_native_charset (NULL); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); i18n_init(); @@ -1028,13 +1031,22 @@ main (int argc, char **argv) setup_libgcrypt_logging (); gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); + /* Tell simple-pwquery about the the standard socket name. */ + { + char *tmp = make_filename (opt.homedir, "S.gpg-agent", NULL); + simple_pw_set_socket (tmp); + xfree (tmp); + } + if (!opt.class) { log_error (_("no class provided\n")); res = 1; } else if (!strcmp (opt.class, "confucius")) - res = confucius_main (mode, argc, argv); + { + res = confucius_main (mode, argc, argv); + } else { log_error (_("class %s is not supported\n"), opt.class);