diff --git a/ChangeLog b/ChangeLog index 15c9ee138..fe930b9ea 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2010-04-07 Werner Koch + + * autogen.sh: Take a .gnupg-autogen.rc file in account. + + * gl/mkdtemp.c (getpid) [W32CE]: New macro. + 2010-03-24 Werner Koch * configure.ac (AH_BOTTOM): Use /gnupg as the default homedir on diff --git a/agent/ChangeLog b/agent/ChangeLog index d424f2b58..57f5d8d14 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,40 @@ +2010-04-14 Werner Koch + + * trustlist.c (read_one_trustfile): Use estream. + +2010-04-13 Werner Koch + + * findkey.c (read_key_file): Use estream. + (agent_write_private_key): Ditto. + +2010-04-07 Werner Koch + + * gpg-agent.c (handle_connections) [W32]: Assume that PTh support + the handle event. Use a dummy event for W32CE. + (get_agent_scd_notify_event) [W32CE]: Do not build. + + * call-pinentry.c: Remove setenv.h. Include sysutils.h. + (atfork_cb): s/setenv/gnupg_setenv/. + + * gpg-agent.c: Do not include setenv.h. + (main): s/unsetenv/gnupg_unsetenv/. + + * protect.c (calibrate_get_time) [W32CE]: Use GetThreadTimes. + +2010-04-06 Werner Koch + + * call-scd.c [!HAVE_SIGNAL_H]: Do not include signal.h. + + * findkey.c (agent_write_private_key): s/remove/gnupg_remove/. + + * command-ssh.c (search_control_file): Replace rewind by fseek and + clearerr. + * genkey.c (check_passphrase_pattern): Ditto. + + * gpg-agent.c [!HAVE_SIGNAL_H]: Do not include signal.h. + (remove_socket): s/remove/gnupg_remove/. + (create_private_keys_directory): Use gnupg_mkdir. + 2010-03-11 Werner Koch * gpg-agent.c: Include "asshelp.h". diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index fab9b8e1d..01c9fc5fc 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -36,7 +36,7 @@ #include "agent.h" #include -#include "setenv.h" +#include "sysutils.h" #include "i18n.h" #ifdef _POSIX_OPEN_MAX @@ -190,7 +190,7 @@ atfork_cb (void *opaque, int where) { value = session_env_getenv (ctrl->session_env, name); if (value) - setenv (name, value, 1); + gnupg_setenv (name, value, 1); } } } @@ -276,7 +276,7 @@ start_pinentry (ctrl_t ctrl) if (!opt.pinentry_program || !*opt.pinentry_program) opt.pinentry_program = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY); - pgmname = opt.pinentry_program; + pgmname = opt.pinentry_program; if ( !(pgmname = strrchr (opt.pinentry_program, '/'))) pgmname = opt.pinentry_program; else diff --git a/agent/call-scd.c b/agent/call-scd.c index d37183ba6..0cbc836bd 100644 --- a/agent/call-scd.c +++ b/agent/call-scd.c @@ -25,7 +25,9 @@ #include #include #include -#include +#ifdef HAVE_SIGNAL_H +# include +#endif #include #include #ifndef HAVE_W32_SYSTEM @@ -385,7 +387,9 @@ start_scd (ctrl_t ctrl) xfree (databuf); } - /* Tell the scdaemon we want him to send us an event signal. */ + /* Tell the scdaemon we want him to send us an event signal. We + don't support this for W32CE. */ +#ifndef HAVE_W32CE_SYSTEM { char buf[100]; @@ -397,6 +401,7 @@ start_scd (ctrl_t ctrl) #endif assuan_transact (ctx, buf, NULL, NULL, NULL, NULL, NULL, NULL); } +#endif /*HAVE_W32CE_SYSTEM*/ primary_scd_ctx = ctx; primary_scd_ctx_reusable = 0; diff --git a/agent/command-ssh.c b/agent/command-ssh.c index 077d93209..f5e4eaa98 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -721,7 +721,8 @@ search_control_file (FILE *fp, const char *hexgrip, assert (strlen (hexgrip) == 40 ); - rewind (fp); + fseek (fp, 0, SEEK_SET); + clearerr (fp); *r_disabled = 0; next_line: do diff --git a/agent/findkey.c b/agent/findkey.c index 9405342d1..30aa7c938 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -57,9 +57,8 @@ agent_write_private_key (const unsigned char *grip, const void *buffer, size_t length, int force) { char *fname; - FILE *fp; + estream_t fp; char hexgrip[40+4+1]; - int fd; bin2hex (grip, 20, hexgrip); strcpy (hexgrip+40, ".key"); @@ -73,53 +72,30 @@ agent_write_private_key (const unsigned char *grip, return gpg_error (GPG_ERR_GENERAL); } - /* In FORCE mode we would like to create FNAME but only if it does - not already exist. We cannot make this guarantee just using - POSIX (GNU provides the "x" opentype for fopen, however, this is - not portable). Thus, we use the more flexible open function and - then use fdopen to obtain a stream. */ - fd = open (fname, force? (O_CREAT | O_TRUNC | O_WRONLY | O_BINARY) - : (O_CREAT | O_EXCL | O_WRONLY | O_BINARY), - S_IRUSR | S_IWUSR -#ifndef HAVE_W32_SYSTEM - | S_IRGRP -#endif - ); - if (fd < 0) - fp = NULL; - else - { - fp = fdopen (fd, "wb"); - if (!fp) - { - int save_e = errno; - close (fd); - errno = save_e; - } - } - + /* FIXME: On POSIX systems we used include S_IRGRP as well. */ + fp = es_fopen (fname, force? "wb" : "wbx"); if (!fp) { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("can't create `%s': %s\n", fname, strerror (errno)); + gpg_error_t tmperr = gpg_error_from_syserror (); + log_error ("can't create `%s': %s\n", fname, gpg_strerror (tmperr)); xfree (fname); return tmperr; } - if (fwrite (buffer, length, 1, fp) != 1) + if (es_fwrite (buffer, length, 1, fp) != 1) { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("error writing `%s': %s\n", fname, strerror (errno)); - fclose (fp); - remove (fname); + gpg_error_t tmperr = gpg_error_from_syserror (); + log_error ("error writing `%s': %s\n", fname, gpg_strerror (tmperr)); + es_fclose (fp); + gnupg_remove (fname); xfree (fname); return tmperr; } - if ( fclose (fp) ) + if (es_fclose (fp)) { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("error closing `%s': %s\n", fname, strerror (errno)); - remove (fname); + gpg_error_t tmperr = gpg_error_from_syserror (); + log_error ("error closing `%s': %s\n", fname, gpg_strerror (tmperr)); + gnupg_remove (fname); xfree (fname); return tmperr; } @@ -425,7 +401,7 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result) { int rc; char *fname; - FILE *fp; + estream_t fp; struct stat st; unsigned char *buf; size_t buflen, erroff; @@ -438,7 +414,7 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result) strcpy (hexgrip+40, ".key"); fname = make_filename (opt.homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL); - fp = fopen (fname, "rb"); + fp = es_fopen (fname, "rb"); if (!fp) { rc = gpg_error_from_syserror (); @@ -448,23 +424,36 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result) return rc; } - if (fstat (fileno(fp), &st)) + if (fstat (es_fileno (fp), &st)) { rc = gpg_error_from_syserror (); log_error ("can't stat `%s': %s\n", fname, strerror (errno)); xfree (fname); - fclose (fp); + es_fclose (fp); return rc; } buflen = st.st_size; buf = xtrymalloc (buflen+1); - if (!buf || fread (buf, buflen, 1, fp) != 1) + if (!buf) { rc = gpg_error_from_syserror (); - log_error ("error reading `%s': %s\n", fname, strerror (errno)); + log_error ("error allocating %zu bytes for `%s': %s\n", + buflen, fname, strerror (errno)); xfree (fname); - fclose (fp); + es_fclose (fp); + xfree (buf); + return rc; + + } + + if (es_fread (buf, buflen, 1, fp) != 1) + { + rc = gpg_error_from_syserror (); + log_error ("error reading %zu bytes from `%s': %s\n", + buflen, fname, strerror (errno)); + xfree (fname); + es_fclose (fp); xfree (buf); return rc; } @@ -472,7 +461,7 @@ read_key_file (const unsigned char *grip, gcry_sexp_t *result) /* Convert the file into a gcrypt S-expression object. */ rc = gcry_sexp_sscan (&s_skey, &erroff, (char*)buf, buflen); xfree (fname); - fclose (fp); + es_fclose (fp); xfree (buf); if (rc) { diff --git a/agent/genkey.c b/agent/genkey.c index d86296390..9e2f32480 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -117,7 +117,8 @@ check_passphrase_pattern (ctrl_t ctrl, const char *pw) fclose (infp); return 1; /* Error - assume password should not be used. */ } - rewind (infp); + fseek (infp, 0, SEEK_SET); + clearerr (infp); i = 0; argv[i++] = "--null"; @@ -134,7 +135,8 @@ check_passphrase_pattern (ctrl_t ctrl, const char *pw) result = 0; /* Success; i.e. no match. */ /* Overwrite our temporary file. */ - rewind (infp); + fseek (infp, 0, SEEK_SET); + clearerr (infp); for (i=((strlen (pw)+99)/100)*100; i > 0; i--) putc ('\xff', infp); fflush (infp); diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index ee4bb2f17..aa0a40716 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1,6 +1,6 @@ /* gpg-agent.c - The GnuPG Agent - * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, - * 2006, 2007, 2009 Free Software Foundation, Inc. + * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009, + * 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -35,7 +35,9 @@ # include #endif /*!HAVE_W32_SYSTEM*/ #include -#include +#ifdef HAVE_SIGNAL_H +# include +#endif #include #define JNLIB_NEED_LOG_LOGV @@ -46,7 +48,6 @@ #include "i18n.h" #include "mkdtemp.h" /* Gnulib replacement. */ #include "sysutils.h" -#include "setenv.h" #include "gc-opt-flags.h" #include "exechelp.h" #include "asshelp.h" @@ -425,7 +426,7 @@ remove_socket (char *name) { char *p; - remove (name); + gnupg_remove (name); p = strrchr (name, '/'); if (p) { @@ -615,7 +616,7 @@ main (int argc, char **argv ) malloc_hooks.realloc = gcry_realloc; malloc_hooks.free = gcry_free; assuan_set_malloc_hooks (&malloc_hooks); - assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); + assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT); assuan_set_system_hooks (ASSUAN_SYSTEM_PTH); assuan_sock_init (); setup_libassuan_logging (&opt.debug); @@ -994,7 +995,7 @@ main (int argc, char **argv ) exec the program given as arguments). */ #ifndef HAVE_W32_SYSTEM if (!opt.keep_display && !argc) - unsetenv ("DISPLAY"); + gnupg_unsetenv ("DISPLAY"); #endif @@ -1374,7 +1375,7 @@ get_agent_ssh_socket_name (void) /* Under W32, this function returns the handle of the scdaemon notification event. Calling it the first time creates that event. */ -#ifdef HAVE_W32_SYSTEM +#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM) void * get_agent_scd_notify_event (void) { @@ -1412,7 +1413,7 @@ get_agent_scd_notify_event (void) log_debug ("returning notify handle %p\n", the_event); return the_event; } -#endif /*HAVE_W32_SYSTEM*/ +#endif /*HAVE_W32_SYSTEM && !HAVE_W32CE_SYSTEM*/ @@ -1510,7 +1511,7 @@ create_server_socket (char *name, int is_ssh, assuan_sock_nonce_t *nonce) assuan_sock_close (fd); agent_exit (2); } - remove (name); + gnupg_remove (name); rc = assuan_sock_bind (fd, (struct sockaddr*) serv_addr, len); } if (rc != -1 @@ -1556,15 +1557,9 @@ create_private_keys_directory (const char *home) fname = make_filename (home, GNUPG_PRIVATE_KEYS_DIR, NULL); if (stat (fname, &statbuf) && errno == ENOENT) { -#ifdef HAVE_W32_SYSTEM /*FIXME: Setup proper permissions. */ - if (!CreateDirectory (fname, NULL)) - log_error (_("can't create directory `%s': %s\n"), - fname, w32_strerror (-1) ); -#else - if (mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR )) + if (gnupg_mkdir (fname, "-rwx")) log_error (_("can't create directory `%s': %s\n"), fname, strerror (errno) ); -#endif else if (!opt.quiet) log_info (_("directory `%s' created\n"), fname); } @@ -1601,15 +1596,9 @@ create_directories (void) #endif ) { -#ifdef HAVE_W32_SYSTEM - if (!CreateDirectory (home, NULL)) - log_error (_("can't create directory `%s': %s\n"), - home, w32_strerror (-1) ); -#else - if (mkdir (home, S_IRUSR|S_IWUSR|S_IXUSR )) + if (gnupg_mkdir (home, "-rwx")) log_error (_("can't create directory `%s': %s\n"), home, strerror (errno) ); -#endif else { if (!opt.quiet) @@ -1863,14 +1852,14 @@ handle_connections (gnupg_fd_t listen_fd, gnupg_fd_t listen_fd_ssh) pth_sigmask (SIG_UNBLOCK, &sigs, NULL); ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); #else -# ifdef PTH_EVENT_HANDLE - sigs = 0; - ev = pth_event (PTH_EVENT_HANDLE, get_agent_scd_notify_event ()); - signo = 0; -# else +# ifdef HAVE_W32CE_SYSTEM /* Use a dummy event. */ sigs = 0; ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); +# else + sigs = 0; + ev = pth_event (PTH_EVENT_HANDLE, get_agent_scd_notify_event ()); + signo = 0; # endif #endif time_ev = NULL; diff --git a/agent/protect-tool.c b/agent/protect-tool.c index 0fc2002ee..38debb956 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -1249,14 +1249,14 @@ store_private_key (const unsigned char *grip, { log_error ("error writing `%s': %s\n", fname, strerror (errno)); es_fclose (fp); - remove (fname); + gnupg_remove (fname); xfree (fname); return -1; } if (es_fclose (fp)) { log_error ("error closing `%s': %s\n", fname, strerror (errno)); - remove (fname); + gnupg_remove (fname); xfree (fname); return -1; } diff --git a/agent/protect.c b/agent/protect.c index 0e2f52ce9..7f3c1cc42 100644 --- a/agent/protect.c +++ b/agent/protect.c @@ -78,7 +78,11 @@ static void calibrate_get_time (struct calibrate_time_s *data) { #ifdef HAVE_W32_SYSTEM +# ifdef HAVE_W32CE_SYSTEM + GetThreadTimes (GetCurrentThread (), +# else GetProcessTimes (GetCurrentProcess (), +# endif &data->creation_time, &data->exit_time, &data->kernel_time, &data->user_time); #else diff --git a/agent/trustlist.c b/agent/trustlist.c index 3236ae425..0e7e0e114 100644 --- a/agent/trustlist.c +++ b/agent/trustlist.c @@ -116,7 +116,7 @@ read_one_trustfile (const char *fname, int allow_include, int *addr_of_tableidx) { gpg_error_t err = 0; - FILE *fp; + estream_t fp; int n, c; char *p, line[256]; trustitem_t *table, *ti; @@ -128,7 +128,7 @@ read_one_trustfile (const char *fname, int allow_include, tablesize = *addr_of_tablesize; tableidx = *addr_of_tableidx; - fp = fopen (fname, "r"); + fp = es_fopen (fname, "r"); if (!fp) { err = gpg_error_from_syserror (); @@ -136,14 +136,14 @@ read_one_trustfile (const char *fname, int allow_include, goto leave; } - while (fgets (line, DIM(line)-1, fp)) + while (es_fgets (line, DIM(line)-1, fp)) { lnr++; if (!*line || line[strlen(line)-1] != '\n') { /* Eat until end of line. */ - while ( (c=getc (fp)) != EOF && c != '\n') + while ( (c=es_getc (fp)) != EOF && c != '\n') ; err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG : GPG_ERR_INCOMPLETE_LINE); @@ -288,7 +288,7 @@ read_one_trustfile (const char *fname, int allow_include, } tableidx++; } - if ( !err && !feof (fp) ) + if ( !err && !es_feof (fp) ) { err = gpg_error_from_syserror (); log_error (_("error reading `%s', line %d: %s\n"), @@ -296,8 +296,7 @@ read_one_trustfile (const char *fname, int allow_include, } leave: - if (fp) - fclose (fp); + es_fclose (fp); *addr_of_table = table; *addr_of_tablesize = tablesize; *addr_of_tableidx = tableidx; diff --git a/autogen.sh b/autogen.sh index b943c6f77..0f42a90a2 100755 --- a/autogen.sh +++ b/autogen.sh @@ -18,7 +18,7 @@ cvtver () { } check_version () { - if [ `("$1" --version || echo "0") | cvtver` -ge "$2" ]; then + if [ $(( `("$1" --version || echo "0") | cvtver` >= $2 )) = 1 ]; then return 0 fi echo "**Error**: "\`$1\'" not installed or too old." >&2 @@ -45,6 +45,24 @@ if test x"$1" = x"--force"; then shift fi +# Begin list of optional variables sourced from ~/.gnupg-autogen.rc +w32_toolprefixes= +w32_extraoptions= +w32ce_toolprefixes= +w32ce_extraoptions= +amd64_toolprefixes= +# End list of optional variables sourced from ~/.gnupg-autogen.rc +# What follows are variables which are sourced but default to +# environment variables or lacking them hardcoded values. +#w32root= +#w32ce_root= +#amd64root= + +if [ -f "$HOME/.gnupg-autogen.rc" ]; then + echo "sourcing extra definitions from $HOME/.gnupg-autogen.rc" + . "$HOME/.gnupg-autogen.rc" +fi + # Convenience option to use certain configure options for some hosts. myhost="" myhostsub="" @@ -59,6 +77,10 @@ case "$1" in --build-amd64) myhost="amd64" ;; + --build*) + echo "**Error**: invalid build option $1" >&2 + exit 1 + ;; *) ;; esac @@ -76,16 +98,17 @@ if [ "$myhost" = "w32" ]; then fi build=`$tsdir/scripts/config.guess` - extraoptions="" case $myhostsub in ce) - [ -z "$w32root" ] && w32root="$HOME/w32ce_root" - toolprefixes="arm-mingw32ce" - extraoptions="--disable-scdaemon" + [ -z "$w32ce_root" ] && w32root="$HOME/w32ce_root" + toolprefixes="$w32ce_toolprefixes arm-mingw32ce" + extraoptions="--disable-scdaemon $w32ce_extraoptions" ;; *) [ -z "$w32root" ] && w32root="$HOME/w32root" - toolprefixes="i586-mingw32msvc i386-mingw32msvc mingw32" + toolprefixes="$w32_toolprefixes i586-mingw32msvc" + toolprefixes="$toolprefixes i386-mingw32msvc mingw32" + extraoptions="$w32_extraoptions" ;; esac echo "Using $w32root as standard install directory" >&2 @@ -146,10 +169,12 @@ if [ "$myhost" = "amd64" ]; then [ -z "$amd64root" ] && amd64root="$HOME/amd64root" echo "Using $amd64root as standard install directory" >&2 + + toolprefixes="$amd64_toolprefixes x86_64-linux-gnu amd64-linux-gnu" # Locate the cross compiler crossbindir= - for host in x86_64-linux-gnu amd64-linux-gnu; do + for host in $toolprefixes ; do if ${host}-gcc --version >/dev/null 2>&1 ; then crossbindir=/usr/${host}/bin conf_CC="CC=${host}-gcc" @@ -224,7 +249,7 @@ if test "$DIE" = "yes"; then cat < + + * asshelp.c (setup_libassuan_logging): Read ASSUAN_DEBUG envvar. + (my_libassuan_log_handler): Use it. + * sysutils.c (_gnupg_getenv): Implement ASSUAN_DEBUG. + +2010-04-08 Werner Koch + + * w32help.h (_setmode, setmode) [W32CE]: Provide prototype and + macro. + +2010-04-07 Werner Koch + + * mischelp.c (timegm): Replace unsetenv/putenv by gnupg_unsetenv. + + * sysutils.c: Include setenv.h. + (gnupg_setenv, gnupg_unsetenv): New. + + +2010-04-06 Werner Koch + + * sysutils.c (gnupg_mkdir): New. + 2010-03-29 Werner Koch * init.c (sleep_on_exit): Change to 400ms. diff --git a/common/asshelp.c b/common/asshelp.c index 0f744ad00..d07adf7bf 100644 --- a/common/asshelp.c +++ b/common/asshelp.c @@ -36,6 +36,14 @@ #include "asshelp.h" +/* A bitfield that specifies the assuan categories to log. This is + identical to the default log handler of libassuan. We need to do + it ourselves because we use a custom log handler and want to use + the same assuan variables to select the categories to log. */ +static int log_cats; +#define TEST_LOG_CAT(x) (!! (log_cats & (1 << (x - 1)))) + + static int my_libassuan_log_handler (assuan_context_t ctx, void *hook, unsigned int cat, const char *msg) @@ -44,8 +52,9 @@ my_libassuan_log_handler (assuan_context_t ctx, void *hook, (void)ctx; - if (cat != ASSUAN_LOG_CONTROL) - return 0; /* We only want the control channel messages. */ + if (! TEST_LOG_CAT (cat)) + return 0; + dbgval = hook? *(unsigned int*)hook : 0; if (!(dbgval & 1024)) return 0; /* Assuan debugging is not enabled. */ @@ -62,6 +71,13 @@ my_libassuan_log_handler (assuan_context_t ctx, void *hook, void setup_libassuan_logging (unsigned int *debug_var_address) { + char *flagstr; + + flagstr = getenv ("ASSUAN_DEBUG"); + if (flagstr) + log_cats = atoi (flagstr); + else /* Default to log the control channel. */ + log_cats = (1 << (ASSUAN_LOG_CONTROL - 1)); assuan_set_log_cb (my_libassuan_log_handler, debug_var_address); } diff --git a/common/estream.c b/common/estream.c index 41ba4f245..75d5ad694 100644 --- a/common/estream.c +++ b/common/estream.c @@ -118,6 +118,9 @@ void *memrchr (const void *block, int c, size_t size); #ifdef HAVE_W32CE_SYSTEM # define _set_errno(a) gpg_err_set_errno ((a)) +/* Setmode is missing in cegcc but available since CE 5.0. */ +int _setmode (int handle, int mode); +# define setmode(a,b) _setmode ((a),(b)) #else # define _set_errno(a) do { errno = (a); } while (0) #endif diff --git a/common/mischelp.c b/common/mischelp.c index e06be21f2..5c8f1cfab 100644 --- a/common/mischelp.c +++ b/common/mischelp.c @@ -183,11 +183,7 @@ timegm (struct tm *tm) putenv (old_zone); } else -#ifdef HAVE_UNSETENV - unsetenv("TZ"); -#else - putenv("TZ"); -#endif + gnupg_unsetenv("TZ"); tzset(); return answer; diff --git a/common/sysutils.c b/common/sysutils.c index 5eab2b8ba..6ad5e27a9 100644 --- a/common/sysutils.c +++ b/common/sysutils.c @@ -51,6 +51,8 @@ #endif #include +#include "setenv.h" /* Gnulib replacement. */ + #include "util.h" #include "i18n.h" @@ -529,6 +531,97 @@ gnupg_remove (const char *fname) } +/* A wrapper around mkdir which takes a string for the mode argument. + This makes it easier to handle the mode argument which is not + defined on all systems. The format of the modestring is + + "-rwxrwxrwx" + + '-' is a don't care or not set. 'r', 'w', 'x' are read allowed, + write allowed, execution allowed with the first group for the user, + the second for the group and the third for all others. If the + string is shorter than above the missing mode characters are meant + to be not set. */ +int +gnupg_mkdir (const char *name, const char *modestr) +{ +#ifdef HAVE_W32CE_SYSTEM + wchar_t *wname; + (void)modestr; + + wname = utf8_to_wchar (name); + if (!wname) + return -1; + if (!CreateDirectoryW (wname, NULL)) + { + xfree (wname); + return -1; /* ERRNO is automagically provided by gpg-error.h. */ + } + xfree (wname); + return 0; +#elif MKDIR_TAKES_ONE_ARG + (void)modestr; + /* Note: In the case of W32 we better use CreateDirectory and try to + set appropriate permissions. However using mkdir is easier + because this sets ERRNO. */ + return mkdir (name); +#else + mode_t mode = 0; + + if (modestr && *modestr) + { + modestr++; + if (*modestr && *modestr++ == 'r') + mode |= S_IRUSR; + if (*modestr && *modestr++ == 'w') + mode |= S_IWUSR; + if (*modestr && *modestr++ == 'x') + mode |= S_IXUSR; + if (*modestr && *modestr++ == 'r') + mode |= S_IRGRP; + if (*modestr && *modestr++ == 'w') + mode |= S_IWGRP; + if (*modestr && *modestr++ == 'x') + mode |= S_IXGRP; + if (*modestr && *modestr++ == 'r') + mode |= S_IROTH; + if (*modestr && *modestr++ == 'w') + mode |= S_IWOTH; + if (*modestr && *modestr++ == 'x') + mode |= S_IXOTH; + } + return mkdir (home, mode) +#endif +} + + +int +gnupg_setenv (const char *name, const char *value, int overwrite) +{ +#ifdef HAVE_W32CE_SYSTEM + (void)name; + (void)value; + (void)overwrite; + return 0; +#else + setenv (name, value, overwrite); +#endif +} + +int +gnupg_unsetenv (const char *name) +{ +#ifdef HAVE_W32CE_SYSTEM + (void)name; + return 0; +#else +# ifdef HAVE_UNSETENV + unsetenv (name); +# else + putenv (name); +# endif +#endif +} #ifdef HAVE_W32CE_SYSTEM @@ -538,8 +631,22 @@ gnupg_remove (const char *fname) char * _gnupg_getenv (const char *name) { - (void)name; - return NULL; + static int initialized; + static char *assuan_debug; + + if (!initialized) + { + assuan_debug = read_w32_registry_string (NULL, + "\\Software\\GNU\\libassuan", + "debug"); + initialized = 1; + } + + if (!strcmp (name, "ASSUAN_DEBUG")) + return assuan_debug; + else + return NULL; } + #endif /*HAVE_W32CE_SYSTEM*/ diff --git a/common/sysutils.h b/common/sysutils.h index ea3b4253e..a2f74f936 100644 --- a/common/sysutils.h +++ b/common/sysutils.h @@ -49,6 +49,9 @@ FILE *gnupg_tmpfile (void); void gnupg_reopen_std (const char *pgmname); void gnupg_allow_set_foregound_window (pid_t pid); int gnupg_remove (const char *fname); +int gnupg_mkdir (const char *name, const char *modestr); +int gnupg_setenv (const char *name, const char *value, int overwrite); +int gnupg_unsetenv (const char *name); #ifdef HAVE_W32_SYSTEM diff --git a/common/util.h b/common/util.h index 615b776c5..159d66ee2 100644 --- a/common/util.h +++ b/common/util.h @@ -298,6 +298,8 @@ ttyname (int fd) #define getpid() GetCurrentProcessId () char *_gnupg_getenv (const char *name); /* See sysutils.c */ #define getenv(a) _gnupg_getenv ((a)) +char *_gnupg_setenv (const char *name); /* See sysutils.c */ +#define setenv(a,b,c) _gnupg_setenv ((a),(b),(c)) #endif diff --git a/common/w32help.h b/common/w32help.h index 518d4251c..6bc9f6605 100644 --- a/common/w32help.h +++ b/common/w32help.h @@ -28,5 +28,12 @@ int write_w32_registry_string (const char *root, const char *dir, const char *name, const char *value); +/* Other stuff. */ +#ifdef HAVE_W32CE_SYSTEM +/* Setmode is missing in cegcc but available since CE 5.0. */ +int _setmode (int handle, int mode); +# define setmode(a,b) _setmode ((a),(b)) +#endif /*HAVE_W32CE_SYSTEM*/ + #endif /*HAVE_W32_SYSTEM*/ #endif /*LIBJNLIB_MISCHELP_H*/ diff --git a/g10/ChangeLog b/g10/ChangeLog index 52fcf4b8e..fd1167e41 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,8 @@ +2010-04-06 Werner Koch + + * openfile.c (mkdir): Remove. + (try_make_homedir): Use gnupg_mkdir. + 2010-04-01 Werner Koch Use gpg_err_set_errno to set ERRNO. diff --git a/g10/openfile.c b/g10/openfile.c index eb12f0482..101a0f1e4 100644 --- a/g10/openfile.c +++ b/g10/openfile.c @@ -56,10 +56,6 @@ #define CMP_FILENAME(a,b) strcmp( (a), (b) ) #endif -#ifdef MKDIR_TAKES_ONE_ARG -#undef mkdir -#define mkdir(a,b) mkdir(a) -#endif /* FIXME: Implement opt.interactive. */ @@ -444,12 +440,11 @@ try_make_homedir (const char *fname) #endif ) { - if ( mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR) ) + if (gnupg_mkdir (fname, "-rwx")) log_fatal ( _("can't create directory `%s': %s\n"), fname, strerror(errno) ); else if (!opt.quiet ) log_info ( _("directory `%s' created\n"), fname ); copy_options_file( fname ); - } } diff --git a/gl/mkdtemp.c b/gl/mkdtemp.c index e3abb11fd..e8db73908 100644 --- a/gl/mkdtemp.c +++ b/gl/mkdtemp.c @@ -80,6 +80,11 @@ # include #endif +#ifdef HAVE_W32CE_SYSTEM +#include +#define getpid() GetCurrentProcessId () +#endif + #if !_LIBC # define __getpid getpid # define __gettimeofday gettimeofday diff --git a/sm/ChangeLog b/sm/ChangeLog index d1c4becec..cbe0245ea 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,22 @@ +2010-04-14 Werner Koch + + * gpgsm.c (main) [W32CE]: Disable dirmngr for now. + +2010-04-13 Werner Koch + + * sign.c (gpgsm_sign): Do not check qualified status in + no-chain-validation mode. + +2010-04-08 Werner Koch + + * gpgsm.c (open_es_fread): Add arg mode. + (main) : Call with mode "r" instead of "rb". + +2010-04-07 Werner Koch + + * misc.c: Remove setenv.h. Include sysutils.h. + (setup_pinentry_env): s/setenv/gnupg_setenv/ + 2010-03-24 Werner Koch * Makefile.am (gpgsm_LDADD): Add extra_sys_libs. diff --git a/sm/gpgsm.c b/sm/gpgsm.c index 1212bc9b7..41215b08d 100644 --- a/sm/gpgsm.c +++ b/sm/gpgsm.c @@ -434,7 +434,7 @@ static void set_cmd (enum cmd_and_opt_values *ret_cmd, static void emergency_cleanup (void); static int check_special_filename (const char *fname, int for_write); static int open_read (const char *filename); -static estream_t open_es_fread (const char *filename); +static estream_t open_es_fread (const char *filename, const char *mode); static FILE *open_fwrite (const char *filename); static estream_t open_es_fwrite (const char *filename); static void run_protect_tool (int argc, char **argv); @@ -942,6 +942,11 @@ main ( int argc, char **argv) opt.homedir = default_homedir (); +#ifdef HAVE_W32CE_SYSTEM + opt.disable_dirmngr = 1; + opt.no_crl_check = 1; +#endif + /* First check whether we have a config file on the commandline */ orig_argc = argc; orig_argv = argv; @@ -1834,9 +1839,9 @@ main ( int argc, char **argv) if (opt.batch) { if (!argc) /* Create from stdin. */ - fpin = open_es_fread ("-"); + fpin = open_es_fread ("-", "r"); else if (argc == 1) /* From file. */ - fpin = open_es_fread (*argv); + fpin = open_es_fread (*argv, "r"); else wrong_args ("--gen-key --batch [parmfile]"); } @@ -2057,7 +2062,7 @@ open_read (const char *filename) /* Same as open_read but return an estream_t. */ static estream_t -open_es_fread (const char *filename) +open_es_fread (const char *filename, const char *mode) { int fd; estream_t fp; @@ -2068,7 +2073,7 @@ open_es_fread (const char *filename) fd = check_special_filename (filename, 0); if (fd != -1) { - fp = es_fdopen_nc (fd, "rb"); + fp = es_fdopen_nc (fd, mode); if (!fp) { log_error ("es_fdopen(%d) failed: %s\n", fd, strerror (errno)); @@ -2076,7 +2081,7 @@ open_es_fread (const char *filename) } return fp; } - fp = es_fopen (filename, "rb"); + fp = es_fopen (filename, mode); if (!fp) { log_error (_("can't open `%s': %s\n"), filename, strerror (errno)); diff --git a/sm/misc.c b/sm/misc.c index 628b321eb..58ef4833c 100644 --- a/sm/misc.c +++ b/sm/misc.c @@ -30,7 +30,7 @@ #include "gpgsm.h" #include "i18n.h" -#include "setenv.h" +#include "sysutils.h" /* Setup the environment so that the pinentry is able to get all required information. This is used prior to an exec of the @@ -49,7 +49,7 @@ setup_pinentry_env (void) but print a warning. */ value = session_env_getenv (opt.session_env, "GPG_TTY"); if (value) - setenv ("GPG_TTY", value, 1); + gnupg_setenv ("GPG_TTY", value, 1); else if (!(lc=getenv ("GPG_TTY")) || !*lc) { log_error (_("GPG_TTY has not been set - " @@ -57,21 +57,21 @@ setup_pinentry_env (void) lc = ttyname (0); if (!lc) lc = "/dev/tty"; - setenv ("GPG_TTY", lc, 1); + gnupg_setenv ("GPG_TTY", lc, 1); } if (opt.lc_ctype) - setenv ("LC_CTYPE", opt.lc_ctype, 1); + gnupg_setenv ("LC_CTYPE", opt.lc_ctype, 1); #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) else if ( (lc = setlocale (LC_CTYPE, "")) ) - setenv ("LC_CTYPE", lc, 1); + gnupg_setenv ("LC_CTYPE", lc, 1); #endif if (opt.lc_messages) - setenv ("LC_MESSAGES", opt.lc_messages, 1); + gnupg_setenv ("LC_MESSAGES", opt.lc_messages, 1); #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) else if ( (lc = setlocale (LC_MESSAGES, "")) ) - setenv ("LC_MESSAGES", lc, 1); + gnupg_setenv ("LC_MESSAGES", lc, 1); #endif iterator = 0; @@ -81,7 +81,7 @@ setup_pinentry_env (void) continue; /* Already set. */ value = session_env_getenv (opt.session_env, name); if (value) - setenv (name, value, 1); + gnupg_setenv (name, value, 1); } #endif /*!HAVE_W32_SYSTEM*/ diff --git a/sm/sign.c b/sm/sign.c index e6ce05ddd..f902a388d 100644 --- a/sm/sign.c +++ b/sm/sign.c @@ -503,31 +503,34 @@ gpgsm_sign (ctrl_t ctrl, certlist_t signerlist, /* Check whether one of the certificates is qualified. Note that we already validated the certificate and thus the user data stored flag must be available. */ - for (cl=signerlist; cl; cl = cl->next) + if (!opt.no_chain_validation) { - size_t buflen; - char buffer[1]; - - err = ksba_cert_get_user_data (cl->cert, "is_qualified", - &buffer, sizeof (buffer), &buflen); - if (err || !buflen) + for (cl=signerlist; cl; cl = cl->next) { - log_error (_("checking for qualified certificate failed: %s\n"), - gpg_strerror (err)); - rc = err; - goto leave; - } - if (*buffer) - err = gpgsm_qualified_consent (ctrl, cl->cert); - else - err = gpgsm_not_qualified_warning (ctrl, cl->cert); - if (err) - { - rc = err; - goto leave; + size_t buflen; + char buffer[1]; + + err = ksba_cert_get_user_data (cl->cert, "is_qualified", + &buffer, sizeof (buffer), &buflen); + if (err || !buflen) + { + log_error (_("checking for qualified certificate failed: %s\n"), + gpg_strerror (err)); + rc = err; + goto leave; + } + if (*buffer) + err = gpgsm_qualified_consent (ctrl, cl->cert); + else + err = gpgsm_not_qualified_warning (ctrl, cl->cert); + if (err) + { + rc = err; + goto leave; + } } } - + /* Prepare hashing (actually we are figuring out what we have set above). */ rc = gcry_md_open (&data_md, 0, 0); diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c index ae46caea8..8506d6feb 100644 --- a/tools/gpg-connect-agent.c +++ b/tools/gpg-connect-agent.c @@ -210,12 +210,17 @@ gnu_getcwd (void) for (;;) { buffer = xmalloc (size+1); +#ifdef HAVE_W32CE_SYSTEM + strcpy (buffer, "/"); + return buffer; +#else if (getcwd (buffer, size) == buffer) return buffer; xfree (buffer); if (errno != ERANGE) return NULL; size *= 2; +#endif } } @@ -989,7 +994,8 @@ do_open (char *line) if (fd >= 0 && fd < DIM (open_fd_table)) { open_fd_table[fd].inuse = 1; -#ifdef HAVE_W32_SYSTEM +#warning fixme: implement our pipe emulation. +#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM) { HANDLE prochandle, handle, newhandle; @@ -1197,7 +1203,11 @@ main (int argc, char **argv) if (log_get_errorcount (0)) exit (2); +#ifdef HAVE_W32CE_SYSTEM + use_tty = 0; +#else use_tty = (isatty ( fileno (stdin)) && isatty (fileno (stdout))); +#endif if (opt.exec) { @@ -1890,7 +1900,11 @@ handle_inquire (assuan_context_t ctx, char *line) { if (d->is_prog) { +#ifdef HAVE_W32CE_SYSTEM + fp = NULL; +#else fp = popen (d->file, "r"); +#endif if (!fp) log_error ("error executing `%s': %s\n", d->file, strerror (errno)); @@ -1931,8 +1945,10 @@ handle_inquire (assuan_context_t ctx, char *line) ; else if (d->is_prog) { +#ifndef HAVE_W32CE_SYSTEM if (pclose (fp)) log_error ("error running `%s': %s\n", d->file, strerror (errno)); +#endif } else fclose (fp);