From cvs at cvs.gnupg.org Mon Aug 2 15:36:27 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 02 Aug 2010 15:36:27 +0200 Subject: [svn] ksba - r322 - in trunk: . src Message-ID: Author: wk Date: 2010-08-02 15:36:25 +0200 (Mon, 02 Aug 2010) New Revision: 322 Modified: trunk/NEWS trunk/configure.ac trunk/src/ChangeLog trunk/src/ksba.h trunk/src/libksba.def trunk/src/libksba.vers trunk/src/reader.c trunk/src/reader.h trunk/src/writer.c trunk/src/writer.h Log: Add 2 new functions. Bumped version number. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-07-15 18:29:50 UTC (rev 321) +++ trunk/src/ChangeLog 2010-08-02 13:36:25 UTC (rev 322) @@ -1,3 +1,13 @@ +2010-08-02 Werner Koch + + * reader.c (ksba_reader_set_release_notify): New. + (ksba_reader_release): Call notify function. + * reader.h (struct ksba_reader_s): Add NOTIFY_CB and NOTIFY_CB_VALUE. + * writer.c (ksba_writer_set_release_notify): New. + (ksba_writer_release): Call notify function. + * writer.h (struct ksba_writer_s): Add NOTIFY_CB and NOTIFY_CB_VALUE. + * ksba.h, libksba.vers, libksba.def: Add new functions. + 2010-07-15 Werner Koch * cms-parser.c (create_and_run_decoder): Add arg flags. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-07-15 18:29:50 UTC (rev 321) +++ trunk/NEWS 2010-08-02 13:36:25 UTC (rev 322) @@ -1,7 +1,12 @@ -Noteworthy changes in version 1.0.9 (unreleased) +Noteworthy changes in version 1.1.0 (unreleased) ------------------------------------------------ + * Interface changes relative to the 1.0.0 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ksba_reader_set_release_notify NEW + ksba_writer_set_release_notify NEW + Noteworthy changes in version 1.0.8 (2010-07-15) ------------------------------------------------ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-07-15 18:29:50 UTC (rev 321) +++ trunk/configure.ac 2010-08-02 13:36:25 UTC (rev 322) @@ -1,5 +1,6 @@ # configure.ac - for libksba -# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 g10 Code GmbH +# Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, +# 2010 g10 Code GmbH # # This file is part of KSBA # @@ -24,7 +25,7 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [1.0.9]) +m4_define([my_version], [1.1.0]) m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ Modified: trunk/src/ksba.h =================================================================== --- trunk/src/ksba.h 2010-07-15 18:29:50 UTC (rev 321) +++ trunk/src/ksba.h 2010-08-02 13:36:25 UTC (rev 322) @@ -429,6 +429,9 @@ /*-- reader.c --*/ gpg_error_t ksba_reader_new (ksba_reader_t *r_r); void ksba_reader_release (ksba_reader_t r); +gpg_error_t ksba_reader_set_release_notify (ksba_reader_t r, + void (*notify)(void*,ksba_reader_t), + void *notify_value); gpg_error_t ksba_reader_clear (ksba_reader_t r, unsigned char **buffer, size_t *buflen); gpg_error_t ksba_reader_error (ksba_reader_t r); @@ -449,6 +452,9 @@ /*-- writer.c --*/ gpg_error_t ksba_writer_new (ksba_writer_t *r_w); void ksba_writer_release (ksba_writer_t w); +gpg_error_t ksba_writer_set_release_notify (ksba_writer_t w, + void (*notify)(void*,ksba_writer_t), + void *notify_value); int ksba_writer_error (ksba_writer_t w); unsigned long ksba_writer_tell (ksba_writer_t w); gpg_error_t ksba_writer_set_fd (ksba_writer_t w, int fd); Modified: trunk/src/libksba.def =================================================================== --- trunk/src/libksba.def 2010-07-15 18:29:50 UTC (rev 321) +++ trunk/src/libksba.def 2010-08-02 13:36:25 UTC (rev 322) @@ -176,3 +176,6 @@ ksba_writer_write @144 ksba_writer_write_octet_string @145 + ksba_reader_set_release_notify @146 + ksba_writer_set_release_notify @147 + Modified: trunk/src/libksba.vers =================================================================== --- trunk/src/libksba.vers 2010-07-15 18:29:50 UTC (rev 321) +++ trunk/src/libksba.vers 2010-08-02 13:36:25 UTC (rev 322) @@ -85,13 +85,13 @@ ksba_reader_clear; ksba_reader_error; ksba_reader_new; ksba_reader_read; ksba_reader_release; ksba_reader_set_cb; ksba_reader_set_fd; ksba_reader_set_file; ksba_reader_set_mem; - ksba_reader_tell; ksba_reader_unread; + ksba_reader_tell; ksba_reader_unread; ksba_reader_set_release_notify; ksba_writer_error; ksba_writer_get_mem; ksba_writer_new; ksba_writer_release; ksba_writer_set_cb; ksba_writer_set_fd; ksba_writer_set_file; ksba_writer_set_filter; ksba_writer_set_mem; ksba_writer_snatch_mem; ksba_writer_tell; ksba_writer_write; - ksba_writer_write_octet_string; + ksba_writer_write_octet_string; ksba_writer_set_release_notify; local: *; Modified: trunk/src/reader.c =================================================================== --- trunk/src/reader.c 2010-07-15 18:29:50 UTC (rev 321) +++ trunk/src/reader.c 2010-08-02 13:36:25 UTC (rev 322) @@ -1,5 +1,5 @@ /* reader.c - provides the Reader object - * Copyright (C) 2001 g10 Code GmbH + * Copyright (C) 2001, 2010 g10 Code GmbH * * This file is part of KSBA. * @@ -57,6 +57,13 @@ { if (!r) return; + if (r->notify_cb) + { + void (*notify_fnc)(void*,ksba_reader_t) = r->notify_cb; + + r->notify_cb = NULL; + notify_fnc (r->notify_cb_value, r); + } if (r->type == READER_TYPE_MEM) xfree (r->u.mem.buffer); xfree (r->unread.buf); @@ -64,6 +71,24 @@ } +/* Set NOTIFY as function to be called by ksba_reader_release before + resources are actually deallocated. NOTIFY_VALUE is passed to the + called function as its first argument. Note that only the last + registered function will be called; passing NULL for NOTIFY removes + the notification. */ +gpg_error_t +ksba_reader_set_release_notify (ksba_reader_t r, + void (*notify)(void*,ksba_reader_t), + void *notify_value) +{ + if (!r) + return gpg_error (GPG_ERR_INV_VALUE); + r->notify_cb = notify; + r->notify_cb_value = notify_value; + return 0; +} + + /* Clear the error and eof indicators for READER, so that it can be continued to use. Also dicards any unread bytes. This is usually required if the upper layer want to send to send an EOF to indicate Modified: trunk/src/reader.h =================================================================== --- trunk/src/reader.h 2010-07-15 18:29:50 UTC (rev 321) +++ trunk/src/reader.h 2010-08-02 13:36:25 UTC (rev 322) @@ -1,5 +1,5 @@ /* reader.h - internl definitions for the reder object. - * Copyright (C) 2001 g10 Code GmbH + * Copyright (C) 2001, 2010 g10 Code GmbH * * This file is part of KSBA. * @@ -55,6 +55,8 @@ void *value; } cb; /* for READER_TYPE_CB */ } u; + void (*notify_cb)(void*,ksba_reader_t); + void *notify_cb_value; }; Modified: trunk/src/writer.c =================================================================== --- trunk/src/writer.c 2010-07-15 18:29:50 UTC (rev 321) +++ trunk/src/writer.c 2010-08-02 13:36:25 UTC (rev 322) @@ -1,5 +1,5 @@ /* writer.c - provides the Writer object - * Copyright (C) 2001 g10 Code GmbH + * Copyright (C) 2001, 2010 g10 Code GmbH * * This file is part of KSBA. * @@ -60,11 +60,37 @@ { if (!w) return; + if (w->notify_cb) + { + void (*notify_fnc)(void*,ksba_writer_t) = w->notify_cb; + + w->notify_cb = NULL; + notify_fnc (w->notify_cb_value, w); + } if (w->type == WRITER_TYPE_MEM) xfree (w->u.mem.buffer); xfree (w); } + +/* Set NOTIFY as function to be called by ksba_reader_release before + resources are actually deallocated. NOTIFY_VALUE is passed to the + called function as its first argument. Note that only the last + registered function will be called; passing NULL for NOTIFY removes + the notification. */ +gpg_error_t +ksba_writer_set_release_notify (ksba_writer_t w, + void (*notify)(void*,ksba_writer_t), + void *notify_value) +{ + if (!w) + return gpg_error (GPG_ERR_INV_VALUE); + w->notify_cb = notify; + w->notify_cb_value = notify_value; + return 0; +} + + int ksba_writer_error (ksba_writer_t w) { Modified: trunk/src/writer.h =================================================================== --- trunk/src/writer.h 2010-07-15 18:29:50 UTC (rev 321) +++ trunk/src/writer.h 2010-08-02 13:36:25 UTC (rev 322) @@ -1,5 +1,5 @@ /* writer.h - internl definitions for the writer object. - * Copyright (C) 2001 g10 Code GmbH + * Copyright (C) 2001, 2010 g10 Code GmbH * * This file is part of KSBA. * @@ -54,6 +54,8 @@ size_t size; } mem; /* for WRITER_TYPE_MEM */ } u; + void (*notify_cb)(void*,ksba_writer_t); + void *notify_cb_value; }; From cvs at cvs.gnupg.org Mon Aug 2 20:30:23 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 02 Aug 2010 20:30:23 +0200 Subject: [svn] w32pth - r41 - trunk Message-ID: Author: wk Date: 2010-08-02 20:30:22 +0200 (Mon, 02 Aug 2010) New Revision: 41 Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac trunk/libw32pth.def Log: Stupid bug fix Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-07-30 08:01:33 UTC (rev 40) +++ trunk/ChangeLog 2010-08-02 18:30:22 UTC (rev 41) @@ -1,3 +1,11 @@ +2010-08-02 Werner Koch + + Release 2.0.4. + + * configure.ac: Set LT version to C2/A2/R1. + + * libw32pth.def (pth_enter, pth_leave): New. + 2010-07-30 Werner Koch Release 2.0.3. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-07-30 08:01:33 UTC (rev 40) +++ trunk/NEWS 2010-08-02 18:30:22 UTC (rev 41) @@ -1,3 +1,9 @@ +Noteworthy changes in version 2.0.4 (2010-08-02) +------------------------------------------------ + + * Bug fix: Export pth_enter and pth_leave. + + Noteworthy changes in version 2.0.3 (2010-07-30) ------------------------------------------------ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-07-30 08:01:33 UTC (rev 40) +++ trunk/configure.ac 2010-08-02 18:30:22 UTC (rev 41) @@ -26,7 +26,7 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [2.0.3]) +m4_define([my_version], [2.0.4]) m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ @@ -41,7 +41,7 @@ # Please remember to document interface changes in the NEWS file. W32PTH_LT_CURRENT=2 W32PTH_LT_AGE=2 -W32PTH_LT_REVISION=0 +W32PTH_LT_REVISION=1 #------------------- # If the API is changed in an incompatible way: increment the next counter. W32PTH_CONFIG_API_VERSION=1 Modified: trunk/libw32pth.def =================================================================== --- trunk/libw32pth.def 2010-07-30 08:01:33 UTC (rev 40) +++ trunk/libw32pth.def 2010-08-02 18:30:22 UTC (rev 41) @@ -76,3 +76,6 @@ pth_cancel @44 + pth_enter @45 + pth_leave @46 + From cvs at cvs.gnupg.org Mon Aug 2 20:32:37 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 02 Aug 2010 20:32:37 +0200 Subject: [svn] w32pth - r42 - tags Message-ID: Author: wk Date: 2010-08-02 20:32:36 +0200 (Mon, 02 Aug 2010) New Revision: 42 Added: tags/w32pth-2.0.4/ Log: From cvs at cvs.gnupg.org Mon Aug 2 20:54:54 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 02 Aug 2010 20:54:54 +0200 Subject: [svn] GnuPG - r5379 - in trunk: . common dirmngr Message-ID: Author: wk Date: 2010-08-02 20:54:53 +0200 (Mon, 02 Aug 2010) New Revision: 5379 Modified: trunk/ChangeLog trunk/common/ChangeLog trunk/common/estream.c trunk/configure.ac trunk/dirmngr/ChangeLog trunk/dirmngr/Makefile.am trunk/dirmngr/dirmngr_ldap.c trunk/dirmngr/ldap-wrapper-ce.c Log: Add code for a threaded LDAP access to replace the wrapper process. Currently used for W32 and W32CE. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-07-26 14:27:59 UTC (rev 5378) +++ trunk/ChangeLog 2010-08-02 18:54:53 UTC (rev 5379) @@ -1,3 +1,12 @@ +2010-08-02 Werner Koch + + * configure.ac: Require libksba 1.1.0 due to the use of + ksba_reader_set_release_notify. + +2010-07-30 Werner Koch + + * configure.ac (GNUPG_PTH_PATH) [W32]: Require version 2.0.3. + 2010-07-25 Werner Koch * configure.ac (USE_LDAPWRAPPER): AC_DEFINE and AM_CONDITIONAL it. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-07-26 14:27:59 UTC (rev 5378) +++ trunk/common/ChangeLog 2010-08-02 18:54:53 UTC (rev 5379) @@ -1,3 +1,7 @@ +2010-07-26 Werner Koch + + * estream.c (es_func_fp_write) [W32]: Write smaller chunks. + 2010-07-25 Werner Koch * argparse.c (initialize): Use ARGPARSE_PRINT_WARNING constant. Modified: trunk/dirmngr/ChangeLog =================================================================== --- trunk/dirmngr/ChangeLog 2010-07-26 14:27:59 UTC (rev 5378) +++ trunk/dirmngr/ChangeLog 2010-08-02 18:54:53 UTC (rev 5379) @@ -1,3 +1,8 @@ +2010-07-26 Werner Koch + + * dirmngr_ldap.c (print_ldap_entries): Remove special fwrite case + for W32 because that is now handles by estream. + 2010-07-25 Werner Koch * Makefile.am (dirmngr_SOURCES) [!USE_LDAPWRAPPER]: Build Modified: trunk/common/estream.c =================================================================== --- trunk/common/estream.c 2010-07-26 14:27:59 UTC (rev 5378) +++ trunk/common/estream.c 2010-08-02 18:54:53 UTC (rev 5379) @@ -955,7 +955,28 @@ if (file_cookie->fp) - bytes_written = fwrite (buffer, 1, size, file_cookie->fp); + { +#ifdef HAVE_W32_SYSTEM + /* Using an fwrite to stdout connected to the console fails with + the error "Not enough space" for an fwrite size of >= 52KB + (tested on Windows XP SP2). To solve this we always chunk + the writes up into smaller blocks. */ + bytes_written = 0; + while (bytes_written < size) + { + size_t cnt = size - bytes_written; + + if (cnt > 32*1024) + cnt = 32*1024; + if (fwrite ((const char*)buffer + bytes_written, + cnt, 1, file_cookie->fp) != 1) + break; /* Write error. */ + bytes_written += cnt; + } +#else + bytes_written = fwrite (buffer, 1, size, file_cookie->fp); +#endif + } else bytes_written = size; /* Successfully written to the bit bucket. */ if (bytes_written != size) Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-07-26 14:27:59 UTC (rev 5378) +++ trunk/configure.ac 2010-08-02 18:54:53 UTC (rev 5379) @@ -49,7 +49,7 @@ NEED_LIBASSUAN_VERSION=2.0.0 NEED_KSBA_API=1 -NEED_KSBA_VERSION=1.0.2 +NEED_KSBA_VERSION=1.1.0 PACKAGE=$PACKAGE_NAME @@ -785,7 +785,11 @@ # Check whether the GNU Pth library is available # Note, that we include a Pth emulation for W32. # -GNUPG_PATH_PTH +if test "$have_w32_system" = yes; then + GNUPG_PATH_PTH([2.0.4]) +else + GNUPG_PATH_PTH +fi if test "$have_pth" = "yes"; then AC_DEFINE(USE_GNU_PTH, 1, [Defined if the GNU Portable Thread Library should be used]) Modified: trunk/dirmngr/Makefile.am =================================================================== --- trunk/dirmngr/Makefile.am 2010-07-26 14:27:59 UTC (rev 5378) +++ trunk/dirmngr/Makefile.am 2010-08-02 18:54:53 UTC (rev 5379) @@ -36,12 +36,18 @@ BUILT_SOURCES = no-libgcrypt.c +if HAVE_W32_SYSTEM +ldap_url = ldap-url.h ldap-url.c +else +ldap_url = +endif + noinst_HEADERS = dirmngr.h crlcache.h crlfetch.h misc.h dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \ ldapserver.h ldapserver.c certcache.c certcache.h \ cdb.h cdblib.c ldap.c misc.c dirmngr-err.h \ - ocsp.c ocsp.h validate.c validate.h ldap-wrapper.h + ocsp.c ocsp.h validate.c validate.h ldap-wrapper.h $(ldap_url) if USE_LDAPWRAPPER dirmngr_SOURCES += ldap-wrapper.c @@ -52,13 +58,11 @@ dirmngr_LDADD = $(libcommonpth) ../gl/libgnu.a $(DNSLIBS) $(LIBASSUAN_LIBS) \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(PTH_LIBS) $(LIBINTL) $(LIBICONV) - -if HAVE_W32_SYSTEM -ldap_url = ldap-url.h ldap-url.c -else -ldap_url = +if !USE_LDAPWRAPPER +dirmngr_LDADD += $(LDAPLIBS) endif + if USE_LDAPWRAPPER dirmngr_ldap_SOURCES = dirmngr_ldap.c $(ldap_url) no-libgcrypt.c dirmngr_ldap_CFLAGS = $(GPG_ERROR_CFLAGS) Modified: trunk/dirmngr/dirmngr_ldap.c =================================================================== --- trunk/dirmngr/dirmngr_ldap.c 2010-07-26 14:27:59 UTC (rev 5378) +++ trunk/dirmngr/dirmngr_ldap.c 2010-08-02 18:54:53 UTC (rev 5379) @@ -32,6 +32,9 @@ #include #include #include +#ifndef USE_LDAPWRAPPER +# include +#endif #ifdef HAVE_W32_SYSTEM #include @@ -55,10 +58,15 @@ #include "i18n.h" #include "util.h" -/* If we are not using the ldap wrapper process we need to include the - prototype for our module's main function. */ -#ifndef USE_LDAPWRAPPER -#include "./ldap-wrapper.h" +/* With the ldap wrapper, there is no need for the pth_enter and leave + functions; thus we redefine them to nops. If we are not using the + ldap wrapper process we need to include the prototype for our + module's main function. */ +#ifdef USE_LDAPWRAPPER +# define pth_enter() do { } while (0) +# define pth_leave() do { } while (0) +#else +# include "./ldap-wrapper.h" #endif #define DEFAULT_LDAP_TIMEOUT 100 /* Arbitrary long timeout. */ @@ -145,6 +153,7 @@ /* Function called by argparse.c to display information. */ +#ifndef USE_LDAPWRAPPER static const char * my_strusage (int level) { @@ -172,6 +181,7 @@ } return p; } +#endif /*!USE_LDAPWRAPPER*/ int @@ -330,8 +340,10 @@ static void set_timeout (my_opt_t myopt) { -#ifndef HAVE_W32_SYSTEM +#ifdef HAVE_W32_SYSTEM /* FIXME for W32. */ + (void)myopt; +#else if (myopt->alarm_timeout) alarm (myopt->alarm_timeout); #endif @@ -345,8 +357,9 @@ LDAPMessage *item; int any = 0; - for (item = ldap_first_entry (ld, msg); item; - item = ldap_next_entry (ld, item)) + for (pth_enter (), item = ldap_first_entry (ld, msg), pth_leave (); + item; + pth_enter (), item = ldap_next_entry (ld, item), pth_leave ()) { BerElement *berctx; char *attr; @@ -366,8 +379,11 @@ } - for (attr = ldap_first_attribute (ld, item, &berctx); attr; - attr = ldap_next_attribute (ld, item, berctx)) + for (pth_enter (), attr = ldap_first_attribute (ld, item, &berctx), + pth_leave (); + attr; + pth_enter (), attr = ldap_next_attribute (ld, item, berctx), + pth_leave ()) { struct berval **values; int idx; @@ -404,8 +420,10 @@ } } + pth_enter (); values = ldap_get_values_len (ld, item, attr); - + pth_leave (); + if (!values) { if (myopt->verbose) @@ -469,11 +487,7 @@ return -1; } } -#if 1 - /* Note: this does not work for STDOUT on a Windows - console, where it fails with "Not enough space" for - CRLs which are 52 KB or larger. */ -#warning still true - implement in estream + if (es_fwrite (values[0]->bv_val, values[0]->bv_len, 1, myopt->outstream) != 1) { @@ -484,33 +498,7 @@ ber_free (berctx, 0); return -1; } -#else - /* On Windows console STDOUT, we have to break up the - writes into small parts. */ - { - int n = 0; - while (n < values[0]->bv_len) - { - int cnt = values[0]->bv_len - n; - /* The actual limit is (52 * 1024 - 1) on Windows XP SP2. */ -#define MAX_CNT (32*1024) - if (cnt > MAX_CNT) - cnt = MAX_CNT; - - if (es_fwrite (((char *) values[0]->bv_val) + n, cnt, 1, - myopt->outstream) != 1) - { - log_error (_("error writing to stdout: %s\n"), - strerror (errno)); - ldap_value_free_len (values); - ldap_memfree (attr); - ber_free (berctx, 0); - return -1; - } - n += cnt; - } - } -#endif + any = 1; if (!myopt->multi) break; /* Print only the first value. */ @@ -540,6 +528,7 @@ int rc = 0; char *host, *dn, *filter, *attrs[2], *attr; int port; + int ret; host = myopt->host? myopt->host : ludp->lud_host; port = myopt->port? myopt->port : ludp->lud_port; @@ -594,14 +583,19 @@ set_timeout (myopt); + pth_enter (); ld = ldap_init (host, port); + pth_leave (); if (!ld) { log_error (_("LDAP init to `%s:%d' failed: %s\n"), host, port, strerror (errno)); return -1; } - if (ldap_simple_bind_s (ld, myopt->user, myopt->pass)) + pth_enter (); + ret = ldap_simple_bind_s (ld, myopt->user, myopt->pass); + pth_leave (); + if (ret) { log_error (_("binding to `%s:%d' failed: %s\n"), host, port, strerror (errno)); @@ -610,11 +604,13 @@ } set_timeout (myopt); + pth_enter (); rc = ldap_search_st (ld, dn, ludp->lud_scope, filter, myopt->multi && !myopt->attr && ludp->lud_attrs? ludp->lud_attrs:attrs, 0, &myopt->timeout, &msg); + pth_leave (); if (rc == LDAP_SIZELIMIT_EXCEEDED && myopt->multi) { if (es_fwrite ("E\0\0\0\x09truncated", 14, 1, myopt->outstream) != 1) Modified: trunk/dirmngr/ldap-wrapper-ce.c =================================================================== --- trunk/dirmngr/ldap-wrapper-ce.c 2010-07-26 14:27:59 UTC (rev 5378) +++ trunk/dirmngr/ldap-wrapper-ce.c 2010-08-02 18:54:53 UTC (rev 5379) @@ -36,6 +36,7 @@ #include #include #include +#include #include "dirmngr.h" #include "misc.h" @@ -46,260 +47,399 @@ #endif -/* To keep track of the LDAP wrapper state we use this structure. */ -struct wrapper_context_s + +/* Read a fixed amount of data from READER into BUFFER. */ +static gpg_error_t +read_buffer (ksba_reader_t reader, unsigned char *buffer, size_t count) { - struct wrapper_context_s *next; + gpg_error_t err; + size_t nread; + + while (count) + { + err = ksba_reader_read (reader, buffer, count, &nread); + if (err) + return err; + buffer += nread; + count -= nread; + } + return 0; +} - pid_t pid; /* The pid of the wrapper process. */ - int printable_pid; /* Helper to print diagnostics after the process has - been cleaned up. */ - int fd; /* Connected with stdout of the ldap wrapper. */ - gpg_error_t fd_error; /* Set to the gpg_error of the last read error - if any. */ - int log_fd; /* Connected with stderr of the ldap wrapper. */ - pth_event_t log_ev; - ctrl_t ctrl; /* Connection data. */ - int ready; /* Internally used to mark to be removed contexts. */ - ksba_reader_t reader; /* The ksba reader object or NULL. */ - char *line; /* Used to print the log lines (malloced). */ - size_t linesize;/* Allocated size of LINE. */ - size_t linelen; /* Use size of LINE. */ - time_t stamp; /* The last time we noticed ativity. */ -}; -/* We keep a global list of spawed wrapper process. A separate thread - makes use of this list to log error messages and to watch out for - finished processes. */ -static struct wrapper_context_s *wrapper_list; +/* Start the reaper thread for this wrapper. */ +void +ldap_wrapper_launch_thread (void) +{ + /* Not required. */ +} -/* We need to know whether we are shutting down the process. */ -static int shutting_down; -/* Start the reaper thread for this wrapper. */ + +/* Wait until all ldap wrappers have terminated. We assume that the + kill has already been sent to all of them. */ void -ldap_wrapper_launch_thread (void) +ldap_wrapper_wait_connections () { - static int done; - pth_attr_t tattr; + /* Not required. */ +} - if (done) - return; - done = 1; - tattr = pth_attr_new(); - pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); - pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "ldap-reaper"); +/* Cleanup all resources held by the connection associated with + CTRL. This is used after a cancel to kill running wrappers. */ +void +ldap_wrapper_connection_cleanup (ctrl_t ctrl) +{ + (void)ctrl; - if (!pth_spawn (tattr, ldap_wrapper_thread, NULL)) + /* Not required. */ +} + + + +/* The cookie we use to implement the outstream of the wrapper thread. */ +struct outstream_cookie_s +{ + int refcount; /* Reference counter - possible values are 1 and 2. */ + + int eof_seen; /* EOF indicator. */ + size_t buffer_len; /* The valid length of the BUFFER. */ + size_t buffer_pos; /* The next read position of the BUFFER. */ + char buffer[4000]; /* Data buffer. */ +}; + + +/* The writer function for the outstream. This is used to transfer + the output of the ldap wrapper thread to the ksba reader object. */ +static ssize_t +outstream_cookie_writer (void *cookie_arg, const void *buffer, size_t size) +{ + struct outstream_cookie_s *cookie = cookie_arg; + const char *src; + char *dst; + ssize_t nwritten = 0; + + src = buffer; + do { - log_error (_("error spawning ldap wrapper reaper thread: %s\n"), - strerror (errno) ); - dirmngr_exit (1); + /* Wait for free space. */ + while (cookie->buffer_len == DIM (cookie->buffer)) + { + /* Buffer is full: Wait for space. */ + pth_yield (NULL); + } + + /* Copy data. */ + dst = cookie->buffer + cookie->buffer_len; + while (size && cookie->buffer_len < DIM (cookie->buffer)) + { + *dst++ = *src++; + size--; + cookie->buffer_len++; + nwritten++; + } } - pth_attr_destroy (tattr); + while (size); /* Until done. */ + + if (nwritten) + { + /* Signal data is available - a pth_yield is sufficient because + the test is explicit. To increase performance we could do a + pth_yield to the other thread and only fall back to yielding + to any thread if that returns an error (i.e. the other thread + is not runnable). However our w32pth does not yet support + yielding to a specific thread, thus this won't help. */ + pth_yield (NULL); + } + + return nwritten; } +static void +outstream_release_cookie (struct outstream_cookie_s *cookie) +{ + cookie->refcount--; + if (!cookie->refcount) + xfree (cookie); +} +/* Closer function for the outstream. This deallocates the cookie if + it won't be used anymore. */ +static int +outstream_cookie_closer (void *cookie_arg) +{ + struct outstream_cookie_s *cookie = cookie_arg; -/* Wait until all ldap wrappers have terminated. We assume that the - kill has already been sent to all of them. */ -void -ldap_wrapper_wait_connections () + if (!cookie) + return 0; /* Nothing to do. */ + + cookie->eof_seen = 1; /* (only useful if refcount > 1) */ + + assert (cookie->refcount > 0); + outstream_release_cookie (cookie); + return 0; +} + + +/* The KSBA reader callback which takes the output of the ldap thread + form the outstream_cookie_writer and make it available to the ksba + reader. */ +static int +outstream_reader_cb (void *cb_value, char *buffer, size_t count, + size_t *r_nread) { - shutting_down = 1; - while (wrapper_list) - pth_yield (NULL); + struct outstream_cookie_s *cookie = cb_value; + char *dst; + const char *src; + size_t nread = 0; + + if (!buffer && !count && !nread) + return gpg_error (GPG_ERR_NOT_SUPPORTED); /* Rewind is not supported. */ + + *r_nread = 0; + dst = buffer; + + while (cookie->buffer_pos == cookie->buffer_len) + { + if (cookie->eof_seen) + return gpg_error (GPG_ERR_EOF); + + /* Wait for data to become available. */ + pth_yield (NULL); + } + + src = cookie->buffer + cookie->buffer_pos; + while (count && cookie->buffer_pos < cookie->buffer_len) + { + *dst++ = *src++; + count--; + cookie->buffer_pos++; + nread++; + } + + if (cookie->buffer_pos == cookie->buffer_len) + cookie->buffer_pos = cookie->buffer_len = 0; + + /* Now there should be some space available. We do this even if + COUNT was zero so to give the writer end a chance to continue. */ + pth_yield (NULL); + + *r_nread = nread; + return 0; /* Success. */ } +/* This function is called by ksba_reader_release. */ +static void +outstream_reader_released (void *cb_value, ksba_reader_t r) +{ + struct outstream_cookie_s *cookie = cb_value; + + (void)r; + + assert (cookie->refcount > 0); + outstream_release_cookie (cookie); +} + + + /* This function is to be used to release a context associated with the - given reader object. */ + given reader object. This does not release the reader object, though. */ void ldap_wrapper_release_context (ksba_reader_t reader) { - if (!reader ) - return; - - for (ctx=wrapper_list; ctx; ctx=ctx->next) - if (ctx->reader == reader) - { - if (DBG_LOOKUP) - log_info ("releasing ldap worker c=%p pid=%d/%d rdr=%p ctrl=%p/%d\n", - ctx, - (int)ctx->pid, (int)ctx->printable_pid, - ctx->reader, - ctx->ctrl, ctx->ctrl? ctx->ctrl->refcount:0); + (void)reader; + /* Nothing to do. */ +} - ctx->reader = NULL; - SAFE_PTH_CLOSE (ctx->fd); - if (ctx->ctrl) - { - ctx->ctrl->refcount--; - ctx->ctrl = NULL; - } - if (ctx->fd_error) - log_info (_("reading from ldap wrapper %d failed: %s\n"), - ctx->printable_pid, gpg_strerror (ctx->fd_error)); - break; - } + + +/* Free a NULL terminated array of malloced strings and the array + itself. */ +static void +free_arg_list (char **arg_list) +{ + int i; + + if (arg_list) + { + for (i=0; arg_list[i]; i++) + xfree (arg_list[i]); + xfree (arg_list); + } } -/* Cleanup all resources held by the connection associated with - CTRL. This is used after a cancel to kill running wrappers. */ -void -ldap_wrapper_connection_cleanup (ctrl_t ctrl) + +/* Copy ARGV into a new array and prepend one element as name of the + program (which is more or less a stub). We need to allocate all + the strings to get ownership of them. */ +static gpg_error_t +create_arg_list (const char *argv[], char ***r_arg_list) { - struct wrapper_context_s *ctx; + gpg_error_t err; + char **arg_list; + int i, j; - for (ctx=wrapper_list; ctx; ctx=ctx->next) - if (ctx->ctrl && ctx->ctrl == ctrl) - { - ctx->ctrl->refcount--; - ctx->ctrl = NULL; - if (ctx->pid != (pid_t)(-1)) - gnupg_kill_process (ctx->pid); - if (ctx->fd_error) - log_info (_("reading from ldap wrapper %d failed: %s\n"), - ctx->printable_pid, gpg_strerror (ctx->fd_error)); - } + for (i = 0; argv[i]; i++) + ; + arg_list = xtrycalloc (i + 2, sizeof *arg_list); + if (!arg_list) + goto outofcore; + + i = 0; + arg_list[i] = xtrystrdup (""); + if (!arg_list[i]) + goto outofcore; + i++; + for (j=0; argv[j]; j++) + { + arg_list[i] = xtrystrdup (argv[j]); + if (!arg_list[i]) + goto outofcore; + i++; + } + arg_list[i] = NULL; + *r_arg_list = arg_list; + return 0; + + outofcore: + err = gpg_error_from_syserror (); + log_error (_("error allocating memory: %s\n"), strerror (errno)); + free_arg_list (arg_list); + *r_arg_list = NULL; + return err; + } + +/* Parameters passed to the wrapper thread. */ +struct ldap_wrapper_thread_parms +{ + char **arg_list; + estream_t outstream; +}; + +/* The thread which runs the LDAP wrapper. */ +static void * +ldap_wrapper_thread (void *opaque) +{ + struct ldap_wrapper_thread_parms *parms = opaque; + + /*err =*/ ldap_wrapper_main (parms->arg_list, parms->outstream); + + /* FIXME: Do we need to return ERR? */ + + free_arg_list (parms->arg_list); + es_fclose (parms->outstream); + xfree (parms); + return NULL; +} + + + /* Start a new LDAP thread and returns a new libksba reader object at READER. ARGV is a NULL terminated list of arguments for the wrapper. The function returns 0 on success or an error code. */ gpg_error_t -ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[]) +ldap_wrapper (ctrl_t ctrl, ksba_reader_t *r_reader, const char *argv[]) { gpg_error_t err; - pid_t pid; - struct wrapper_context_s *ctx; - int i; - int j; - const char **arg_list; - const char *pgmname; - int outpipe[2], errpipe[2]; + struct ldap_wrapper_thread_parms *parms; + pth_attr_t tattr; + es_cookie_io_functions_t outstream_func = { NULL }; + struct outstream_cookie_s *outstream_cookie; + ksba_reader_t reader; - /* It would be too simple to connect stderr just to our logging - stream. The problem is that if we are running multi-threaded - everything gets intermixed. Clearly we don't want this. So the - only viable solutions are either to have another thread - responsible for logging the messages or to add an option to the - wrapper module to do the logging on its own. Given that we anyway - need a way to rip the child process and this is best done using a - general ripping thread, that thread can do the logging too. */ + (void)ctrl; - *reader = NULL; + *r_reader = NULL; - /* Files: We need to prepare stdin and stdout. We get stderr from - the function. */ - if (!opt.ldap_wrapper_program || !*opt.ldap_wrapper_program) - pgmname = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR_LDAP); - else - pgmname = opt.ldap_wrapper_program; + parms = xtrycalloc (1, sizeof *parms); + if (!parms) + return gpg_error_from_syserror (); - /* Create command line argument array. */ - for (i = 0; argv[i]; i++) - ; - arg_list = xtrycalloc (i + 2, sizeof *arg_list); - if (!arg_list) + err = create_arg_list (argv, &parms->arg_list); + if (err) { - err = gpg_error_from_syserror (); - log_error (_("error allocating memory: %s\n"), strerror (errno)); + xfree (parms); return err; } - for (i = j = 0; argv[i]; i++, j++) - if (!i && argv[i + 1] && !strcmp (*argv, "--pass")) - { - arg_list[j] = "--env-pass"; - setenv ("DIRMNGR_LDAP_PASS", argv[1], 1); - i++; - } - else - arg_list[j] = (char*) argv[i]; - ctx = xtrycalloc (1, sizeof *ctx); - if (!ctx) + outstream_cookie = xtrycalloc (1, sizeof *outstream_cookie); + if (!outstream_cookie) { err = gpg_error_from_syserror (); - log_error (_("error allocating memory: %s\n"), strerror (errno)); - xfree (arg_list); + free_arg_list (parms->arg_list); + xfree (parms); return err; } + outstream_cookie->refcount++; - err = gnupg_create_inbound_pipe (outpipe); + err = ksba_reader_new (&reader); if (!err) - { - err = gnupg_create_inbound_pipe (errpipe); - if (err) - { - close (outpipe[0]); - close (outpipe[1]); - } - } + err = ksba_reader_set_release_notify (reader, + outstream_reader_released, + outstream_cookie); + if (!err) + err = ksba_reader_set_cb (reader, + outstream_reader_cb, outstream_cookie); if (err) { - log_error (_("error creating pipe: %s\n"), gpg_strerror (err)); - xfree (arg_list); - xfree (ctx); + log_error (_("error initializing reader object: %s\n"), + gpg_strerror (err)); + ksba_reader_release (reader); + outstream_release_cookie (outstream_cookie); + free_arg_list (parms->arg_list); + xfree (parms); return err; } - err = gnupg_spawn_process_fd (pgmname, arg_list, - -1, outpipe[1], errpipe[1], &pid); - xfree (arg_list); - close (outpipe[1]); - close (errpipe[1]); - if (err) + + outstream_func.func_write = outstream_cookie_writer; + outstream_func.func_close = outstream_cookie_closer; + parms->outstream = es_fopencookie (outstream_cookie, "wb", outstream_func); + if (!parms->outstream) { - close (outpipe[0]); - close (errpipe[0]); - xfree (ctx); + err = gpg_error_from_syserror (); + free_arg_list (parms->arg_list); + outstream_release_cookie (outstream_cookie); + xfree (parms); return err; } + outstream_cookie->refcount++; - ctx->pid = pid; - ctx->printable_pid = (int) pid; - ctx->fd = outpipe[0]; - ctx->log_fd = errpipe[0]; - ctx->log_ev = pth_event (PTH_EVENT_FD | PTH_UNTIL_FD_READABLE, ctx->log_fd); - if (! ctx->log_ev) + tattr = pth_attr_new(); + pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); + pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 128*1024); + pth_attr_set (tattr, PTH_ATTR_NAME, "ldap-wrapper"); + + if (pth_spawn (tattr, ldap_wrapper_thread, parms)) + parms = NULL; /* Now owned by the thread. */ + else { - xfree (ctx); - return gpg_error_from_syserror (); + err = gpg_error_from_syserror (); + log_error ("error spawning ldap wrapper thread: %s\n", + strerror (errno) ); } - ctx->ctrl = ctrl; - ctrl->refcount++; - ctx->stamp = time (NULL); - - err = ksba_reader_new (reader); - if (!err) - err = ksba_reader_set_cb (*reader, reader_callback, ctx); + pth_attr_destroy (tattr); + if (parms) + { + free_arg_list (parms->arg_list); + es_fclose (parms->outstream); + xfree (parms); + } if (err) { - log_error (_("error initializing reader object: %s\n"), - gpg_strerror (err)); - destroy_wrapper (ctx); - ksba_reader_release (*reader); - *reader = NULL; + ksba_reader_release (reader); return err; } - /* Hook the context into our list of running wrappers. */ - ctx->reader = *reader; - ctx->next = wrapper_list; - wrapper_list = ctx; - if (opt.verbose) - log_info ("ldap wrapper %d started (reader %p)\n", - (int)ctx->pid, ctx->reader); - /* Need to wait for the first byte so we are able to detect an empty output and not let the consumer see an EOF without further error indications. The CRL loading logic assumes that after return @@ -308,19 +448,20 @@ { unsigned char c; - err = read_buffer (*reader, &c, 1); + err = read_buffer (reader, &c, 1); if (err) { - ldap_wrapper_release_context (*reader); - ksba_reader_release (*reader); - *reader = NULL; + ksba_reader_release (reader); + reader = NULL; if (gpg_err_code (err) == GPG_ERR_EOF) return gpg_error (GPG_ERR_NO_DATA); else return err; } - ksba_reader_unread (*reader, &c, 1); + ksba_reader_unread (reader, &c, 1); } + *r_reader = reader; + return 0; } From cvs at cvs.gnupg.org Tue Aug 3 01:35:12 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 03 Aug 2010 01:35:12 +0200 Subject: [svn] assuan - r379 - trunk/src Message-ID: Author: marcus Date: 2010-08-03 01:35:11 +0200 (Tue, 03 Aug 2010) New Revision: 379 Modified: trunk/src/ChangeLog trunk/src/gpgcedev.c Log: 2010-08-03 Marcus Brinkmann * gpgcedev.c: Use index (between 1 and table size) into opnctx_table as public context identifiers, instead using pointers into the table directly (which are not stable under table resize). (OPNCTX_TO_IDX, OPNCTX_FROM_IDX, OPNCTX_VALID_IDX_P): New macros. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-06-29 17:11:03 UTC (rev 378) +++ trunk/src/ChangeLog 2010-08-02 23:35:11 UTC (rev 379) @@ -1,3 +1,10 @@ +2010-08-03 Marcus Brinkmann + + * gpgcedev.c: Use index (between 1 and table size) into + opnctx_table as public context identifiers, instead using pointers + into the table directly (which are not stable under table resize). + (OPNCTX_TO_IDX, OPNCTX_FROM_IDX, OPNCTX_VALID_IDX_P): New macros. + 2010-06-28 Werner Koch * gpgcedev.c (GPG_IOControl) : Unblock threads. Modified: trunk/src/gpgcedev.c =================================================================== --- trunk/src/gpgcedev.c 2010-06-29 17:11:03 UTC (rev 378) +++ trunk/src/gpgcedev.c 2010-08-02 23:35:11 UTC (rev 379) @@ -104,6 +104,10 @@ /* A malloced table of open-context and the number of allocated slots. */ static opnctx_t opnctx_table; static size_t opnctx_table_size; +/* The macros make sure that 0 is never a valid openctx_arg. */ +#define OPNCTX_TO_IDX(ctx_arg) (((ctx_arg) - opnctx_table) + 1) +#define OPNCTX_FROM_IDX(idx) (&opnctx_table[(idx) - 1]) +#define OPNCTX_VALID_IDX_P(idx) ((idx) > 0 && (idx) <= opnctx_table_size) /* A criticial section object used to protect the OPNCTX_TABLE. */ static CRITICAL_SECTION opnctx_table_cs; @@ -216,7 +220,9 @@ /* Return a new opnctx handle and mark it as used. Returns NULL and sets LastError on memory failure etc. opnctx_table_cs must be - locked on entry and is locked on exit. */ + locked on entry and is locked on exit. Note that the returned + pointer is only valid as long as opnctx_table_cs stays locked, as + it is not stable under table reallocation. */ static opnctx_t allocate_opnctx (void) { @@ -256,44 +262,48 @@ /* Verify context CTX, returns NULL if not valid and the pointer to the context if valid. opnctx_table_cs must be locked on entry and - is locked on exit. */ + is locked on exit. Note that the returned pointer is only valid as + long as opnctx_table_cs remains locked. */ opnctx_t -verify_opnctx (opnctx_t ctx) +verify_opnctx (DWORD ctx_arg) { - int idx = ctx - opnctx_table; - if (idx < 0 || idx >= opnctx_table_size) + opnctx_t ctx; + + if (! OPNCTX_VALID_IDX_P (ctx_arg)) { SetLastError (ERROR_INVALID_HANDLE); return NULL; } - if (! opnctx_table[idx].inuse) + ctx = OPNCTX_FROM_IDX (ctx_arg); + + if (! ctx->inuse) { SetLastError (ERROR_INVALID_HANDLE); return NULL; } - return &opnctx_table[idx]; + return ctx; } -/* Verify access CODE for context CTX, returning a reference to the - locked pipe implementation. opnctx_table_cs must be locked on - entry and is locked on exit. */ +/* Verify access CODE for context CTX_ARG, returning a reference to + the locked pipe implementation. opnctx_table_cs must be unlocked + on entry and is unlocked on exit. */ pipeimpl_t -access_opnctx (opnctx_t ctx, DWORD code) +access_opnctx (DWORD ctx_arg, DWORD code) { - int idx; + opnctx_t ctx; + pipeimpl_t pimpl; EnterCriticalSection (&opnctx_table_cs); - idx = ctx - opnctx_table; - if (idx < 0 || idx >= opnctx_table_size || ! opnctx_table[idx].inuse) + ctx = verify_opnctx (ctx_arg); + if (! ctx) { - SetLastError (ERROR_INVALID_HANDLE); + /* Error is set by verify_opnctx. */ LeaveCriticalSection (&opnctx_table_cs); return NULL; } - ctx = &opnctx_table[idx]; - if (!(ctx->access_code & code)) + if (! (ctx->access_code & code)) { SetLastError (ERROR_INVALID_ACCESS); LeaveCriticalSection (&opnctx_table_cs); @@ -305,19 +315,20 @@ ctx->pipeimpl = pipeimpl_new (); if (! ctx->pipeimpl) { - log_debug (" access_opnctx (ctx=0x%p): error: can't create pipe\n", - ctx); + log_debug (" access_opnctx (ctx=%i): error: can't create pipe\n", + ctx_arg); LeaveCriticalSection (&opnctx_table_cs); return NULL; } - log_debug (" access_opnctx (ctx=0x%p): created pipe 0x%p\n", - ctx, ctx->pipeimpl); + log_debug (" access_opnctx (ctx=%i): created pipe 0x%p\n", + ctx_arg, ctx->pipeimpl); } - - EnterCriticalSection (&ctx->pipeimpl->critsect); - ctx->pipeimpl->refcnt++; + pimpl = ctx->pipeimpl; + + EnterCriticalSection (&pimpl->critsect); + pimpl->refcnt++; LeaveCriticalSection (&opnctx_table_cs); - return ctx->pipeimpl; + return pimpl; } @@ -387,6 +398,7 @@ GPG_Open (DWORD devctx, DWORD access_code, DWORD share_mode) { opnctx_t opnctx; + DWORD ctx_arg = 0; log_debug ("GPG_Open (devctx=%p)\n", (void*)devctx); if (devctx != DEVCTX_VALUE) @@ -409,12 +421,14 @@ opnctx->access_code = access_code; opnctx->share_mode = share_mode; - log_debug ("GPG_Open (devctx=%p): success: created context 0x%p\n", - (void*) devctx, opnctx); + ctx_arg = OPNCTX_TO_IDX (opnctx); + log_debug ("GPG_Open (devctx=%p): success: created context %i\n", + (void*) devctx, ctx_arg); + leave: LeaveCriticalSection (&opnctx_table_cs); - return (DWORD)opnctx; + return ctx_arg; } @@ -422,16 +436,16 @@ BOOL GPG_Close (DWORD opnctx_arg) { - opnctx_t opnctx = (opnctx_t)opnctx_arg; + opnctx_t opnctx; BOOL result = FALSE; - log_debug ("GPG_Close (ctx=0x%p)\n", (void*)opnctx); + log_debug ("GPG_Close (ctx=%i)\n", opnctx_arg); EnterCriticalSection (&opnctx_table_cs); - opnctx = verify_opnctx (opnctx); + opnctx = verify_opnctx (opnctx_arg); if (!opnctx) { - log_debug ("GPG_Close (ctx=0x%p): could not find context\n", (void*)opnctx); + log_debug ("GPG_Close (ctx=%i): could not find context\n", opnctx_arg); goto leave; } @@ -459,7 +473,7 @@ opnctx->rvid = 0; opnctx->inuse = 0; result = TRUE; - log_debug ("GPG_Close (ctx=0x%p): success\n", (void*)opnctx); + log_debug ("GPG_Close (ctx=%i): success\n", opnctx_arg); leave: LeaveCriticalSection (&opnctx_table_cs); @@ -471,20 +485,19 @@ DWORD GPG_Read (DWORD opnctx_arg, void *buffer, DWORD count) { - opnctx_t ctx = (opnctx_t)opnctx_arg; pipeimpl_t pimpl; const char *src; char *dst; int result = -1; - log_debug ("GPG_Read (ctx=0x%p, buffer=0x%p, count=%d)\n", - (void*)ctx, buffer, count); + log_debug ("GPG_Read (ctx=%i, buffer=0x%p, count=%d)\n", + opnctx_arg, buffer, count); - pimpl = access_opnctx (ctx, GENERIC_READ); + pimpl = access_opnctx (opnctx_arg, GENERIC_READ); if (!pimpl) { - log_debug ("GPG_Read (ctx=0x%p): error: could not access context\n", - (void*)ctx); + log_debug ("GPG_Read (ctx=%i): error: could not access context\n", + opnctx_arg); return -1; } @@ -496,7 +509,7 @@ /* Check for end of file. */ if (pimpl->flags & PIPE_FLAG_NO_WRITER) { - log_debug ("GPG_Read (ctx=0x%p): success: EOF\n", (void*)ctx); + log_debug ("GPG_Read (ctx=%i): success: EOF\n", opnctx_arg); result = 0; goto leave; } @@ -504,7 +517,7 @@ /* Check for request to unblock once. */ if (pimpl->flags & PIPE_FLAG_UNBLOCK_READER) { - log_debug ("GPG_Read (ctx=0x%p): success: EBUSY (due to unblock request)\n", (void*)ctx); + log_debug ("GPG_Read (ctx=%i): success: EBUSY (due to unblock request)\n", opnctx_arg); pimpl->flags &= ~PIPE_FLAG_UNBLOCK_READER; SetLastError (ERROR_BUSY); result = -1; @@ -512,9 +525,9 @@ } LeaveCriticalSection (&pimpl->critsect); - log_debug ("GPG_Read (ctx=0x%p): waiting: data_available\n", (void*)ctx); + log_debug ("GPG_Read (ctx=%i): waiting: data_available\n", opnctx_arg); WaitForSingleObject (data_available, INFINITE); - log_debug ("GPG_Read (ctx=0x%p): resuming: data_available\n", (void*)ctx); + log_debug ("GPG_Read (ctx=%i): resuming: data_available\n", opnctx_arg); EnterCriticalSection (&pimpl->critsect); goto retry; } @@ -535,10 +548,10 @@ Even if COUNT was passed as NULL and no space is available, signaling must be done. */ if (!SetEvent (pimpl->space_available)) - log_debug ("GPG_Read (ctx=0x%p): warning: SetEvent(space_available) failed: rc=%d\n", - (void*) ctx, (int)GetLastError ()); + log_debug ("GPG_Read (ctx=%i): warning: SetEvent(space_available) failed: rc=%d\n", + opnctx_arg, (int)GetLastError ()); - log_debug ("GPG_Read (ctx=0x%p): success: result=%d\n", (void*)ctx, result); + log_debug ("GPG_Read (ctx=%i): success: result=%d\n", opnctx_arg, result); leave: pipeimpl_unref (pimpl); @@ -550,27 +563,26 @@ DWORD GPG_Write (DWORD opnctx_arg, const void *buffer, DWORD count) { - opnctx_t ctx = (opnctx_t)opnctx_arg; pipeimpl_t pimpl; int result = -1; const char *src; char *dst; size_t nwritten = 0; - log_debug ("GPG_Write (ctx=0x%p, buffer=0x%p, count=%d)\n", (void*)ctx, + log_debug ("GPG_Write (ctx=%i, buffer=0x%p, count=%d)\n", opnctx_arg, buffer, count); - pimpl = access_opnctx (ctx, GENERIC_WRITE); + pimpl = access_opnctx (opnctx_arg, GENERIC_WRITE); if (!pimpl) { - log_debug ("GPG_Write (ctx=0x%p): error: could not access context\n", - (void*)ctx); + log_debug ("GPG_Write (ctx=%i): error: could not access context\n", + opnctx_arg); return -1; } if (!count) { - log_debug ("GPG_Write (ctx=0x%p): success\n", (void*)ctx); + log_debug ("GPG_Write (ctx=%i): success\n", opnctx_arg); result = 0; goto leave; } @@ -579,7 +591,7 @@ /* Check for broken pipe. */ if (pimpl->flags & PIPE_FLAG_NO_READER) { - log_debug ("GPG_Write (ctx=0x%p): error: broken pipe\n", (void*)ctx); + log_debug ("GPG_Write (ctx=%i): error: broken pipe\n", opnctx_arg); SetLastError (ERROR_BROKEN_PIPE); goto leave; } @@ -587,7 +599,7 @@ /* Check for request to unblock once. */ if (pimpl->flags & PIPE_FLAG_UNBLOCK_WRITER) { - log_debug ("GPG_Write (ctx=0x%p): success: EBUSY (due to unblock request)\n", (void*)ctx); + log_debug ("GPG_Write (ctx=%i): success: EBUSY (due to unblock request)\n", opnctx_arg); pimpl->flags &= ~PIPE_FLAG_UNBLOCK_WRITER; SetLastError (ERROR_BUSY); result = -1; @@ -600,9 +612,9 @@ /* Buffer is full. */ HANDLE space_available = pimpl->space_available; LeaveCriticalSection (&pimpl->critsect); - log_debug ("GPG_Write (ctx=0x%p): waiting: space_available\n", (void*)ctx); + log_debug ("GPG_Write (ctx=%i): waiting: space_available\n", opnctx_arg); WaitForSingleObject (space_available, INFINITE); - log_debug ("GPG_Write (ctx=0x%p): resuming: space_available\n", (void*)ctx); + log_debug ("GPG_Write (ctx=%i): resuming: space_available\n", opnctx_arg); EnterCriticalSection (&pimpl->critsect); goto retry; } @@ -619,10 +631,10 @@ result = nwritten; if (!SetEvent (pimpl->data_available)) - log_debug ("GPG_Write (ctx=0x%p): warning: SetEvent(data_available) failed: rc=%d\n", - (void*) ctx, (int)GetLastError ()); + log_debug ("GPG_Write (ctx=%i): warning: SetEvent(data_available) failed: rc=%d\n", + opnctx_arg, (int)GetLastError ()); - log_debug ("GPG_Write (ctx=0x%p): success: result=%d\n", (void*)ctx, result); + log_debug ("GPG_Write (ctx=%i): success: result=%d\n", opnctx_arg, result); leave: pipeimpl_unref (pimpl); @@ -632,7 +644,7 @@ DWORD -GPG_Seek (DWORD opnctx, long amount, WORD type) +GPG_Seek (DWORD opnctx_arg, long amount, WORD type) { SetLastError (ERROR_SEEK_ON_DEVICE); return -1; /* Error. */ @@ -644,14 +656,15 @@ static BOOL make_pipe (opnctx_t ctx, LONG rvid) { + DWORD ctx_arg = OPNCTX_TO_IDX (ctx); opnctx_t peerctx = NULL; int idx; - log_debug (" make_pipe (ctx=0x%p, rvid=%08lx)\n", ctx, rvid); + log_debug (" make_pipe (ctx=%i, rvid=%08lx)\n", ctx_arg, rvid); if (ctx->pipeimpl) { - log_debug (" make_pipe (ctx=0x%p): error: already assigned\n", ctx); + log_debug (" make_pipe (ctx=%i): error: already assigned\n", ctx_arg); SetLastError (ERROR_ALREADY_ASSIGNED); return FALSE; } @@ -664,14 +677,14 @@ } if (! peerctx) { - log_debug (" make_pipe (ctx=0x%p): error: not found\n", ctx); + log_debug (" make_pipe (ctx=%i): error: not found\n", ctx_arg); SetLastError (ERROR_NOT_FOUND); return FALSE; } if (peerctx == ctx) { - log_debug (" make_pipe (ctx=0x%p): error: target and source identical\n", ctx); + log_debug (" make_pipe (ctx=%i): error: target and source identical\n", ctx_arg); SetLastError (ERROR_INVALID_TARGET_HANDLE); return FALSE; } @@ -682,7 +695,7 @@ if (!(peerctx->access_code & GENERIC_WRITE)) { SetLastError (ERROR_INVALID_ACCESS); - log_debug (" make_pipe (ctx=0x%p): error: peer is not writer\n", ctx); + log_debug (" make_pipe (ctx=%i): error: peer is not writer\n", ctx_arg); return FALSE; } } @@ -692,14 +705,14 @@ if (!(peerctx->access_code & GENERIC_READ)) { SetLastError (ERROR_INVALID_ACCESS); - log_debug (" make_pipe (ctx=0x%p): error: peer is not reader\n", ctx); + log_debug (" make_pipe (ctx=%i): error: peer is not reader\n", ctx_arg); return FALSE; } } else { SetLastError (ERROR_INVALID_ACCESS); - log_debug (" make_pipe (ctx=0x%p): error: invalid access\n", ctx); + log_debug (" make_pipe (ctx=%i): error: invalid access\n", ctx_arg); return FALSE; } @@ -710,19 +723,19 @@ peerctx->pipeimpl = pipeimpl_new (); if (! peerctx->pipeimpl) { - log_debug (" make_pipe (ctx=0x%p): error: can't create pipe\n", - ctx); + log_debug (" make_pipe (ctx=%i): error: can't create pipe\n", + ctx_arg); return FALSE; } - log_debug (" make_pipe (ctx=0x%p): created pipe 0x%p\n", - ctx, peerctx->pipeimpl); + log_debug (" make_pipe (ctx=%i): created pipe 0x%p\n", + ctx_arg, peerctx->pipeimpl); } EnterCriticalSection (&peerctx->pipeimpl->critsect); peerctx->pipeimpl->refcnt++; ctx->pipeimpl = peerctx->pipeimpl; LeaveCriticalSection (&peerctx->pipeimpl->critsect); - log_debug (" make_pipe (ctx=0x%p): success: combined with peer ctx=0x%p (pipe 0x%p)\n", - ctx, peerctx, peerctx->pipeimpl); + log_debug (" make_pipe (ctx=%i): success: combined with peer ctx=%i (pipe 0x%p)\n", + ctx_arg, OPNCTX_TO_IDX (peerctx), peerctx->pipeimpl); return TRUE; } @@ -756,37 +769,37 @@ GPG_IOControl (DWORD opnctx_arg, DWORD code, void *inbuf, DWORD inbuflen, void *outbuf, DWORD outbuflen, DWORD *actualoutlen) { - opnctx_t opnctx = (opnctx_t)opnctx_arg; + opnctx_t opnctx; BOOL result = FALSE; LONG rvid; - log_debug ("GPG_IOControl (ctx=0x%p, %08x)\n", (void*)opnctx, code); + log_debug ("GPG_IOControl (ctx=%i, %08x)\n", opnctx_arg, code); EnterCriticalSection (&opnctx_table_cs); - opnctx = verify_opnctx (opnctx); + opnctx = verify_opnctx (opnctx_arg); if (!opnctx) { - log_debug ("GPG_IOControl (ctx=0x%p): error: could not access context\n", - (void*)opnctx); + log_debug ("GPG_IOControl (ctx=%i): error: could not access context\n", + opnctx_arg); goto leave; } switch (code) { case GPGCEDEV_IOCTL_GET_RVID: - log_debug ("GPG_IOControl (ctx=0x%p): code: GET_RVID\n", (void*)opnctx); + log_debug ("GPG_IOControl (ctx=%i): code: GET_RVID\n", opnctx_arg); if (inbuf || inbuflen || !outbuf || outbuflen < sizeof (LONG)) { - log_debug ("GPG_IOControl (ctx=0x%p): error: invalid parameter\n", - (void*)opnctx); + log_debug ("GPG_IOControl (ctx=%i): error: invalid parameter\n", + opnctx_arg); SetLastError (ERROR_INVALID_PARAMETER); goto leave; } if (! opnctx->rvid) opnctx->rvid = create_rendezvous_id (); - log_debug ("GPG_IOControl (ctx=0x%p): returning rvid: %08lx\n", - (void*)opnctx, opnctx->rvid); + log_debug ("GPG_IOControl (ctx=%i): returning rvid: %08lx\n", + opnctx_arg, opnctx->rvid); memcpy (outbuf, &opnctx->rvid, sizeof (LONG)); if (actualoutlen) @@ -795,28 +808,28 @@ break; case GPGCEDEV_IOCTL_MAKE_PIPE: - log_debug ("GPG_IOControl (ctx=0x%p): code: MAKE_PIPE\n", (void*)opnctx); + log_debug ("GPG_IOControl (ctx=%i): code: MAKE_PIPE\n", opnctx_arg); if (!inbuf || inbuflen < sizeof (LONG) || outbuf || outbuflen || actualoutlen) { - log_debug ("GPG_IOControl (ctx=0x%p): error: invalid parameter\n", - (void*)opnctx); + log_debug ("GPG_IOControl (ctx=%i): error: invalid parameter\n", + opnctx_arg); SetLastError (ERROR_INVALID_PARAMETER); goto leave; } memcpy (&rvid, inbuf, sizeof (LONG)); - log_debug ("GPG_IOControl (ctx=0x%p): requesting to finish pipe for rvid: %08lx\n", - (void*)opnctx, rvid); + log_debug ("GPG_IOControl (ctx=%i): requesting to finish pipe for rvid: %08lx\n", + opnctx_arg, rvid); if (make_pipe (opnctx, rvid)) result = TRUE; break; case GPGCEDEV_IOCTL_UNBLOCK: - log_debug ("GPG_IOControl (ctx=0x%p): code: UNBLOCK\n", (void*)opnctx); + log_debug ("GPG_IOControl (ctx=%i): code: UNBLOCK\n", opnctx_arg); if (inbuf || inbuflen || outbuf || outbuflen || actualoutlen) { - log_debug ("GPG_IOControl (ctx=0x%p): error: invalid parameter\n", - (void*)opnctx); + log_debug ("GPG_IOControl (ctx=%i): error: invalid parameter\n", + opnctx_arg); SetLastError (ERROR_INVALID_PARAMETER); goto leave; } @@ -831,19 +844,19 @@ and the application has open handles for this device. What we do is to unblock them all simialr to an explicit unblock call. */ - log_debug ("GPG_IOControl (ctx=0x%p): code: NOTIFY\n", (void*)opnctx); + log_debug ("GPG_IOControl (ctx=%i): code: NOTIFY\n", opnctx_arg); if (unblock_call (opnctx)) result = TRUE; break; default: - log_debug ("GPG_IOControl (ctx=0x%p): code: (unknown)\n", (void*)opnctx); + log_debug ("GPG_IOControl (ctx=%i): code: (unknown)\n", opnctx_arg); SetLastError (ERROR_INVALID_PARAMETER); break; } - log_debug ("GPG_IOControl (ctx=0x%p): success: result=%d\n", (void*)opnctx, + log_debug ("GPG_IOControl (ctx=%i): success: result=%d\n", opnctx_arg, result); leave: From cvs at cvs.gnupg.org Tue Aug 3 10:52:13 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 03 Aug 2010 10:52:13 +0200 Subject: [svn] assuan - r380 - trunk/src Message-ID: Author: marcus Date: 2010-08-03 10:52:13 +0200 (Tue, 03 Aug 2010) New Revision: 380 Modified: trunk/src/ChangeLog trunk/src/gpgcedev.c Log: 2010-08-03 Marcus Brinkmann * gpgcedev.c (GPGCEDEV_IOCTL_ASSIGN_RVID): New call ASSIGN_RVID. (PIPE_FLAG_HALT_MONITOR): New flag. (struct pipeimpl_s): New members monitor_proc, monitor_access. (pipeimpl_new): Initialize them. (assert_pipeimpl): New function. (access_opnctx, make_pipe): Use it. (make_pipe): If there is a monitor, halt it. (monitor, assign_rvid): New functions. (GPG_IOControl): Handle GPGCEDEV_IOCTL_ASSIGN_RVID. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-08-02 23:35:11 UTC (rev 379) +++ trunk/src/ChangeLog 2010-08-03 08:52:13 UTC (rev 380) @@ -1,5 +1,15 @@ 2010-08-03 Marcus Brinkmann + * gpgcedev.c (GPGCEDEV_IOCTL_ASSIGN_RVID): New call ASSIGN_RVID. + (PIPE_FLAG_HALT_MONITOR): New flag. + (struct pipeimpl_s): New members monitor_proc, monitor_access. + (pipeimpl_new): Initialize them. + (assert_pipeimpl): New function. + (access_opnctx, make_pipe): Use it. + (make_pipe): If there is a monitor, halt it. + (monitor, assign_rvid): New functions. + (GPG_IOControl): Handle GPGCEDEV_IOCTL_ASSIGN_RVID. + * gpgcedev.c: Use index (between 1 and table size) into opnctx_table as public context identifiers, instead using pointers into the table directly (which are not stable under table resize). Modified: trunk/src/gpgcedev.c =================================================================== --- trunk/src/gpgcedev.c 2010-08-02 23:35:11 UTC (rev 379) +++ trunk/src/gpgcedev.c 2010-08-03 08:52:13 UTC (rev 380) @@ -65,6 +65,15 @@ #define GPGCEDEV_IOCTL_UNBLOCK \ CTL_CODE (FILE_DEVICE_STREAMS, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS) +/* The IOCTL to assign a rendezvous id to a process. + + The required inbuf parameters are the rendezvous ID to assign and + the process ID of the process receiving the RVID. The handle on + which this is called is not really used at all! */ +#define GPGCEDEV_IOCTL_ASSIGN_RVID \ + CTL_CODE (FILE_DEVICE_STREAMS, 2051, METHOD_BUFFERED, FILE_ANY_ACCESS) + + struct pipeimpl_s { CRITICAL_SECTION critsect; /* Lock for all members. */ @@ -79,10 +88,15 @@ #define PIPE_FLAG_NO_WRITER 2 #define PIPE_FLAG_UNBLOCK_READER 4 #define PIPE_FLAG_UNBLOCK_WRITER 8 +#define PIPE_FLAG_HALT_MONITOR 16 int flags; HANDLE space_available; /* Set if space is available. */ HANDLE data_available; /* Set if data is available. */ + + /* For the monitor thread started by ASSIGN_RVID. */ + HANDLE monitor_proc; + int monitor_access; }; typedef struct pipeimpl_s *pipeimpl_t; @@ -175,7 +189,8 @@ pimpl->flags = 0; pimpl->space_available = CreateEvent (NULL, FALSE, FALSE, NULL); pimpl->data_available = CreateEvent (NULL, FALSE, FALSE, NULL); - + pimpl->monitor_proc = INVALID_HANDLE_VALUE; + pimpl->monitor_access = 0; return pimpl; } @@ -285,6 +300,27 @@ } +static pipeimpl_t +assert_pipeimpl (opnctx_t ctx) +{ + DWORD ctx_arg = OPNCTX_TO_IDX (ctx); + + if (! ctx->pipeimpl) + { + ctx->pipeimpl = pipeimpl_new (); + if (! ctx->pipeimpl) + { + log_debug (" assert_pipeimpl (ctx=%i): error: can't create pipe\n", + ctx_arg); + return NULL; + } + log_debug (" assert_pipeimpl (ctx=%i): created pipe 0x%p\n", + ctx_arg, ctx->pipeimpl); + } + return ctx->pipeimpl; +} + + /* Verify access CODE for context CTX_ARG, returning a reference to the locked pipe implementation. opnctx_table_cs must be unlocked on entry and is unlocked on exit. */ @@ -310,20 +346,12 @@ return NULL; } - if (! ctx->pipeimpl) + pimpl = assert_pipeimpl (ctx); + if (! pimpl) { - ctx->pipeimpl = pipeimpl_new (); - if (! ctx->pipeimpl) - { - log_debug (" access_opnctx (ctx=%i): error: can't create pipe\n", - ctx_arg); - LeaveCriticalSection (&opnctx_table_cs); - return NULL; - } - log_debug (" access_opnctx (ctx=%i): created pipe 0x%p\n", - ctx_arg, ctx->pipeimpl); + LeaveCriticalSection (&opnctx_table_cs); + return NULL; } - pimpl = ctx->pipeimpl; EnterCriticalSection (&pimpl->critsect); pimpl->refcnt++; @@ -403,7 +431,7 @@ log_debug ("GPG_Open (devctx=%p)\n", (void*)devctx); if (devctx != DEVCTX_VALUE) { - log_debug ("GPG_Open (devctx=%p): error: devctx mismatch (expected 0x%p)\n", + log_debug ("GPG_Open (devctx=%p): error: wrong devctx (expected 0x%p)\n", (void*) devctx); SetLastError (ERROR_INVALID_PARAMETER); return 0; /* Error. */ @@ -517,7 +545,8 @@ /* Check for request to unblock once. */ if (pimpl->flags & PIPE_FLAG_UNBLOCK_READER) { - log_debug ("GPG_Read (ctx=%i): success: EBUSY (due to unblock request)\n", opnctx_arg); + log_debug ("GPG_Read (ctx=%i): success: EBUSY (due to unblock)\n", + opnctx_arg); pimpl->flags &= ~PIPE_FLAG_UNBLOCK_READER; SetLastError (ERROR_BUSY); result = -1; @@ -548,8 +577,8 @@ Even if COUNT was passed as NULL and no space is available, signaling must be done. */ if (!SetEvent (pimpl->space_available)) - log_debug ("GPG_Read (ctx=%i): warning: SetEvent(space_available) failed: rc=%d\n", - opnctx_arg, (int)GetLastError ()); + log_debug ("GPG_Read (ctx=%i): warning: SetEvent(space_available) " + "failed: rc=%d\n", opnctx_arg, (int)GetLastError ()); log_debug ("GPG_Read (ctx=%i): success: result=%d\n", opnctx_arg, result); @@ -599,7 +628,8 @@ /* Check for request to unblock once. */ if (pimpl->flags & PIPE_FLAG_UNBLOCK_WRITER) { - log_debug ("GPG_Write (ctx=%i): success: EBUSY (due to unblock request)\n", opnctx_arg); + log_debug ("GPG_Write (ctx=%i): success: EBUSY (due to unblock)\n", + opnctx_arg); pimpl->flags &= ~PIPE_FLAG_UNBLOCK_WRITER; SetLastError (ERROR_BUSY); result = -1; @@ -614,7 +644,8 @@ LeaveCriticalSection (&pimpl->critsect); log_debug ("GPG_Write (ctx=%i): waiting: space_available\n", opnctx_arg); WaitForSingleObject (space_available, INFINITE); - log_debug ("GPG_Write (ctx=%i): resuming: space_available\n", opnctx_arg); + log_debug ("GPG_Write (ctx=%i): resuming: space_available\n", + opnctx_arg); EnterCriticalSection (&pimpl->critsect); goto retry; } @@ -631,8 +662,8 @@ result = nwritten; if (!SetEvent (pimpl->data_available)) - log_debug ("GPG_Write (ctx=%i): warning: SetEvent(data_available) failed: rc=%d\n", - opnctx_arg, (int)GetLastError ()); + log_debug ("GPG_Write (ctx=%i): warning: SetEvent(data_available) " + "failed: rc=%d\n", opnctx_arg, (int)GetLastError ()); log_debug ("GPG_Write (ctx=%i): success: result=%d\n", opnctx_arg, result); @@ -659,6 +690,7 @@ DWORD ctx_arg = OPNCTX_TO_IDX (ctx); opnctx_t peerctx = NULL; int idx; + pipeimpl_t pimpl; log_debug (" make_pipe (ctx=%i, rvid=%08lx)\n", ctx_arg, rvid); @@ -684,7 +716,8 @@ if (peerctx == ctx) { - log_debug (" make_pipe (ctx=%i): error: target and source identical\n", ctx_arg); + log_debug (" make_pipe (ctx=%i): error: target and source identical\n", + ctx_arg); SetLastError (ERROR_INVALID_TARGET_HANDLE); return FALSE; } @@ -695,7 +728,8 @@ if (!(peerctx->access_code & GENERIC_WRITE)) { SetLastError (ERROR_INVALID_ACCESS); - log_debug (" make_pipe (ctx=%i): error: peer is not writer\n", ctx_arg); + log_debug (" make_pipe (ctx=%i): error: peer is not writer\n", + ctx_arg); return FALSE; } } @@ -705,7 +739,8 @@ if (!(peerctx->access_code & GENERIC_READ)) { SetLastError (ERROR_INVALID_ACCESS); - log_debug (" make_pipe (ctx=%i): error: peer is not reader\n", ctx_arg); + log_debug (" make_pipe (ctx=%i): error: peer is not reader\n", + ctx_arg); return FALSE; } } @@ -718,25 +753,31 @@ /* Make sure the peer has a pipe implementation to be shared. If not yet, create one. */ - if (! peerctx->pipeimpl) + pimpl = assert_pipeimpl (peerctx); + if (! pimpl) + return FALSE; + + EnterCriticalSection (&pimpl->critsect); + pimpl->refcnt++; + if (pimpl->monitor_proc != INVALID_HANDLE_VALUE) { - peerctx->pipeimpl = pipeimpl_new (); - if (! peerctx->pipeimpl) - { - log_debug (" make_pipe (ctx=%i): error: can't create pipe\n", - ctx_arg); - return FALSE; - } - log_debug (" make_pipe (ctx=%i): created pipe 0x%p\n", - ctx_arg, peerctx->pipeimpl); + /* If there is a monitor to the pipe, then it's now about time + to ask it to go away. */ + log_debug (" make_pipe (ctx=%i): waking up monitor for pipe 0x%p\n", + ctx_arg, pimpl); + pimpl->flags |= PIPE_FLAG_HALT_MONITOR; + if (pimpl->monitor_access & GENERIC_READ) + SetEvent (pimpl->data_available); + else + SetEvent (pimpl->space_available); } - EnterCriticalSection (&peerctx->pipeimpl->critsect); - peerctx->pipeimpl->refcnt++; - ctx->pipeimpl = peerctx->pipeimpl; - LeaveCriticalSection (&peerctx->pipeimpl->critsect); - log_debug (" make_pipe (ctx=%i): success: combined with peer ctx=%i (pipe 0x%p)\n", - ctx_arg, OPNCTX_TO_IDX (peerctx), peerctx->pipeimpl); + LeaveCriticalSection (&pimpl->critsect); + ctx->pipeimpl = pimpl; + + log_debug (" make_pipe (ctx=%i): success: combined with peer ctx=%i " + "(pipe 0x%p)\n", ctx_arg, OPNCTX_TO_IDX (peerctx), pimpl); + return TRUE; } @@ -765,6 +806,158 @@ return TRUE; } + +static DWORD CALLBACK +monitor (void *arg) +{ + pipeimpl_t pimpl = (pipeimpl_t) arg; + HANDLE handles[2]; + + log_debug ("starting monitor (pimpl=0x%p)\n", pimpl); + + EnterCriticalSection (&pimpl->critsect); + /* Putting proc first in the array is convenient, as this is a hard + break-out condition (and thus takes precedence in WFMO). The + reader/writer event is a soft condition, which also requires a + flag to be set. */ + handles[0] = pimpl->monitor_proc; + if (pimpl->monitor_access & GENERIC_READ) + handles[1] = pimpl->data_available; + else + handles[1] = pimpl->space_available; + + retry: + /* First check if the peer has not gone away. If it has, we are done. */ + if (pimpl->flags & PIPE_FLAG_HALT_MONITOR) + { + log_debug ("monitor (pimpl=0x%p): done: monitored process taking over\n", + pimpl); + } + else + { + DWORD res; + + LeaveCriticalSection (&pimpl->critsect); + log_debug ("monitor (pimpl=0x%p): waiting\n", pimpl); + res = WaitForMultipleObjects (2, handles, FALSE, INFINITE); + log_debug ("monitor (pimpl=0x%p): resuming\n", pimpl); + EnterCriticalSection (&pimpl->critsect); + + if (res == WAIT_FAILED) + { + log_debug ("monitor (pimpl=0x%p): WFMO failed: %i\n", + pimpl, GetLastError ()); + } + else if (res == WAIT_OBJECT_0) + { + log_debug ("monitor (pimpl=0x%p): done: monitored process died\n", + pimpl); + } + else if (res == WAIT_OBJECT_0 + 1) + goto retry; + else + { + log_debug ("monitor (pimpl=0x%p): unexpected result of WFMO: %i\n", + pimpl, res); + } + } + + log_debug ("ending monitor (pimpl=0x%p)\n", pimpl); + CloseHandle (pimpl->monitor_proc); + pimpl->monitor_proc = INVALID_HANDLE_VALUE; + pimpl->monitor_access = 0; + pimpl->flags &= ~PIPE_FLAG_HALT_MONITOR; + pipeimpl_unref (pimpl); + + return 0; +} + + +/* opnctx_table_s is locked on entering and on exit. */ +static BOOL +assign_rvid (opnctx_t ctx, DWORD rvid, DWORD pid) +{ + DWORD ctx_arg = OPNCTX_TO_IDX (ctx); + int idx; + opnctx_t peerctx; + HANDLE monitor_hnd; + HANDLE proc; + pipeimpl_t pimpl; + + log_debug (" assign_rvid (ctx=%i, rvid=%08lx, pid=%08lx)\n", + ctx_arg, rvid, pid); + + for (idx = 0; idx < opnctx_table_size; idx++) + if (opnctx_table[idx].inuse && opnctx_table[idx].rvid == rvid) + { + peerctx = &opnctx_table[idx]; + break; + } + if (! peerctx) + { + log_debug (" assign_rvid (ctx=%i): error: not found\n", ctx_arg); + SetLastError (ERROR_NOT_FOUND); + return FALSE; + } + + if (peerctx->pipeimpl + && peerctx->pipeimpl->monitor_proc != INVALID_HANDLE_VALUE) + { + log_debug (" assign_rvid (ctx=%i): error: rvid already assigned\n", + ctx_arg); + SetLastError (ERROR_ALREADY_ASSIGNED); + return FALSE; + } + + proc = OpenProcess (0, FALSE, pid); + if (proc == NULL) + { + log_debug (" assign_rvid (ctx=%i): error: process not found\n", + ctx_arg); + return FALSE; + } + + /* Acquire a reference to the pipe. We don't want accesss to be + checked. */ + pimpl = assert_pipeimpl (peerctx); + if (! pimpl) + { + CloseHandle (proc); + return FALSE; + } + + EnterCriticalSection (&pimpl->critsect); + pimpl->refcnt++; + + /* The monitor shadows the peer, so it takes its access. Our access + is the opposite of that of the peer. */ + pimpl->monitor_proc = proc; + if (peerctx->access_code == GENERIC_READ) + pimpl->monitor_access = GENERIC_WRITE; + else + pimpl->monitor_access = GENERIC_READ; + + monitor_hnd = CreateThread (NULL, 0, monitor, pimpl, 0, NULL); + if (monitor_hnd == INVALID_HANDLE_VALUE) + { + pimpl->monitor_access = 0; + pimpl->monitor_proc = INVALID_HANDLE_VALUE; + LeaveCriticalSection (&pimpl->critsect); + + CloseHandle (proc); + log_debug (" assign_rvid (ctx=%i): error: can not create monitor\n", + ctx_arg); + return FALSE; + } + CloseHandle (monitor_hnd); + + /* Consume the pimpl reference. */ + LeaveCriticalSection (&pimpl->critsect); + + return TRUE; +} + + BOOL GPG_IOControl (DWORD opnctx_arg, DWORD code, void *inbuf, DWORD inbuflen, void *outbuf, DWORD outbuflen, DWORD *actualoutlen) @@ -772,6 +965,7 @@ opnctx_t opnctx; BOOL result = FALSE; LONG rvid; + LONG pid; log_debug ("GPG_IOControl (ctx=%i, %08x)\n", opnctx_arg, code); @@ -818,7 +1012,7 @@ goto leave; } memcpy (&rvid, inbuf, sizeof (LONG)); - log_debug ("GPG_IOControl (ctx=%i): requesting to finish pipe for rvid: %08lx\n", + log_debug ("GPG_IOControl (ctx=%i): make pipe for rvid: %08lx\n", opnctx_arg, rvid); if (make_pipe (opnctx, rvid)) result = TRUE; @@ -838,6 +1032,24 @@ result = TRUE; break; + case GPGCEDEV_IOCTL_ASSIGN_RVID: + log_debug ("GPG_IOControl (ctx=%i): code: ASSIGN_RVID\n", opnctx_arg); + if (!inbuf || inbuflen < 2 * sizeof (DWORD) + || outbuf || outbuflen || actualoutlen) + { + log_debug ("GPG_IOControl (ctx=%i): error: invalid parameter\n", + opnctx_arg); + SetLastError (ERROR_INVALID_PARAMETER); + goto leave; + } + memcpy (&rvid, inbuf, sizeof (DWORD)); + memcpy (&pid, ((char *) inbuf) + sizeof (DWORD), sizeof (DWORD)); + log_debug ("GPG_IOControl (ctx=%i): assign rvid %08lx to pid %08lx\n", + opnctx_arg, rvid, pid); + if (assign_rvid (opnctx, rvid, pid)) + result = TRUE; + break; + case IOCTL_PSL_NOTIFY: /* This notification is received if the application's main thread exits and the application has other threads running @@ -879,7 +1091,6 @@ } - /* Entry point called by the DLL loader. */ int WINAPI @@ -909,4 +1120,3 @@ return TRUE; } - From cvs at cvs.gnupg.org Tue Aug 3 11:01:25 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 03 Aug 2010 11:01:25 +0200 Subject: [svn] gpgme - r1483 - trunk/src Message-ID: Author: marcus Date: 2010-08-03 11:01:24 +0200 (Tue, 03 Aug 2010) New Revision: 1483 Modified: trunk/src/ChangeLog trunk/src/w32-io.c Log: 2010-08-03 Marcus Brinkmann * w32-io.c (GPGCEDEV_IOCTL_ASSIGN_RVID): New macro. (_gpgme_io_spawn): Use ASSIGN_RVID. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-06-29 17:13:07 UTC (rev 1482) +++ trunk/src/ChangeLog 2010-08-03 09:01:24 UTC (rev 1483) @@ -1,3 +1,8 @@ +2010-08-03 Marcus Brinkmann + + * w32-io.c (GPGCEDEV_IOCTL_ASSIGN_RVID): New macro. + (_gpgme_io_spawn): Use ASSIGN_RVID. + 2010-06-11 Marcus Brinkmann * w32-io.c (_gpgme_io_spawn): Remove debug printf. Modified: trunk/src/w32-io.c =================================================================== --- trunk/src/w32-io.c 2010-06-29 17:13:07 UTC (rev 1482) +++ trunk/src/w32-io.c 2010-08-03 09:01:24 UTC (rev 1483) @@ -38,6 +38,8 @@ #include #define GPGCEDEV_IOCTL_UNBLOCK \ CTL_CODE (FILE_DEVICE_STREAMS, 2050, METHOD_BUFFERED, FILE_ANY_ACCESS) +#define GPGCEDEV_IOCTL_ASSIGN_RVID \ + CTL_CODE (FILE_DEVICE_STREAMS, 2051, METHOD_BUFFERED, FILE_ANY_ACCESS) #endif #include "util.h" @@ -863,8 +865,9 @@ #ifdef HAVE_W32CE_SYSTEM /* Scenario: We never create a full pipe, but already started - reading. Then we need to unblock the reader in the pipe driver - to make our reader thread notice that we want it to go away. */ + writing more than the pipe buffer. Then we need to unblock the + writer in the pipe driver to make our writer thread notice that + we want it to go away. */ if (!DeviceIoControl (ctx->file_hd, GPGCEDEV_IOCTL_UNBLOCK, NULL, 0, NULL, 0, NULL, NULL)) @@ -1467,6 +1470,7 @@ int fd_out_isnull = 1; int fd_err_isnull = 1; char *cmdline; + HANDLE hd = INVALID_HANDLE_VALUE; TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_spawn", path, "path=%s", path); @@ -1538,12 +1542,39 @@ return TRACE_SYSRES (-1); } + /* Create arbitrary pipe descriptor to send in ASSIGN_RVID + commands. Errors are ignored. We don't need read or write access, + as ASSIGN_RVID works without any permissions, yay! */ + hd = CreateFile (L"GPG1:", 0, 0, + NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hd == INVALID_HANDLE_VALUE) + { + TRACE_LOG1 (DEBUG_SYSIO, "CreateFile failed (ignored): ec=%d", + (int) GetLastError ()); + } + /* Insert the inherited handles. */ for (i = 0; fd_list[i].fd != -1; i++) { /* Return the child name of this handle. */ fd_list[i].peer_name = fd_table[fd_list[i].fd].rvid; + + if (hd != INVALID_HANDLE_VALUE) + { + DWORD data[2]; + data[0] = (DWORD) fd_table[fd_list[i].fd].rvid; + data[1] = pi.dwProcessId; + if (!DeviceIoControl (hd, GPGCEDEV_IOCTL_ASSIGN_RVID, + data, sizeof (data), NULL, 0, NULL, NULL)) + { + TRACE_LOG1 (DEBUG_SYSIO, + "ASSIGN_RVID(%i, %i) failed (ignored): %i", + data[0], data[1], (int) GetLastError ()); + } + } } + if (hd != INVALID_HANDLE_VALUE) + CloseHandle (hd); #else SECURITY_ATTRIBUTES sec_attr; From cvs at cvs.gnupg.org Tue Aug 3 11:16:02 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 03 Aug 2010 11:16:02 +0200 Subject: [svn] gpgme - r1484 - trunk/src Message-ID: Author: marcus Date: 2010-08-03 11:16:01 +0200 (Tue, 03 Aug 2010) New Revision: 1484 Modified: trunk/src/ChangeLog trunk/src/gpgme-tool.c Log: 2010-08-03 Marcus Brinkmann * gpgme-tool.c (result_encrypt_to_xml, result_sign_to_xml) (result_verify_to_xml, result_import_to_xml) (result_genkey_to_xml): Check vigorously for null pointers. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-08-03 09:01:24 UTC (rev 1483) +++ trunk/src/ChangeLog 2010-08-03 09:16:01 UTC (rev 1484) @@ -1,5 +1,9 @@ 2010-08-03 Marcus Brinkmann + * gpgme-tool.c (result_encrypt_to_xml, result_sign_to_xml) + (result_verify_to_xml, result_import_to_xml) + (result_genkey_to_xml): Check vigorously for null pointers. + * w32-io.c (GPGCEDEV_IOCTL_ASSIGN_RVID): New macro. (_gpgme_io_spawn): Use ASSIGN_RVID. Modified: trunk/src/gpgme-tool.c =================================================================== --- trunk/src/gpgme-tool.c 2010-08-03 09:01:24 UTC (rev 1483) +++ trunk/src/gpgme-tool.c 2010-08-03 09:16:01 UTC (rev 1484) @@ -742,8 +742,8 @@ gpg_error_t result_add_timestamp (struct result_xml_state *state, char *name, unsigned int timestamp) -{ - char code[20]; +{ + code[20]; snprintf (code, sizeof (code) - 1, "%ui", timestamp); result_xml_tag_start (state, name, "unix", code, NULL); @@ -828,7 +828,8 @@ while (inv_recp) { result_xml_tag_start (&state, "invalid-key", NULL); - result_add_fpr (&state, "fpr", inv_recp->fpr); + if (inv_recp->fpr) + result_add_fpr (&state, "fpr", inv_recp->fpr); result_add_error (&state, "reason", inv_recp->reason); result_xml_tag_end (&state); inv_recp = inv_recp->next; @@ -917,7 +918,8 @@ while (inv_key) { result_xml_tag_start (&state, "invalid-key", NULL); - result_add_fpr (&state, "fpr", inv_key->fpr); + if (inv_key->fpr) + result_add_fpr (&state, "fpr", inv_key->fpr); result_add_error (&state, "reason", inv_key->reason); result_xml_tag_end (&state); inv_key = inv_key->next; @@ -985,7 +987,8 @@ /* FIXME: Could be done better. */ result_add_value (&state, "summary", sig->summary); - result_add_fpr (&state, "fpr", sig->fpr); + if (sig->fpr) + result_add_fpr (&state, "fpr", sig->fpr); result_add_error (&state, "status", sig->status); /* FIXME: notations */ result_add_timestamp (&state, "timestamp", sig->timestamp); @@ -1050,7 +1053,8 @@ { result_xml_tag_start (&state, "import-status", NULL); - result_add_fpr (&state, "fpr", stat->fpr); + if (stat->fpr) + result_add_fpr (&state, "fpr", stat->fpr); result_add_error (&state, "result", stat->result); /* FIXME: Could be done better. */ result_add_value (&state, "status", stat->status); @@ -1082,7 +1086,8 @@ result_add_value (&state, "primary", res->primary); result_add_value (&state, "sub", res->sub); - result_add_fpr (&state, "fpr", res->fpr); + if (res->fpr) + result_add_fpr (&state, "fpr", res->fpr); result_xml_tag_end (&state); From cvs at cvs.gnupg.org Tue Aug 3 16:06:42 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 03 Aug 2010 16:06:42 +0200 Subject: [svn] GnuPG - r5380 - trunk/dirmngr Message-ID: Author: wk Date: 2010-08-03 16:06:42 +0200 (Tue, 03 Aug 2010) New Revision: 5380 Modified: trunk/dirmngr/ChangeLog trunk/dirmngr/dirmngr_ldap.c Log: Fix regressions on POSIX -This line, and those below, will be ignored-- M dirmngr/dirmngr_ldap.c M dirmngr/ChangeLog Modified: trunk/dirmngr/ChangeLog =================================================================== --- trunk/dirmngr/ChangeLog 2010-08-02 18:54:53 UTC (rev 5379) +++ trunk/dirmngr/ChangeLog 2010-08-03 14:06:42 UTC (rev 5380) @@ -1,3 +1,8 @@ +2010-08-03 Werner Koch + + * dirmngr_ldap.c (pth_enter, pth_leave) [USE_LDAPWRAPPER]: Turn + into functions for use in a 'for' control stmt. + 2010-07-26 Werner Koch * dirmngr_ldap.c (print_ldap_entries): Remove special fwrite case Modified: trunk/dirmngr/dirmngr_ldap.c =================================================================== --- trunk/dirmngr/dirmngr_ldap.c 2010-08-02 18:54:53 UTC (rev 5379) +++ trunk/dirmngr/dirmngr_ldap.c 2010-08-03 14:06:42 UTC (rev 5380) @@ -63,8 +63,8 @@ ldap wrapper process we need to include the prototype for our module's main function. */ #ifdef USE_LDAPWRAPPER -# define pth_enter() do { } while (0) -# define pth_leave() do { } while (0) +static void pth_enter (void) { } +static void pth_leave (void) { } #else # include "./ldap-wrapper.h" #endif @@ -153,7 +153,7 @@ /* Function called by argparse.c to display information. */ -#ifndef USE_LDAPWRAPPER +#ifdef USE_LDAPWRAPPER static const char * my_strusage (int level) { From cvs at cvs.gnupg.org Wed Aug 4 09:40:33 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 04 Aug 2010 09:40:33 +0200 Subject: [svn] gpgme - r1485 - trunk/src Message-ID: Author: marcus Date: 2010-08-04 09:40:33 +0200 (Wed, 04 Aug 2010) New Revision: 1485 Modified: trunk/src/gpgme-tool.c Log: Too embarrassing for a changelog entry. Modified: trunk/src/gpgme-tool.c =================================================================== --- trunk/src/gpgme-tool.c 2010-08-03 09:16:01 UTC (rev 1484) +++ trunk/src/gpgme-tool.c 2010-08-04 07:40:33 UTC (rev 1485) @@ -743,7 +743,7 @@ result_add_timestamp (struct result_xml_state *state, char *name, unsigned int timestamp) { - code[20]; + char code[20]; snprintf (code, sizeof (code) - 1, "%ui", timestamp); result_xml_tag_start (state, name, "unix", code, NULL); From cvs at cvs.gnupg.org Wed Aug 4 09:47:06 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 04 Aug 2010 09:47:06 +0200 Subject: [svn] gpgme - r1486 - trunk/src Message-ID: Author: marcus Date: 2010-08-04 09:47:05 +0200 (Wed, 04 Aug 2010) New Revision: 1486 Modified: trunk/src/w32-io.c Log: Are you ready already? Modified: trunk/src/w32-io.c =================================================================== --- trunk/src/w32-io.c 2010-08-04 07:40:33 UTC (rev 1485) +++ trunk/src/w32-io.c 2010-08-04 07:47:05 UTC (rev 1486) @@ -1549,7 +1549,7 @@ NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hd == INVALID_HANDLE_VALUE) { - TRACE_LOG1 (DEBUG_SYSIO, "CreateFile failed (ignored): ec=%d", + TRACE_LOG1 ("CreateFile failed (ignored): ec=%d", (int) GetLastError ()); } @@ -1567,8 +1567,7 @@ if (!DeviceIoControl (hd, GPGCEDEV_IOCTL_ASSIGN_RVID, data, sizeof (data), NULL, 0, NULL, NULL)) { - TRACE_LOG1 (DEBUG_SYSIO, - "ASSIGN_RVID(%i, %i) failed (ignored): %i", + TRACE_LOG3 ("ASSIGN_RVID(%i, %i) failed (ignored): %i", data[0], data[1], (int) GetLastError ()); } } From cvs at cvs.gnupg.org Wed Aug 4 10:31:38 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 04 Aug 2010 10:31:38 +0200 Subject: [svn] ksba - r323 - trunk/tests Message-ID: Author: wk Date: 2010-08-04 10:31:38 +0200 (Wed, 04 Aug 2010) New Revision: 323 Modified: trunk/tests/ChangeLog trunk/tests/t-cms-parser.c trunk/tests/t-common.h Log: Minor change Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2010-08-02 13:36:25 UTC (rev 322) +++ trunk/tests/ChangeLog 2010-08-04 08:31:38 UTC (rev 323) @@ -1,3 +1,7 @@ +2010-08-04 Werner Koch + + * t-cms-parser.c (one_file): Use print_sexp_hex for the s/n. + 2010-07-15 Werner Koch * t-cms-parser.c (dummy_writer_cb): New. Modified: trunk/tests/t-cms-parser.c =================================================================== --- trunk/tests/t-cms-parser.c 2010-08-02 13:36:25 UTC (rev 322) +++ trunk/tests/t-cms-parser.c 2010-08-04 08:31:38 UTC (rev 323) @@ -151,7 +151,7 @@ ksba_free (dn); putchar ('\n'); printf ("recipient %d - serial: ", idx); - print_sexp (p); + print_sexp_hex (p); ksba_free (p); putchar ('\n'); @@ -177,7 +177,7 @@ ksba_free (dn); putchar ('\n'); printf ("signer %d - serial: ", idx); - print_sexp (p); + print_sexp_hex (p); ksba_free (p); putchar ('\n'); Modified: trunk/tests/t-common.h =================================================================== --- trunk/tests/t-common.h 2010-08-02 13:36:25 UTC (rev 322) +++ trunk/tests/t-common.h 2010-08-04 08:31:38 UTC (rev 323) @@ -155,7 +155,7 @@ } } -/* Variant of print_sexp which force printing the values in hex. */ +/* Variant of print_sexp which forces printing the values in hex. */ void print_sexp_hex (ksba_const_sexp_t p) { From cvs at cvs.gnupg.org Thu Aug 5 10:51:12 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 05 Aug 2010 10:51:12 +0200 Subject: [svn] GnuPG - r5381 - trunk/dirmngr Message-ID: Author: wk Date: 2010-08-05 10:51:11 +0200 (Thu, 05 Aug 2010) New Revision: 5381 Modified: trunk/dirmngr/crlfetch.c Log: Typo fix Modified: trunk/dirmngr/crlfetch.c =================================================================== --- trunk/dirmngr/crlfetch.c 2010-08-03 14:06:42 UTC (rev 5380) +++ trunk/dirmngr/crlfetch.c 2010-08-05 08:51:11 UTC (rev 5381) @@ -264,7 +264,7 @@ } break; - case 99999: /* Made up status code foer error reporting. */ + case 99999: /* Made up status code for error reporting. */ log_error (_("error retrieving `%s': %s\n"), url, gpg_strerror (err)); break; From cvs at cvs.gnupg.org Thu Aug 5 20:47:26 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 05 Aug 2010 20:47:26 +0200 Subject: [svn] GnuPG - r5382 - trunk/common Message-ID: Author: wk Date: 2010-08-05 20:47:25 +0200 (Thu, 05 Aug 2010) New Revision: 5382 Modified: trunk/common/ChangeLog trunk/common/estream.h trunk/common/http.c trunk/common/http.h Log: Simplified http.c. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-08-05 08:51:11 UTC (rev 5381) +++ trunk/common/ChangeLog 2010-08-05 18:47:25 UTC (rev 5382) @@ -1,3 +1,17 @@ +2010-08-05 Werner Koch + + * estream.h (es_asprintf, es_vasprintf): Add lost prototyps. + + * http.c: Require estream and make HTTP_USE_ESTREAM obsolete. It + make the code unreadable and we require estream anyway for GnuPG. + (http_wait_response): Get use of cookies right. + (send_request): s/xtryasprintf/es_asprintf/ to allow standalone + use of the code. + (insert_escapes, connect_server): s/sprintf/snprintf/. + (parse_response): s/my_read_line/es_read_line/. + (my_read_line): Remove. + (write_server): Use pth_write. + 2010-07-26 Werner Koch * estream.c (es_func_fp_write) [W32]: Write smaller chunks. Modified: trunk/common/estream.h =================================================================== --- trunk/common/estream.h 2010-08-05 08:51:11 UTC (rev 5381) +++ trunk/common/estream.h 2010-08-05 18:47:25 UTC (rev 5382) @@ -352,6 +352,11 @@ const char *ES__RESTRICT format, va_list ap) _ESTREAM_GCC_A_PRINTF(2,0); +char *es_asprintf (const char *ES__RESTRICT format, ...) + _ESTREAM_GCC_A_PRINTF(1,2); +char *es_vasprintf (const char *ES__RESTRICT format, va_list ap) + _ESTREAM_GCC_A_PRINTF(1,0); + int es_setvbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf, int mode, size_t size); void es_setbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf); Modified: trunk/common/http.c =================================================================== --- trunk/common/http.c 2010-08-05 08:51:11 UTC (rev 5381) +++ trunk/common/http.c 2010-08-05 18:47:25 UTC (rev 5382) @@ -21,11 +21,13 @@ /* Simple HTTP client implementation. We try to keep the code as self-contained as possible. There are some contraints however: + - estream is required. We now require estream because it provides a + very useful and portable asprintf implementation and the fopencookie + function. - stpcpy is required - fixme: list other requirements. - - 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 @@ -129,18 +131,13 @@ # define counter_strtoul(a) strtoul ((a), NULL, 10) #endif -/* Define a prefix to map stream functions to the estream library. */ -#ifdef HTTP_USE_ESTREAM -#define P_ES(a) es_ ## a -#else -#define P_ES(a) a +#if defined(HTTP_USE_ESTREAM) && defined (__GNUC__) +# warning HTTP_USE_ESTREAM is an obsolete macro #endif + #ifndef HTTP_USE_GNUTLS typedef void * gnutls_session_t; #endif -#if defined(HTTP_USE_GNUTLS) && !defined(HTTP_USE_ESTREAM) -#error Use of GNUTLS also requires support for Estream -#endif static gpg_error_t do_parse_uri (parsed_uri_t uri, int only_local_part); static int remove_escapes (char *string); @@ -156,7 +153,6 @@ unsigned int flags, const char *srvtag); static gpg_error_t write_server (int sock, const char *data, size_t length); -#ifdef HTTP_USE_ESTREAM static ssize_t cookie_read (void *cookie, void *buffer, size_t size); static ssize_t cookie_write (void *cookie, const void *buffer, size_t size); static int cookie_close (void *cookie); @@ -187,8 +183,6 @@ }; typedef struct cookie_s *cookie_t; -#endif /*HTTP_USE_ESTREAM*/ - #ifdef HTTP_USE_GNUTLS static gpg_error_t (*tls_callback) (http_t, gnutls_session_t, int); #endif /*HTTP_USE_GNUTLS*/ @@ -211,15 +205,10 @@ int sock; unsigned int in_data:1; unsigned int is_http_0_9:1; -#ifdef HTTP_USE_ESTREAM estream_t fp_read; estream_t fp_write; void *write_cookie; void *read_cookie; -#else /*!HTTP_USE_ESTREAM*/ - FILE *fp_read; - FILE *fp_write; -#endif /*!HTTP_USE_ESTREAM*/ void *tls_context; parsed_uri_t uri; http_req_t req_type; @@ -375,9 +364,9 @@ if (!hd->fp_read && !hd->fp_write && hd->sock != -1) sock_close (hd->sock); if (hd->fp_read) - P_ES(fclose) (hd->fp_read); + es_fclose (hd->fp_read); if (hd->fp_write) - P_ES(fclose) (hd->fp_write); + es_fclose (hd->fp_write); http_release_parsed_uri (hd->uri); xfree (hd); } @@ -392,17 +381,12 @@ { if (!hd->in_data) { -#ifdef HTTP_USE_ESTREAM es_fputs ("\r\n", hd->fp_write); es_fflush (hd->fp_write); -#else - fflush (hd->fp_write); - write_server (hd->sock, "\r\n", 2); -#endif hd->in_data = 1; } else - P_ES(fflush) (hd->fp_write); + es_fflush (hd->fp_write); } @@ -410,42 +394,21 @@ http_wait_response (http_t hd) { gpg_error_t err; + cookie_t cookie; /* Make sure that we are in the data. */ http_start_data (hd); - /* We dup the socket, to cope with the fact that fclose closes the - underlying socket. In TLS mode we don't do that because we can't - close the socket gnutls is working on; instead we make sure that - the fclose won't close the socket in this case. */ -#ifdef HTTP_USE_ESTREAM - if (hd->write_cookie) - { - /* The write cookie is only set in the TLS case. */ - cookie_t cookie = hd->write_cookie; - cookie->keep_socket = 1; - } - else -#endif /*HTTP_USE_ESTREAM*/ - { -#ifdef HAVE_W32_SYSTEM - HANDLE handle = (HANDLE)hd->sock; - if (!DuplicateHandle (GetCurrentProcess(), handle, - GetCurrentProcess(), &handle, 0, - TRUE, DUPLICATE_SAME_ACCESS )) - return gpg_error_from_syserror (); - hd->sock = (int)handle; -#else - hd->sock = dup (hd->sock); -#endif - if (hd->sock == -1) - return gpg_error_from_syserror (); - } - P_ES(fclose) (hd->fp_write); + /* Close the write stream but keep the socket open. */ + cookie = hd->write_cookie; + if (!cookie) + return gpg_error (GPG_ERR_INTERNAL); + + cookie->keep_socket = 1; + es_fclose (hd->fp_write); hd->fp_write = NULL; -#ifdef HTTP_USE_ESTREAM + /* The close has released the cookie and thus we better set it to NULL. */ hd->write_cookie = NULL; -#endif /* Shutdown one end of the socket is desired. As per HTTP/1.0 this is not required but some very old servers (e.g. the original pksd @@ -454,30 +417,23 @@ shutdown (hd->sock, 1); hd->in_data = 0; -#ifdef HTTP_USE_ESTREAM - { - cookie_t cookie; + /* Create a new cookie and a stream for reading. */ + cookie = xtrycalloc (1, sizeof *cookie); + if (!cookie) + return gpg_error_from_syserror (); + cookie->fd = hd->sock; + if (hd->uri->use_tls) + cookie->tls_session = hd->tls_context; - cookie = xtrycalloc (1, sizeof *cookie); - if (!cookie) + hd->read_cookie = cookie; + hd->fp_read = es_fopencookie (cookie, "r", cookie_functions); + if (!hd->fp_read) + { + xfree (cookie); + hd->read_cookie = NULL; return gpg_error_from_syserror (); - cookie->fd = hd->sock; - if (hd->uri->use_tls) - cookie->tls_session = hd->tls_context; + } - hd->fp_read = es_fopencookie (cookie, "r", cookie_functions); - if (!hd->fp_read) - { - xfree (cookie); - return gpg_error_from_syserror (); - } - } -#else /*!HTTP_USE_ESTREAM*/ - hd->fp_read = fdopen (hd->sock, "r"); - if (!hd->fp_read) - return gpg_error_from_syserror (); -#endif /*!HTTP_USE_ESTREAM*/ - err = parse_response (hd); return err; } @@ -515,9 +471,9 @@ if (!hd->fp_read && !hd->fp_write && hd->sock != -1) sock_close (hd->sock); if (hd->fp_read && !keep_read_stream) - P_ES(fclose) (hd->fp_read); + es_fclose (hd->fp_read); if (hd->fp_write) - P_ES(fclose) (hd->fp_write); + es_fclose (hd->fp_write); http_release_parsed_uri (hd->uri); while (hd->headers) { @@ -531,29 +487,18 @@ } -#ifdef HTTP_USE_ESTREAM estream_t http_get_read_ptr (http_t hd) { return hd?hd->fp_read:NULL; } + estream_t http_get_write_ptr (http_t hd) { return hd?hd->fp_write:NULL; } -#else /*!HTTP_USE_ESTREAM*/ -FILE * -http_get_read_ptr (http_t hd) -{ - return hd?hd->fp_read:NULL; -} -FILE * -http_get_write_ptr (http_t hd) -{ - return hd?hd->fp_write:NULL; -} -#endif /*!HTTP_USE_ESTREAM*/ + unsigned int http_get_status_code (http_t hd) { @@ -794,7 +739,7 @@ { if (buffer) { - sprintf (buffer, "%%%02X", *s); + snprintf (buffer, 4, "%%%02X", *s); buffer += 3; } n += 3; @@ -1017,7 +962,7 @@ if (http_proxy && *http_proxy) { - request = xtryasprintf + request = es_asprintf ("%s http://%s:%hu%s%s HTTP/1.0\r\n%s%s", hd->req_type == HTTP_REQ_GET ? "GET" : hd->req_type == HTTP_REQ_HEAD ? "HEAD" : @@ -1035,7 +980,7 @@ else snprintf (portstr, sizeof portstr, ":%u", port); - request = xtryasprintf + request = es_asprintf ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s", hd->req_type == HTTP_REQ_GET ? "GET" : hd->req_type == HTTP_REQ_HEAD ? "HEAD" : @@ -1053,7 +998,6 @@ } -#ifdef HTTP_USE_ESTREAM /* First setup estream so that we can write even the first line using estream. This is also required for the sake of gnutls. */ { @@ -1066,16 +1010,15 @@ goto leave; } cookie->fd = hd->sock; + hd->write_cookie = cookie; if (hd->uri->use_tls) - { - cookie->tls_session = tls_session; - hd->write_cookie = cookie; - } + cookie->tls_session = tls_session; hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); if (!hd->fp_write) { xfree (cookie); + hd->write_cookie = NULL; err = gpg_error_from_syserror (); } else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) @@ -1083,45 +1026,22 @@ else err = 0; - if(err==0) - for(;headers;headers=headers->next) - { - if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write)) - || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write))) - { - err = gpg_error_from_syserror (); - break; - } - } - } - - leave: - -#else /*!HTTP_USE_ESTREAM*/ - /* We send out the start of the request through our own send - function and only then assign a stdio stream. This allows for - better error reporting that through standard stdio means. */ - err = write_server (hd->sock, request, strlen (request)); if (!err) - for (;headers;headers=headers->next) - { - err = write_server (hd->sock, headers->d, strlen(headers->d)); - if (err) - break; - err = write_server (hd->sock, "\r\n", 2); - if (err) - break; - } - if (!err) { - hd->fp_write = fdopen (hd->sock, "w"); - if (!hd->fp_write) - err = gpg_error_from_syserror (); + for (;headers; headers=headers->next) + { + if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write)) + || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write))) + { + err = gpg_error_from_syserror (); + break; + } + } } - -#endif /*!HTTP_USE_ESTREAM*/ - - xfree (request); + } + + leave: + es_free (request); xfree (authstr); xfree (proxy_authstr); @@ -1181,97 +1101,6 @@ } - -/* - Same as fgets() but if the buffer is too short a larger one will be - allocated up to some limit *MAX_LENGTH. A line is considered a - byte stream ending in a LF. Returns the length of the line. EOF is - indicated by a line of length zero. The last LF may be missing due - to an EOF. If MAX_LENGTH is zero on return, the line has been - truncated. If the returned buffer is NULL, not enough memory was - enable to increase it, the return value will also be 0 and some - bytes might have been lost which should be no problem becuase - out-of-memory is pretty fatal for most applications. - - If a line has been truncated, the file pointer is internally moved - forward to the end of the line. - - Note: The returned buffer is allocated with enough extra space to - append a CR,LF,Nul - */ -static size_t -my_read_line ( -#ifdef HTTP_USE_ESTREAM - estream_t fp, -#else - FILE *fp, -#endif - char **addr_of_buffer, - size_t *length_of_buffer, size_t *max_length) -{ - int c; - char *buffer = *addr_of_buffer; - size_t length = *length_of_buffer; - size_t nbytes = 0; - size_t maxlen = *max_length; - char *p; - - if (!buffer) /* Must allocate a new buffer. */ - { - length = 256; - buffer = xtrymalloc (length); - *addr_of_buffer = buffer; - if (!buffer) - { - *length_of_buffer = *max_length = 0; - return 0; - } - *length_of_buffer = length; - } - - length -= 3; /* Reserve 3 bytes (cr,lf,eol). */ - p = buffer; - while ((c = P_ES(getc) (fp)) != EOF) - { - if (nbytes == length) /* Increase the buffer. */ - { - if (length > maxlen) /* Limit reached. */ - { - /* Skip the rest of the line. */ - while (c != '\n' && (c = P_ES(getc) (fp)) != EOF) - ; - *p++ = '\n'; /* Always append a LF (we reserved some space). */ - nbytes++; - *max_length = 0; /* Indicate truncation */ - break; /*(the while loop)*/ - } - length += 3; /* Adjust for the reserved bytes. */ - length += length < 1024 ? 256 : 1024; - *addr_of_buffer = xtryrealloc (buffer, length); - if (!*addr_of_buffer) - { - int save_errno = errno; - xfree (buffer); - *length_of_buffer = *max_length = 0; - gpg_err_set_errno (save_errno); - return 0; - } - buffer = *addr_of_buffer; - *length_of_buffer = length; - length -= 3; /* And re-adjust for the reservation. */ - p = buffer + nbytes; - } - *p++ = c; - nbytes++; - if (c == '\n') - break; - } - *p = 0; /* Make sure the line is a string. */ - - return nbytes; -} - - /* Transform a header name into a standard capitalized format; e.g. "Content-Type". Conversion stops at the colon. As usual we don't use the localized versions of ctype.h. */ @@ -1418,7 +1247,7 @@ do { maxlen = MAX_LINELEN; - len = my_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen); + len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen); line = hd->buffer; if (!line) return gpg_error_from_syserror (); /* Out of core. */ @@ -1462,7 +1291,7 @@ do { maxlen = MAX_LINELEN; - len = my_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen); + len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen); line = hd->buffer; if (!line) return gpg_error_from_syserror (); /* Out of core. */ @@ -1664,7 +1493,7 @@ struct addrinfo hints, *res, *ai; char portstr[35]; - sprintf (portstr, "%hu", port); + snprintf (portstr, sizeof portstr, "%hu", port); memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_STREAM; if (getaddrinfo (serverlist[srv].target, portstr, &hints, &res)) @@ -1778,22 +1607,25 @@ write_server (int sock, const char *data, size_t length) { int nleft; + int nwritten; /* FIXME: We would better use pth I/O functions. */ nleft = length; while (nleft > 0) { -#ifdef HAVE_W32_SYSTEM - int nwritten; - +#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_PTH) nwritten = send (sock, data, nleft, 0); if ( nwritten == SOCKET_ERROR ) { log_info ("network write failed: ec=%d\n", (int)WSAGetLastError ()); return gpg_error (GPG_ERR_NETWORK); } -#else /*!HAVE_W32_SYSTEM*/ - int nwritten = write (sock, data, nleft); +#else /*!HAVE_W32_SYSTEM || HAVE_PTH*/ +# ifdef HAVE_PTH + nwritten = pth_write (sock, data, nleft); +# else + nwritten = write (sock, data, nleft); +# endif if (nwritten == -1) { if (errno == EINTR) @@ -1810,7 +1642,7 @@ log_info ("network write failed: %s\n", strerror (errno)); return gpg_error_from_syserror (); } -#endif /*!HAVE_W32_SYSTEM*/ +#endif /*!HAVE_W32_SYSTEM || HAVE_PTH*/ nleft -= nwritten; data += nwritten; } @@ -1820,7 +1652,6 @@ -#ifdef HTTP_USE_ESTREAM /* Read handler for estream. */ static ssize_t cookie_read (void *cookie, void *buffer, size_t size) @@ -1961,7 +1792,6 @@ xfree (c); return 0; } -#endif /*HTTP_USE_ESTREAM*/ @@ -1999,9 +1829,7 @@ #endif /*HTTP_USE_GNUTLS*/ header_t hdr; -#ifdef HTTP_USE_ESTREAM es_init (); -#endif log_set_prefix ("http-test", 1 | 4); if (argc == 1) { @@ -2100,7 +1928,7 @@ switch (http_get_status_code (hd)) { case 200: - while ((c = P_ES(getc) (http_get_read_ptr (hd))) != EOF) + while ((c = es_getc (http_get_read_ptr (hd))) != EOF) putchar (c); break; case 301: Modified: trunk/common/http.h =================================================================== --- trunk/common/http.h 2010-08-05 08:51:11 UTC (rev 5381) +++ trunk/common/http.h 2010-08-05 18:47:25 UTC (rev 5382) @@ -21,9 +21,7 @@ #define GNUPG_COMMON_HTTP_H #include -#ifdef HTTP_USE_ESTREAM #include "../common/estream.h" -#endif struct uri_tuple_s { struct uri_tuple_s *next; @@ -100,13 +98,8 @@ const char *srvtag, strlist_t headers); -#ifdef HTTP_USE_ESTREAM estream_t http_get_read_ptr (http_t hd); estream_t http_get_write_ptr (http_t hd); -#else /*!HTTP_USE_ESTREAM*/ -FILE *http_get_read_ptr (http_t hd); -FILE *http_get_write_ptr (http_t hd); -#endif /*!HTTP_USE_ESTREAM*/ unsigned int http_get_status_code (http_t hd); const char *http_get_header (http_t hd, const char *name); From cvs at cvs.gnupg.org Fri Aug 6 12:25:51 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 06 Aug 2010 12:25:51 +0200 Subject: [svn] w32pth - r43 - trunk Message-ID: Author: wk Date: 2010-08-06 12:25:50 +0200 (Fri, 06 Aug 2010) New Revision: 43 Modified: trunk/ChangeLog trunk/NEWS trunk/w32-pth.c Log: Fix regression Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-08-02 18:32:36 UTC (rev 42) +++ trunk/ChangeLog 2010-08-06 10:25:50 UTC (rev 43) @@ -1,3 +1,8 @@ +2010-08-06 Werner Koch + + * w32-pth.c (set_timer): Fix timer setting on plain windows. + Fixes regression introduced on 2010-02-25. + 2010-08-02 Werner Koch Release 2.0.4. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-08-02 18:32:36 UTC (rev 42) +++ trunk/NEWS 2010-08-06 10:25:50 UTC (rev 43) @@ -1,3 +1,9 @@ +Noteworthy changes in version 2.0.5 +------------------------------------------------ + + * Fix regression in W32 timer handling introduced by 2.0.3. + + Noteworthy changes in version 2.0.4 (2010-08-02) ------------------------------------------------ Modified: trunk/w32-pth.c =================================================================== --- trunk/w32-pth.c 2010-08-02 18:32:36 UTC (rev 42) +++ trunk/w32-pth.c 2010-08-06 10:25:50 UTC (rev 43) @@ -688,8 +688,12 @@ #else /* Plain Windows. */ LARGE_INTEGER ll; char strerr[256]; + + if (DBG_CALLS) + _pth_debug (DEBUG_CALLS, "set_timer hd=%p ms=%lu\n", + hd, (unsigned long)milliseconds); - ll.QuadPart = - (milliseconds * 10000); + ll.QuadPart = ((unsigned long)milliseconds * ((long long)-10000LL)); if (!SetWaitableTimer (hd, &ll, 0, NULL, NULL, FALSE)) { if (DBG_ERROR) From cvs at cvs.gnupg.org Fri Aug 6 15:52:03 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 06 Aug 2010 15:52:03 +0200 Subject: [svn] GnuPG - r5383 - in trunk: . common dirmngr Message-ID: Author: wk Date: 2010-08-06 15:52:01 +0200 (Fri, 06 Aug 2010) New Revision: 5383 Modified: trunk/ChangeLog trunk/common/ChangeLog trunk/common/homedir.c trunk/common/http.c trunk/common/http.h trunk/dirmngr/ChangeLog trunk/dirmngr/certcache.c trunk/dirmngr/crlcache.c trunk/dirmngr/crlfetch.c trunk/dirmngr/dirmngr.c trunk/dirmngr/ldap-wrapper-ce.c trunk/dirmngr/misc.c trunk/dirmngr/misc.h trunk/dirmngr/server.c Log: More work on the dirmngr. It now builds for W32 and W32CE and quick tests show that it works on W32. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/ChangeLog 2010-08-06 13:52:01 UTC (rev 5383) @@ -1,3 +1,7 @@ +2010-08-05 Werner Koch + + * configure.ac (AH_BOTTOM): Remove HTTP_USE_ESTREAM. + 2010-08-02 Werner Koch * configure.ac: Require libksba 1.1.0 due to the use of Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/common/ChangeLog 2010-08-06 13:52:01 UTC (rev 5383) @@ -1,3 +1,17 @@ +2010-08-06 Werner Koch + + * homedir.c (dirmngr_socket_name) [W32CE]: Base on default homedir. + (gnupg_cachedir) [W32CE]: Drop drive letter. + + * http.c (http_open_document): Rename to _http_open_document and + add arg ERRSOURCE. Pass ERRSOURCE to all called funcs. + (http_wait_response, http_open, http_parse_uri): Likewise. + (do_parse_uri, parse_response, store_header): Change to return an + gpg_err_code_t. Change callers. + (send_request): Add arg ERRSOURCE. Change callers. + * http.h (http_open_document, http_wait_response, http_open) + (http_parse_uri): Define as macro. + 2010-08-05 Werner Koch * estream.h (es_asprintf, es_vasprintf): Add lost prototyps. Modified: trunk/dirmngr/ChangeLog =================================================================== --- trunk/dirmngr/ChangeLog 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/dirmngr/ChangeLog 2010-08-06 13:52:01 UTC (rev 5383) @@ -1,3 +1,24 @@ +2010-08-06 Werner Koch + + * dirmngr.c (JNLIB_NEED_AFLOCAL): Define macro. + (main): Use SUN_LEN macro. + (main) [W32]: Allow EEXIST in addition to EADDRINUSE. + (JNLIB_NEED_AFLOCAL): + +2010-08-05 Werner Koch + + * server.c (set_error, leave_cmd): New. + (cmd_validate, cmd_ldapserver, cmd_isvalid, cmd_checkcrl) + (cmd_checkocsp, cmd_lookup, cmd_listcrls, cmd_cachecert): Use + leave_cmd. + (cmd_getinfo): New. + (data_line_cookie_write, data_line_cookie_close): New. + (cmd_listcrls): Replace assuan_get_data_fp by es_fopencookie. + + * misc.c (create_estream_ksba_reader, my_estream_ksba_reader_cb): New. + * certcache.c (load_certs_from_dir): Use create_estream_ksba_reader. + * crlcache.c (crl_cache_load): Ditto. + 2010-08-03 Werner Koch * dirmngr_ldap.c (pth_enter, pth_leave) [USE_LDAPWRAPPER]: Turn Modified: trunk/common/homedir.c =================================================================== --- trunk/common/homedir.c 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/common/homedir.c 2010-08-06 13:52:01 UTC (rev 5383) @@ -412,7 +412,12 @@ dir = tmp; } else - dir = "c:\\temp\\cache\\dirmngr"; + { + dir = "c:\\temp\\cache\\gnupg"; +#ifdef HAVE_W32CE_SYSTEM + dir += 2; +#endif + } } return dir; #else /*!HAVE_W32_SYSTEM*/ @@ -430,6 +435,12 @@ if (!name) { + char *p; +# ifdef HAVE_W32CE_SYSTEM + const char *s1, *s2; + + s1 = default_homedir (); +# else char s1[MAX_PATH]; const char *s2; @@ -440,9 +451,13 @@ that. */ if (w32_shgetfolderpath (NULL, CSIDL_WINDOWS, NULL, 0, s1) < 0) strcpy (s1, "C:\\WINDOWS"); +# endif s2 = DIRSEP_S "S.dirmngr"; name = xmalloc (strlen (s1) + strlen (s2) + 1); strcpy (stpcpy (name, s1), s2); + for (p=name; *p; p++) + if (*p == '/') + *p = '\\'; } return name; #else /*!HAVE_W32_SYSTEM*/ Modified: trunk/common/http.c =================================================================== --- trunk/common/http.c 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/common/http.c 2010-08-06 13:52:01 UTC (rev 5383) @@ -131,21 +131,18 @@ # define counter_strtoul(a) strtoul ((a), NULL, 10) #endif -#if defined(HTTP_USE_ESTREAM) && defined (__GNUC__) -# warning HTTP_USE_ESTREAM is an obsolete macro -#endif - #ifndef HTTP_USE_GNUTLS typedef void * gnutls_session_t; #endif -static gpg_error_t do_parse_uri (parsed_uri_t uri, int only_local_part); +static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part); static int remove_escapes (char *string); static int insert_escapes (char *buffer, const char *string, const char *special); static uri_tuple_t parse_tuple (char *string); static gpg_error_t send_request (http_t hd, const char *auth,const char *proxy, - const char *srvtag,strlist_t headers); + const char *srvtag,strlist_t headers, + gpg_err_source_t errsource); static char *build_rel_path (parsed_uri_t uri); static gpg_error_t parse_response (http_t hd); @@ -334,9 +331,10 @@ pointer for completing the the request and to wait for the response. */ gpg_error_t -http_open (http_t *r_hd, http_req_t reqtype, const char *url, - const char *auth, unsigned int flags, const char *proxy, - void *tls_context, const char *srvtag,strlist_t headers) +_http_open (http_t *r_hd, http_req_t reqtype, const char *url, + const char *auth, unsigned int flags, const char *proxy, + void *tls_context, const char *srvtag, strlist_t headers, + gpg_err_source_t errsource) { gpg_error_t err; http_t hd; @@ -344,7 +342,7 @@ *r_hd = NULL; if (!(reqtype == HTTP_REQ_GET || reqtype == HTTP_REQ_POST)) - return gpg_error (GPG_ERR_INV_ARG); + return gpg_err_make (errsource, GPG_ERR_INV_ARG); /* Create the handle. */ hd = xtrycalloc (1, sizeof *hd); @@ -355,9 +353,9 @@ hd->flags = flags; hd->tls_context = tls_context; - err = http_parse_uri (&hd->uri, url); + err = _http_parse_uri (&hd->uri, url, errsource); if (!err) - err = send_request (hd, auth, proxy, srvtag, headers); + err = send_request (hd, auth, proxy, srvtag, headers, errsource); if (err) { @@ -391,7 +389,7 @@ gpg_error_t -http_wait_response (http_t hd) +_http_wait_response (http_t hd, gpg_err_source_t errsource) { gpg_error_t err; cookie_t cookie; @@ -402,7 +400,7 @@ /* Close the write stream but keep the socket open. */ cookie = hd->write_cookie; if (!cookie) - return gpg_error (GPG_ERR_INTERNAL); + return gpg_err_make (errsource, GPG_ERR_INTERNAL); cookie->keep_socket = 1; es_fclose (hd->fp_write); @@ -420,7 +418,7 @@ /* Create a new cookie and a stream for reading. */ cookie = xtrycalloc (1, sizeof *cookie); if (!cookie) - return gpg_error_from_syserror (); + return gpg_err_make (errsource, gpg_err_code_from_syserror ()); cookie->fd = hd->sock; if (hd->uri->use_tls) cookie->tls_session = hd->tls_context; @@ -431,7 +429,7 @@ { xfree (cookie); hd->read_cookie = NULL; - return gpg_error_from_syserror (); + return gpg_err_make (errsource, gpg_err_code_from_syserror ()); } err = parse_response (hd); @@ -444,18 +442,19 @@ be used as an HTTP proxy and any enabled $http_proxy gets ignored. */ gpg_error_t -http_open_document (http_t *r_hd, const char *document, - const char *auth, unsigned int flags, const char *proxy, - void *tls_context, const char *srvtag,strlist_t headers) +_http_open_document (http_t *r_hd, const char *document, + const char *auth, unsigned int flags, const char *proxy, + void *tls_context, const char *srvtag, strlist_t headers, + gpg_err_source_t errsource) { gpg_error_t err; - err = http_open (r_hd, HTTP_REQ_GET, document, auth, flags, - proxy, tls_context, srvtag, headers); + err = _http_open (r_hd, HTTP_REQ_GET, document, auth, flags, + proxy, tls_context, srvtag, headers, errsource); if (err) return err; - err = http_wait_response (*r_hd); + err = _http_wait_response (*r_hd, errsource); if (err) http_close (*r_hd, 0); @@ -513,13 +512,14 @@ * resources (even on error). */ gpg_error_t -http_parse_uri (parsed_uri_t * ret_uri, const char *uri) +_http_parse_uri (parsed_uri_t * ret_uri, const char *uri, + gpg_err_source_t errsource) { *ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri)); if (!*ret_uri) - return gpg_error_from_syserror (); + return gpg_err_make (errsource, gpg_err_code_from_syserror ()); strcpy ((*ret_uri)->buffer, uri); - return do_parse_uri (*ret_uri, 0); + return gpg_err_make (errsource, do_parse_uri (*ret_uri, 0)); } void @@ -539,7 +539,7 @@ } -static gpg_error_t +static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part) { uri_tuple_t *tail; @@ -557,13 +557,13 @@ /* A quick validity check. */ if (strspn (p, VALID_URI_CHARS) != n) - return gpg_error (GPG_ERR_BAD_URI); /* Invalid characters found. */ + return GPG_ERR_BAD_URI; /* Invalid characters found. */ if (!only_local_part) { /* Find the scheme. */ if (!(p2 = strchr (p, ':')) || p2 == p) - return gpg_error (GPG_ERR_BAD_URI); /* No scheme. */ + return GPG_ERR_BAD_URI; /* No scheme. */ *p2++ = 0; for (pp=p; *pp; pp++) *pp = tolower (*(unsigned char*)pp); @@ -578,13 +578,13 @@ } #endif else - return gpg_error (GPG_ERR_INV_URI); /* Unsupported scheme */ + return GPG_ERR_INV_URI; /* Unsupported scheme */ p = p2; /* Find the hostname */ if (*p != '/') - return gpg_error (GPG_ERR_INV_URI); /* Does not start with a slash. */ + return GPG_ERR_INV_URI; /* Does not start with a slash. */ p++; if (*p == '/') /* There seems to be a hostname. */ @@ -622,9 +622,9 @@ } if ((n = remove_escapes (uri->host)) < 0) - return gpg_error (GPG_ERR_BAD_URI); + return GPG_ERR_BAD_URI; if (n != strlen (uri->host)) - return gpg_error (GPG_ERR_BAD_URI); /* Hostname incudes a Nul. */ + return GPG_ERR_BAD_URI; /* Hostname incudes a Nul. */ p = p2 ? p2 : NULL; } } /* End global URI part. */ @@ -641,9 +641,9 @@ uri->path = p; if ((n = remove_escapes (p)) < 0) - return gpg_error (GPG_ERR_BAD_URI); + return GPG_ERR_BAD_URI; if (n != strlen (p)) - return gpg_error (GPG_ERR_BAD_URI); /* Path includes a Nul. */ + return GPG_ERR_BAD_URI; /* Path includes a Nul. */ p = p2 ? p2 : NULL; if (!p || !*p) @@ -658,7 +658,7 @@ if ((p2 = strchr (p, '&'))) *p2++ = 0; if (!(elem = parse_tuple (p))) - return gpg_error (GPG_ERR_BAD_URI); + return GPG_ERR_BAD_URI; *tail = elem; tail = &elem->next; @@ -816,7 +816,8 @@ */ static gpg_error_t send_request (http_t hd, const char *auth, - const char *proxy,const char *srvtag,strlist_t headers) + const char *proxy, const char *srvtag, strlist_t headers, + gpg_err_source_t errsource) { gnutls_session_t tls_session; gpg_error_t err; @@ -832,7 +833,7 @@ if (hd->uri->use_tls && !tls_session) { log_error ("TLS requested but no GNUTLS context provided\n"); - return gpg_error (GPG_ERR_INTERNAL); + return gpg_err_make (errsource, GPG_ERR_INTERNAL); } server = *hd->uri->host ? hd->uri->host : "localhost"; @@ -848,14 +849,13 @@ if (proxy) http_proxy = proxy; - err = http_parse_uri (&uri, http_proxy); + err = _http_parse_uri (&uri, http_proxy, errsource); if (err) { log_error ("invalid HTTP proxy (%s): %s\n", http_proxy, gpg_strerror (err)); http_release_parsed_uri (uri); - return gpg_error (GPG_ERR_CONFIGURATION); - + return gpg_err_make (errsource, GPG_ERR_CONFIGURATION); } if (uri->auth) @@ -866,7 +866,7 @@ uri->auth, strlen(uri->auth)); if (!proxy_authstr) { - err = gpg_error_from_syserror (); + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); http_release_parsed_uri (uri); return err; } @@ -887,9 +887,9 @@ if (hd->sock == -1) { xfree (proxy_authstr); - return (save_errno - ? gpg_error_from_errno (save_errno) - : gpg_error (GPG_ERR_NOT_FOUND)); + return gpg_err_make (errsource, (save_errno + ? gpg_err_code_from_errno (save_errno) + : GPG_ERR_NOT_FOUND)); } #ifdef HTTP_USE_GNUTLS @@ -907,7 +907,7 @@ { log_info ("TLS handshake failed: %s\n", gnutls_strerror (rc)); xfree (proxy_authstr); - return gpg_error (GPG_ERR_NETWORK); + return gpg_err_make (errsource, GPG_ERR_NETWORK); } if (tls_callback) @@ -934,7 +934,7 @@ if (!myauth) { xfree (proxy_authstr); - return gpg_error_from_syserror (); + return gpg_err_make (errsource, gpg_err_code_from_syserror ()); } remove_escapes (myauth); } @@ -952,13 +952,13 @@ if (!authstr) { xfree (proxy_authstr); - return gpg_error_from_syserror (); + return gpg_err_make (errsource, gpg_err_code_from_syserror ()); } } p = build_rel_path (hd->uri); if (!p) - return gpg_error_from_syserror (); + return gpg_err_make (errsource, gpg_err_code_from_syserror ()); if (http_proxy && *http_proxy) { @@ -991,7 +991,7 @@ xfree (p); if (!request) { - err = gpg_error_from_syserror (); + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); xfree (authstr); xfree (proxy_authstr); return err; @@ -1006,7 +1006,7 @@ cookie = xtrycalloc (1, sizeof *cookie); if (!cookie) { - err = gpg_error_from_syserror (); + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); goto leave; } cookie->fd = hd->sock; @@ -1017,12 +1017,12 @@ hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); if (!hd->fp_write) { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); xfree (cookie); hd->write_cookie = NULL; - err = gpg_error_from_syserror (); } else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) - err = gpg_error_from_syserror (); + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); else err = 0; @@ -1033,7 +1033,7 @@ if ((es_fputs (headers->d, hd->fp_write) || es_fflush (hd->fp_write)) || (es_fputs("\r\n",hd->fp_write) || es_fflush(hd->fp_write))) { - err = gpg_error_from_syserror (); + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); break; } } @@ -1128,7 +1128,7 @@ /* Store an HTTP header line in LINE away. Line continuation is supported as well as merging of headers with the same name. This function may modify LINE. */ -static gpg_error_t +static gpg_err_code_t store_header (http_t hd, char *line) { size_t n; @@ -1143,17 +1143,17 @@ line[--n] = 0; } if (!n) /* we are never called to hit this. */ - return gpg_error (GPG_ERR_BUG); + return GPG_ERR_BUG; if (*line == ' ' || *line == '\t') { /* Continuation. This won't happen too often as it is not recommended. We use a straightforward implementaion. */ if (!hd->headers) - return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); + return GPG_ERR_PROTOCOL_VIOLATION; n += strlen (hd->headers->value); p = xtrymalloc (n+1); if (!p) - return gpg_error_from_syserror (); + return gpg_err_code_from_syserror (); strcpy (stpcpy (p, hd->headers->value), line); xfree (hd->headers->value); hd->headers->value = p; @@ -1163,7 +1163,7 @@ capitalize_header_name (line); p = strchr (line, ':'); if (!p) - return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); + return GPG_ERR_PROTOCOL_VIOLATION; *p++ = 0; while (*p == ' ' || *p == '\t') p++; @@ -1178,7 +1178,7 @@ it is a comma separated list and merge them. */ p = xtrymalloc (strlen (h->value) + 1 + strlen (value)+ 1); if (!p) - return gpg_error_from_syserror (); + return gpg_err_code_from_syserror (); strcpy (stpcpy (stpcpy (p, h->value), ","), value); xfree (h->value); h->value = p; @@ -1188,13 +1188,13 @@ /* Append a new header. */ h = xtrymalloc (sizeof *h + strlen (line)); if (!h) - return gpg_error_from_syserror (); + return gpg_err_code_from_syserror (); strcpy (h->name, line); h->value = xtrymalloc (strlen (value)+1); if (!h->value) { xfree (h); - return gpg_error_from_syserror (); + return gpg_err_code_from_syserror (); } strcpy (h->value, value); h->next = hd->headers; @@ -1226,7 +1226,7 @@ * Parse the response from a server. * Returns: Errorcode and sets some files in the handle */ -static gpg_error_t +static gpg_err_code_t parse_response (http_t hd) { char *line, *p, *p2; @@ -1250,12 +1250,13 @@ len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen); line = hd->buffer; if (!line) - return gpg_error_from_syserror (); /* Out of core. */ + return gpg_err_code_from_syserror (); /* Out of core. */ if (!maxlen) - return gpg_error (GPG_ERR_TRUNCATED); /* Line has been truncated. */ + return GPG_ERR_TRUNCATED; /* Line has been truncated. */ if (!len) - return gpg_error (GPG_ERR_EOF); - if ( (hd->flags & HTTP_FLAG_LOG_RESP) ) + return GPG_ERR_EOF; + + if ((hd->flags & HTTP_FLAG_LOG_RESP)) log_info ("RESP: `%.*s'\n", (int)strlen(line)-(*line&&line[1]?2:0),line); } @@ -1294,21 +1295,21 @@ len = es_read_line (hd->fp_read, &hd->buffer, &hd->buffer_size, &maxlen); line = hd->buffer; if (!line) - return gpg_error_from_syserror (); /* Out of core. */ + return gpg_err_code_from_syserror (); /* Out of core. */ /* Note, that we can silently ignore truncated lines. */ if (!len) - return gpg_error (GPG_ERR_EOF); + return GPG_ERR_EOF; /* Trim line endings of empty lines. */ if ((*line == '\r' && line[1] == '\n') || *line == '\n') *line = 0; - if ( (hd->flags & HTTP_FLAG_LOG_RESP) ) + if ((hd->flags & HTTP_FLAG_LOG_RESP)) log_info ("RESP: `%.*s'\n", (int)strlen(line)-(*line&&line[1]?2:0),line); if (*line) { - gpg_error_t err = store_header (hd, line); - if (err) - return err; + gpg_err_code_t ec = store_header (hd, line); + if (ec) + return ec; } } while (len && *line); Modified: trunk/common/http.h =================================================================== --- trunk/common/http.h 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/common/http.h 2010-08-06 13:52:01 UTC (rev 5383) @@ -70,33 +70,44 @@ void http_register_tls_callback (gpg_error_t (*cb) (http_t, void *, int)); -gpg_error_t http_parse_uri (parsed_uri_t *ret_uri, const char *uri); +gpg_error_t _http_parse_uri (parsed_uri_t *ret_uri, const char *uri, + gpg_err_source_t errsource); +#define http_parse_uri(a,b) \ + _http_parse_uri ((a), (b), GPG_ERR_SOURCE_DEFAULT) void http_release_parsed_uri (parsed_uri_t uri); -gpg_error_t http_open (http_t *r_hd, http_req_t reqtype, - const char *url, - const char *auth, - unsigned int flags, - const char *proxy, - void *tls_context, - const char *srvtag, - strlist_t headers); +gpg_error_t _http_open (http_t *r_hd, http_req_t reqtype, + const char *url, + const char *auth, + unsigned int flags, + const char *proxy, + void *tls_context, + const char *srvtag, + strlist_t headers, + gpg_err_source_t errsource); +#define http_open(a,b,c,d,e,f,g,h,i) \ + _http_open ((a),(b),(c),(d),(e),(f),(g),(h),(i), GPG_ERR_SOURCE_DEFAULT) void http_start_data (http_t hd); -gpg_error_t http_wait_response (http_t hd); +gpg_error_t _http_wait_response (http_t hd, gpg_err_source_t errsource); +#define http_wait_response(a) \ + _http_wait_response ((a), GPG_ERR_SOURCE_DEFAULT) void http_close (http_t hd, int keep_read_stream); -gpg_error_t http_open_document (http_t *r_hd, - const char *document, - const char *auth, - unsigned int flags, - const char *proxy, - void *tls_context, - const char *srvtag, - strlist_t headers); +gpg_error_t _http_open_document (http_t *r_hd, + const char *document, + const char *auth, + unsigned int flags, + const char *proxy, + void *tls_context, + const char *srvtag, + strlist_t headers, + gpg_err_source_t errsource); +#define http_open_document(a,b,c,d,e,f,g,h) \ + _http_open_document ((a),(b),(c),(d),(e),(f),(g),(h), GPG_ERR_SOURCE_DEFAULT) estream_t http_get_read_ptr (http_t hd); estream_t http_get_write_ptr (http_t hd); Modified: trunk/dirmngr/certcache.c =================================================================== --- trunk/dirmngr/certcache.c 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/dirmngr/certcache.c 2010-08-06 13:52:01 UTC (rev 5383) @@ -360,13 +360,10 @@ fname, strerror (errno)); continue; } - err = ksba_reader_new (&reader); - if (!err) - err = ksba_reader_set_file (reader, fp); + + err = create_estream_ksba_reader (&reader, fp); if (err) { - log_error (_("can't setup KSBA reader: %s\n"), gpg_strerror (err)); - ksba_reader_release (reader); es_fclose (fp); continue; } Modified: trunk/dirmngr/crlcache.c =================================================================== --- trunk/dirmngr/crlcache.c 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/dirmngr/crlcache.c 2010-08-06 13:52:01 UTC (rev 5383) @@ -2369,18 +2369,12 @@ return err; } - err = ksba_reader_new (&reader); + err = create_estream_ksba_reader (&reader, fp); if (!err) - err = ksba_reader_set_file (reader, fp); - if (err) { - log_error (_("error initializing reader object: %s\n"), - gpg_strerror (err)); + err = crl_cache_insert (ctrl, filename, reader); ksba_reader_release (reader); - return err; } - err = crl_cache_insert (ctrl, filename, reader); - ksba_reader_release (reader); es_fclose (fp); return err; } Modified: trunk/dirmngr/crlfetch.c =================================================================== --- trunk/dirmngr/crlfetch.c 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/dirmngr/crlfetch.c 2010-08-06 13:52:01 UTC (rev 5383) @@ -30,6 +30,7 @@ #include "http.h" #include "estream.h" +#include "ldap-wrapper.h" /* For detecting armored CRLs received via HTTP (yes, such CRLS really @@ -228,7 +229,8 @@ pointer (or well the callback context) with the reader. It is only required when closing the reader thus there is no performance issue doing it - this way. */ + this way. FIXME: We now have a close notification + which might be used here. */ register_file_reader (*reader, cb_ctx); http_close (hd, 1); } Modified: trunk/dirmngr/dirmngr.c =================================================================== --- trunk/dirmngr/dirmngr.c 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/dirmngr/dirmngr.c 2010-08-06 13:52:01 UTC (rev 5383) @@ -44,6 +44,7 @@ #define JNLIB_NEED_LOG_LOGV +#define JNLIB_NEED_AFLOCAL #include "dirmngr.h" #include @@ -963,12 +964,17 @@ memset (&serv_addr, 0, sizeof serv_addr); serv_addr.sun_family = AF_UNIX; strcpy (serv_addr.sun_path, socket_name); - len = (offsetof (struct sockaddr_un, sun_path) - + strlen (serv_addr.sun_path) + 1); + len = SUN_LEN (&serv_addr); rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len); - if (rc == -1 && errno == EADDRINUSE) + if (rc == -1 + && (errno == EADDRINUSE +#ifdef HAVE_W32_SYSTEM + || errno == EEXIST +#endif + )) { + /* Fixme: We should test whether a dirmngr is already running. */ gnupg_remove (socket_name); rc = assuan_sock_bind (fd, (struct sockaddr*) &serv_addr, len); } Modified: trunk/dirmngr/ldap-wrapper-ce.c =================================================================== --- trunk/dirmngr/ldap-wrapper-ce.c 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/dirmngr/ldap-wrapper-ce.c 2010-08-06 13:52:01 UTC (rev 5383) @@ -199,7 +199,7 @@ const char *src; size_t nread = 0; - if (!buffer && !count && !nread) + if (!buffer && !count && !r_nread) return gpg_error (GPG_ERR_NOT_SUPPORTED); /* Rewind is not supported. */ *r_nread = 0; Modified: trunk/dirmngr/misc.c =================================================================== --- trunk/dirmngr/misc.c 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/dirmngr/misc.c 2010-08-06 13:52:01 UTC (rev 5383) @@ -1,6 +1,6 @@ /* misc.c - miscellaneous * Copyright (C) 2002 Klar?lvdalens Datakonsult AB - * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2002, 2003, 2004, 2010 Free Software Foundation, Inc. * * This file is part of DirMngr. * @@ -484,3 +484,48 @@ return buf; } + +/* A KSBA reader callback to read from an estream. */ +static int +my_estream_ksba_reader_cb (void *cb_value, char *buffer, size_t count, + size_t *r_nread) +{ + estream_t fp = cb_value; + + if (!fp) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!buffer && !count && !r_nread) + { + es_rewind (fp); + return 0; + } + + *r_nread = es_fread (buffer, 1, count, fp); + if (!*r_nread) + return -1; /* EOF or error. */ + return 0; /* Success. */ +} + + +/* Create a KSBA reader object and connect it to the estream FP. */ +gpg_error_t +create_estream_ksba_reader (ksba_reader_t *r_reader, estream_t fp) +{ + gpg_error_t err; + ksba_reader_t reader; + + *r_reader = NULL; + err = ksba_reader_new (&reader); + if (!err) + err = ksba_reader_set_cb (reader, my_estream_ksba_reader_cb, fp); + if (err) + { + log_error (_("error initializing reader object: %s\n"), + gpg_strerror (err)); + ksba_reader_release (reader); + return err; + } + *r_reader = reader; + return 0; +} Modified: trunk/dirmngr/misc.h =================================================================== --- trunk/dirmngr/misc.h 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/dirmngr/misc.h 2010-08-06 13:52:01 UTC (rev 5383) @@ -73,15 +73,9 @@ URL. */ char *host_and_port_from_url (const char *url, int *port); +/* Create a KSBA reader object and connect it to the estream FP. */ +gpg_error_t create_estream_ksba_reader (ksba_reader_t *r_reader, estream_t fp); -#ifdef HAVE_FOPENCOOKIE -/* We have to implement funopen in terms of glibc's fopencookie. */ -FILE *funopen(void *cookie, - int (*readfn)(void *, char *, int), - int (*writefn)(void *, const char *, int), - fpos_t (*seekfn)(void *, fpos_t, int), - int (*closefn)(void *)); -#endif /*HAVE_FOPENCOOKIE*/ #endif /* MISC_H */ Modified: trunk/dirmngr/server.c =================================================================== --- trunk/dirmngr/server.c 2010-08-05 18:47:25 UTC (rev 5382) +++ trunk/dirmngr/server.c 2010-08-06 13:52:01 UTC (rev 5383) @@ -40,6 +40,7 @@ #include "certcache.h" #include "validate.h" #include "misc.h" +#include "ldap-wrapper.h" /* To avoid DoS attacks we limit the size of a certificate to something reasonable. */ @@ -47,6 +48,7 @@ #define PARM_ERROR(t) assuan_set_error (ctx, \ gpg_error (GPG_ERR_ASS_PARAMETER), (t)) +#define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) @@ -61,7 +63,21 @@ }; +/* Cookie definition for assuan data line output. */ +static ssize_t data_line_cookie_write (void *cookie, + const void *buffer, size_t size); +static int data_line_cookie_close (void *cookie); +static es_cookie_io_functions_t data_line_cookie_functions = + { + NULL, + data_line_cookie_write, + NULL, + data_line_cookie_close + }; + + + /* Accessor for the local ldapservers variable. */ ldap_server_t @@ -74,7 +90,56 @@ } +/* Helper to print a message while leaving a command. */ +static gpg_error_t +leave_cmd (assuan_context_t ctx, gpg_error_t err) +{ + if (err) + { + const char *name = assuan_get_command_name (ctx); + if (!name) + name = "?"; + if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) + log_error ("command '%s' failed: %s\n", name, + gpg_strerror (err)); + else + log_error ("command '%s' failed: %s <%s>\n", name, + gpg_strerror (err), gpg_strsource (err)); + } + return err; +} +/* A write handler used by es_fopencookie to write assuan data + lines. */ +static ssize_t +data_line_cookie_write (void *cookie, const void *buffer, size_t size) +{ + assuan_context_t ctx = cookie; + + if (assuan_send_data (ctx, buffer, size)) + { + gpg_err_set_errno (EIO); + return -1; + } + + return size; +} + +static int +data_line_cookie_close (void *cookie) +{ + assuan_context_t ctx = cookie; + + if (assuan_send_data (ctx, NULL, 0)) + { + gpg_err_set_errno (EIO); + return -1; + } + + return 0; +} + + /* Copy the % and + escaped string S into the buffer D and replace the escape sequences. Note, that it is sufficient to allocate the target string D as long as the source string S, i.e.: strlen(s)+1. @@ -452,17 +517,17 @@ while (spacep (line)) line++; if (*line == '\0') - return PARM_ERROR (_("ldapserver missing")); + return leave_cmd (ctx, PARM_ERROR (_("ldapserver missing"))); server = ldapserver_parse_one (line, "", 0); if (! server) - return gpg_error (GPG_ERR_INV_ARG); + return leave_cmd (ctx, gpg_error (GPG_ERR_INV_ARG)); last_next_p = &ctrl->server_local->ldapservers; while (*last_next_p) last_next_p = &(*last_next_p)->next; *last_next_p = server; - return 0; + return leave_cmd (ctx, 0); } @@ -522,7 +587,7 @@ if (strlen (issuerhash) != 40) { xfree (issuerhash); - return PARM_ERROR (_("serialno missing in cert ID")); + return leave_cmd (ctx, PARM_ERROR (_("serialno missing in cert ID"))); } ocsp_mode = 1; } @@ -574,10 +639,8 @@ } } - if (err) - log_error (_("command %s failed: %s\n"), "ISVALID", gpg_strerror (err)); xfree (issuerhash); - return err; + return leave_cmd (ctx, err); } @@ -688,10 +751,8 @@ } leave: - if (err) - log_error (_("command %s failed: %s\n"), "CHECKCRL", gpg_strerror (err)); ksba_cert_release (cert); - return err; + return leave_cmd (ctx, err); } @@ -773,10 +834,8 @@ err = ocsp_isvalid (ctrl, cert, NULL, force_default_responder); leave: - if (err) - log_error (_("command %s failed: %s\n"), "CHECKOCSP", gpg_strerror (err)); ksba_cert_release (cert); - return err; + return leave_cmd (ctx, err); } @@ -1066,10 +1125,7 @@ else err = lookup_cert_by_pattern (ctx, line, single, cache_only); - if (err) - log_error (_("command %s failed: %s\n"), "LOOKUP", gpg_strerror (err)); - - return err; + return leave_cmd (ctx, err); } @@ -1126,9 +1182,7 @@ } } - if (err) - log_error (_("command %s failed: %s\n"), "LOADCRL", gpg_strerror (err)); - return err; + return leave_cmd (ctx, err); } @@ -1143,17 +1197,19 @@ cmd_listcrls (assuan_context_t ctx, char *line) { gpg_error_t err; - estream_t fp = assuan_get_data_fp (ctx); + estream_t fp; (void)line; + fp = es_fopencookie (ctx, "w", data_line_cookie_functions); if (!fp) - return PARM_ERROR (_("no data stream")); - - err = crl_cache_list (fp); - if (err) - log_error (_("command %s failed: %s\n"), "LISTCRLS", gpg_strerror (err)); - return err; + err = set_error (GPG_ERR_ASS_GENERAL, "error setting up a data stream"); + else + { + err = crl_cache_list (fp); + es_fclose (fp); + } + return leave_cmd (ctx, err); } @@ -1204,10 +1260,8 @@ err = cache_cert (cert); leave: - if (err) - log_error (_("command %s failed: %s\n"), "CACHECERT", gpg_strerror (err)); ksba_cert_release (cert); - return err; + return leave_cmd (ctx, err); } @@ -1273,14 +1327,57 @@ err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CERT, NULL); leave: - if (err) - log_error (_("command %s failed: %s\n"), "VALIDATE", gpg_strerror (err)); ksba_cert_release (cert); - return err; + return leave_cmd (ctx, err); } + +static const char hlp_getinfo[] = + "GETINFO \n" + "\n" + "Multi purpose command to return certain information. \n" + "Supported values of WHAT are:\n" + "\n" + "version - Return the version of the program.\n" + "pid - Return the process id of the server.\n" + "\n" + "socket_name - Return the name of the socket.\n"; +static gpg_error_t +cmd_getinfo (assuan_context_t ctx, char *line) +{ + gpg_error_t err; + if (!strcmp (line, "version")) + { + const char *s = VERSION; + err = assuan_send_data (ctx, s, strlen (s)); + } + else if (!strcmp (line, "pid")) + { + char numbuf[50]; + + snprintf (numbuf, sizeof numbuf, "%lu", (unsigned long)getpid ()); + err = assuan_send_data (ctx, numbuf, strlen (numbuf)); + } + else if (!strcmp (line, "socket_name")) + { + const char *s = dirmngr_socket_name (); + + if (s) + err = assuan_send_data (ctx, s, strlen (s)); + else + err = gpg_error (GPG_ERR_NO_DATA); + } + else + err = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); + + return leave_cmd (ctx, err); +} + + + + /* Tell the assuan library about our commands. */ static int register_commands (assuan_context_t ctx) @@ -1299,8 +1396,7 @@ { "LISTCRLS", cmd_listcrls, hlp_listcrls }, { "CACHECERT", cmd_cachecert, hlp_cachecert }, { "VALIDATE", cmd_validate, hlp_validate }, - { "INPUT", NULL }, - { "OUTPUT", NULL }, + { "GETINFO", cmd_getinfo, hlp_getinfo }, { NULL, NULL } }; int i, j, rc; From cvs at cvs.gnupg.org Mon Aug 9 11:05:18 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 09 Aug 2010 11:05:18 +0200 Subject: [svn] GnuPG - r5384 - trunk/tools Message-ID: Author: wk Date: 2010-08-09 11:05:18 +0200 (Mon, 09 Aug 2010) New Revision: 5384 Modified: trunk/tools/ChangeLog trunk/tools/gpgtar-create.c trunk/tools/gpgtar.c Log: Add option --null Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2010-08-06 13:52:01 UTC (rev 5383) +++ trunk/tools/ChangeLog 2010-08-09 09:05:18 UTC (rev 5384) @@ -1,3 +1,8 @@ +2010-08-09 Werner Koch + + * gpgtar.c (main): Add options -T and --null. + * gpgtar-create.c (gpgtar_create): Implement option --null. + 2010-07-16 Werner Koch * gpgtar-create.c: Rewrite to better support W32. Modified: trunk/tools/gpgtar-create.c =================================================================== --- trunk/tools/gpgtar-create.c 2010-08-06 13:52:01 UTC (rev 5383) +++ trunk/tools/gpgtar-create.c 2010-08-09 09:05:18 UTC (rev 5384) @@ -736,27 +736,88 @@ +/* Create a new tarball using the names in the array INPATTERN. If + INPATTERN is NULL take the pattern as null terminated strings from + stdin. */ void gpgtar_create (char **inpattern) { gpg_error_t err = 0; - const char *pattern; struct scanctrl_s scanctrl_buffer; scanctrl_t scanctrl = &scanctrl_buffer; tar_header_t hdr, *start_tail; estream_t outstream = NULL; + int eof_seen = 0; + if (!inpattern) + es_set_binary (es_stdin); + memset (scanctrl, 0, sizeof *scanctrl); scanctrl->flist_tail = &scanctrl->flist; - for (; (pattern = *inpattern); inpattern++) + while (!eof_seen) { char *pat, *p; + int skip_this = 0; - if (!*pattern) - continue; + if (inpattern) + { + const char *pattern = *inpattern; - pat = xtrystrdup (pattern); + if (!pattern) + break; /* End of array. */ + inpattern++; + + if (!*pattern) + continue; + + pat = xtrystrdup (pattern); + } + else /* Read null delimited pattern from stdin. */ + { + int c; + char namebuf[4096]; + size_t n = 0; + + for (;;) + { + if ((c = es_getc (es_stdin)) == EOF) + { + if (es_ferror (es_stdin)) + { + err = gpg_error_from_syserror (); + log_error ("error reading `%s': %s\n", + "[stdin]", strerror (errno)); + goto leave; + } + /* Note: The Nul is a delimiter and not a terminator. */ + c = 0; + eof_seen = 1; + } + if (n >= sizeof namebuf - 1) + { + if (!skip_this) + { + skip_this = 1; + log_error ("error reading `%s': %s\n", + "[stdin]", "filename too long"); + } + } + else + namebuf[n++] = c; + if (!c) + { + namebuf[n] = 0; + break; + } + } + + if (skip_this || n < 2) + continue; + + pat = xtrystrdup (namebuf); + } + if (!pat) { err = gpg_error_from_syserror (); @@ -771,7 +832,7 @@ log_info ("scanning `%s'\n", pat); start_tail = scanctrl->flist_tail; - if (!pattern_valid_p (pat)) + if (skip_this || !pattern_valid_p (pat)) log_error ("skipping invalid name `%s'\n", pat); else if (!add_entry (pat, NULL, scanctrl) && *start_tail && ((*start_tail)->typeflag & TF_DIRECTORY)) Modified: trunk/tools/gpgtar.c =================================================================== --- trunk/tools/gpgtar.c 2010-08-06 13:52:01 UTC (rev 5383) +++ trunk/tools/gpgtar.c 2010-08-09 09:05:18 UTC (rev 5384) @@ -55,12 +55,14 @@ oOutput = 'o', oQuiet = 'q', oVerbose = 'v', + oFilesFrom = 'T', oNoVerbose = 500, aSignEncrypt, oSkipCrypto, oSetFilename, - aList + aList, + oNull }; @@ -84,7 +86,11 @@ ARGPARSE_s_n (oQuiet, "quiet", N_("be somewhat more quiet")), ARGPARSE_s_n (oSkipCrypto, "skip-crypto", N_("skip the crypto processing")), ARGPARSE_s_s (oSetFilename, "set-filename", "@"), + ARGPARSE_s_s (oFilesFrom, "files-from", + N_("|FILE|get names to create from FILE")), + ARGPARSE_s_n (oNull, "null", N_("-T reads null-terminated names")), + ARGPARSE_end () }; @@ -157,6 +163,8 @@ int no_more_options = 0; enum cmd_and_opt_values cmd = 0; int skip_crypto = 0; + const char *files_from = NULL; + int null_names = 0; assert (sizeof (struct ustar_raw_header) == 512); @@ -181,6 +189,8 @@ case oQuiet: opt.quiet = 1; break; case oVerbose: opt.verbose++; break; case oNoVerbose: opt.verbose = 0; break; + case oFilesFrom: files_from = pargs.r.ret_str; break; + case oNull: null_names = 1; break; case aList: case aDecrypt: @@ -202,6 +212,11 @@ } } + if ((files_from && !null_names) || (!files_from && null_names)) + log_error ("--files-from and --null may only be used in conjunction\n"); + if (files_from && strcmp (files_from, "-")) + log_error ("--files-from only supports argument \"-\"\n"); + if (log_get_errorcount (0)) exit (2); @@ -213,6 +228,8 @@ fname = argc ? *argv : NULL; if (opt.filename) log_info ("note: ignoring option --set-filename\n"); + if (files_from) + log_info ("note: ignoring option --files-from\n"); if (skip_crypto) gpgtar_list (fname); else @@ -220,14 +237,15 @@ break; case aEncrypt: - if (!argc) + if ((!argc && !null_names) + || (argc && null_names)) usage (1); if (opt.filename) log_info ("note: ignoring option --set-filename\n"); if (skip_crypto) - gpgtar_create (argv); + gpgtar_create (null_names? NULL :argv); else - tar_and_encrypt (argv); + tar_and_encrypt (null_names? NULL : argv); break; case aDecrypt: @@ -235,6 +253,8 @@ usage (1); if (opt.outfile) log_info ("note: ignoring option --output\n"); + if (files_from) + log_info ("note: ignoring option --files-from\n"); fname = argc ? *argv : NULL; if (skip_crypto) gpgtar_extract (fname); From cvs at cvs.gnupg.org Mon Aug 9 11:36:50 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 09 Aug 2010 11:36:50 +0200 Subject: [svn] GnuPG - r5385 - trunk/tools Message-ID: Author: wk Date: 2010-08-09 11:36:49 +0200 (Mon, 09 Aug 2010) New Revision: 5385 Modified: trunk/tools/gpgtar.c Log: Add dummy options --cms and --openpgp. Modified: trunk/tools/gpgtar.c =================================================================== --- trunk/tools/gpgtar.c 2010-08-09 09:05:18 UTC (rev 5384) +++ trunk/tools/gpgtar.c 2010-08-09 09:36:49 UTC (rev 5385) @@ -60,6 +60,8 @@ aSignEncrypt, oSkipCrypto, + oOpenPGP, + oCMS, oSetFilename, aList, oNull @@ -89,8 +91,9 @@ ARGPARSE_s_s (oFilesFrom, "files-from", N_("|FILE|get names to create from FILE")), ARGPARSE_s_n (oNull, "null", N_("-T reads null-terminated names")), + ARGPARSE_s_n (oOpenPGP, "--openpgp", "@"), + ARGPARSE_s_n (oCMS, "--cms", "@"), - ARGPARSE_end () }; @@ -208,6 +211,9 @@ skip_crypto = 1; break; + case oOpenPGP: /* Dummy option for now. */ break; + case oCMS: /* Dummy option for now. */ break; + default: pargs.err = 2; break; } } From cvs at cvs.gnupg.org Mon Aug 9 12:35:46 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 09 Aug 2010 12:35:46 +0200 Subject: [svn] assuan - r381 - trunk Message-ID: Author: wk Date: 2010-08-09 12:35:46 +0200 (Mon, 09 Aug 2010) New Revision: 381 Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac Log: Release 2.0.1 Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-08-03 08:52:13 UTC (rev 380) +++ trunk/ChangeLog 2010-08-09 10:35:46 UTC (rev 381) @@ -1,3 +1,9 @@ +2010-08-09 Werner Koch + + Release 2.0.1 + + * configure.ac: Set LT version to C1/A1/R0. + 2010-04-20 Werner Koch * configure.ac: Change wording of the no-funopen warning. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-08-03 08:52:13 UTC (rev 380) +++ trunk/NEWS 2010-08-09 10:35:46 UTC (rev 381) @@ -1,8 +1,6 @@ -Noteworthy changes in version 2.0.1 (unreleased) +Noteworthy changes in version 2.0.1 (2010-08-09) ------------------------------------------------ - Under development: - * Support for WindowsCE. * Input and output notification handler can now really access the Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-08-03 08:52:13 UTC (rev 380) +++ trunk/configure.ac 2010-08-09 10:35:46 UTC (rev 381) @@ -25,7 +25,7 @@ # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. m4_define([my_version], [2.0.1]) -m4_define([my_issvn], [yes]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $( (svn info 2>/dev/null \ || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) @@ -38,10 +38,8 @@ # (Interfaces added: AGE++) # (Interfaces removed/changed: AGE=0) # -LIBASSUAN_LT_CURRENT=0 -# Subtract 2 from this value if you want to make the LFS transition an -# ABI break. [Note to self: Remove this comment with the next regular break.] -LIBASSUAN_LT_AGE=0 +LIBASSUAN_LT_CURRENT=1 +LIBASSUAN_LT_AGE=1 LIBASSUAN_LT_REVISION=0 # If the API is changed in an incompatible way: increment the next counter. From cvs at cvs.gnupg.org Mon Aug 9 12:48:14 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 09 Aug 2010 12:48:14 +0200 Subject: [svn] assuan - r382 - tags Message-ID: Author: wk Date: 2010-08-09 12:48:13 +0200 (Mon, 09 Aug 2010) New Revision: 382 Added: tags/libassuan-2.0.1/ Log: From cvs at cvs.gnupg.org Mon Aug 9 12:48:47 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 09 Aug 2010 12:48:47 +0200 Subject: [svn] assuan - r383 - trunk Message-ID: Author: wk Date: 2010-08-09 12:48:47 +0200 (Mon, 09 Aug 2010) New Revision: 383 Modified: trunk/NEWS trunk/configure.ac Log: Post release updates. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-08-09 10:48:13 UTC (rev 382) +++ trunk/NEWS 2010-08-09 10:48:47 UTC (rev 383) @@ -1,3 +1,7 @@ +Noteworthy changes in version 2.0.2 +------------------------------------------------ + + Noteworthy changes in version 2.0.1 (2010-08-09) ------------------------------------------------ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-08-09 10:48:13 UTC (rev 382) +++ trunk/configure.ac 2010-08-09 10:48:47 UTC (rev 383) @@ -24,8 +24,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [2.0.1]) -m4_define([my_issvn], [no]) +m4_define([my_version], [2.0.2]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $( (svn info 2>/dev/null \ || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) From cvs at cvs.gnupg.org Mon Aug 9 17:40:31 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 09 Aug 2010 17:40:31 +0200 Subject: [svn] GnuPG - r5386 - in trunk: . agent common tools Message-ID: Author: wk Date: 2010-08-09 17:40:29 +0200 (Mon, 09 Aug 2010) New Revision: 5386 Modified: trunk/ChangeLog trunk/agent/ChangeLog trunk/agent/Makefile.am trunk/autogen.sh trunk/common/ChangeLog trunk/common/logging.c trunk/configure.ac trunk/tools/ChangeLog trunk/tools/watchgnupg.c Log: Support logging via TCP Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-08-09 09:36:49 UTC (rev 5385) +++ trunk/ChangeLog 2010-08-09 15:40:29 UTC (rev 5386) @@ -1,3 +1,7 @@ +2010-08-09 Werner Koch + + * configure.ac (inet_pton): Check for it. + 2010-08-05 Werner Koch * configure.ac (AH_BOTTOM): Remove HTTP_USE_ESTREAM. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2010-08-09 09:36:49 UTC (rev 5385) +++ trunk/agent/ChangeLog 2010-08-09 15:40:29 UTC (rev 5386) @@ -1,3 +1,8 @@ +2010-08-09 Werner Koch + + * Makefile.am (t_common_ldadd): Add NETLIBS for sake of the TCP + logging. + 2010-06-24 Werner Koch * genkey.c (check_passphrase_pattern): Use HANG option for Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-08-09 09:36:49 UTC (rev 5385) +++ trunk/common/ChangeLog 2010-08-09 15:40:29 UTC (rev 5386) @@ -1,3 +1,10 @@ +2010-08-09 Werner Koch + + * logging.c (WITH_IPV6): New macro. + (parse_portno): New. From libassuan. + (fun_writer): Support TCP logging on all platforms. + (sock_close): New. + 2010-08-06 Werner Koch * homedir.c (dirmngr_socket_name) [W32CE]: Base on default homedir. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2010-08-09 09:36:49 UTC (rev 5385) +++ trunk/tools/ChangeLog 2010-08-09 15:40:29 UTC (rev 5386) @@ -1,5 +1,8 @@ 2010-08-09 Werner Koch + * watchgnupg.c: Inlcude in.h and inet.h. + (main): Support tcp connections. + * gpgtar.c (main): Add options -T and --null. * gpgtar-create.c (gpgtar_create): Implement option --null. Modified: trunk/agent/Makefile.am =================================================================== --- trunk/agent/Makefile.am 2010-08-09 09:36:49 UTC (rev 5385) +++ trunk/agent/Makefile.am 2010-08-09 15:40:29 UTC (rev 5386) @@ -105,8 +105,8 @@ # TESTS = t-protect -t_common_ldadd = $(common_libs) \ - $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) +t_common_ldadd = $(common_libs) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \ + $(LIBINTL) $(LIBICONV) $(NETLIBS) t_protect_SOURCES = t-protect.c protect.c t_protect_LDADD = $(t_common_ldadd) Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2010-08-09 09:36:49 UTC (rev 5385) +++ trunk/autogen.sh 2010-08-09 15:40:29 UTC (rev 5386) @@ -267,5 +267,5 @@ $AUTOCONF${FORCE} echo "You may now run: - ./configure --sysconfdir=/etc --enable-maintainer-mode --enable-symcryptrun --enable-mailto && make + ./configure --sysconfdir=/etc --enable-maintainer-mode --enable-symcryptrun --enable-mailto --enable-gpgtar && make " Modified: trunk/common/logging.c =================================================================== --- trunk/common/logging.c 2010-08-09 09:36:49 UTC (rev 5385) +++ trunk/common/logging.c 2010-08-09 15:40:29 UTC (rev 5386) @@ -29,16 +29,19 @@ #include #include #include -#ifndef HAVE_W32_SYSTEM +#ifdef HAVE_W32_SYSTEM +# include +#else /*!HAVE_W32_SYSTEM*/ # include # include -#endif /*HAVE_W32_SYSTEM*/ +# include +# include +#endif /*!HAVE_W32_SYSTEM*/ #include #include #include - #define JNLIB_NEED_LOG_LOGV 1 #define JNLIB_NEED_AFLOCAL 1 #include "libjnlib-config.h" @@ -56,7 +59,23 @@ # define isatty(a) (0) #endif +#undef WITH_IPV6 +#if defined (AF_INET6) && defined(PF_INET) \ + && defined (INET6_ADDRSTRLEN) && defined(HAVE_INET_PTON) +# define WITH_IPV6 1 +#endif +#ifndef EAFNOSUPPORT +# define EAFNOSUPPORT EINVAL +#endif + +#ifdef HAVE_W32_SYSTEM +#define sock_close(a) closesocket(a) +#else +#define sock_close(a) close(a) +#endif + + static estream_t logstream; static int log_socket = -1; static char prefix_buffer[80]; @@ -109,7 +128,11 @@ while (nleft > 0) { +#ifdef HAVE_W32_SYSTEM + nwritten = send (fd, buf, nleft, 0); +#else nwritten = write (fd, buf, nleft); +#endif if (nwritten < 0 && errno == EINTR) continue; if (nwritten < 0) @@ -122,6 +145,27 @@ } +/* Returns true if STR represents a valid port number in decimal + notation and no garbage is following. */ +static int +parse_portno (const char *str, unsigned short *r_port) +{ + unsigned int value; + + for (value=0; *str && (*str >= '0' && *str <= '9'); str++) + { + value = value * 10 + (*str - '0'); + if (value > 65535) + return 0; + } + if (*str || !value) + return 0; + + *r_port = value; + return 1; +} + + static ssize_t fun_writer (void *cookie_arg, const void *buffer, size_t size) { @@ -134,12 +178,129 @@ processes often close stderr and by writing to file descriptor 2 we might send the log message to a file not intended for logging (e.g. a pipe or network connection). */ -#ifndef HAVE_W32_SYSTEM if (cookie->want_socket && cookie->fd == -1) { +#ifdef WITH_IPV6 + struct sockaddr_in6 srvr_addr_in6; +#endif + struct sockaddr_in srvr_addr_in; +#ifndef HAVE_W32_SYSTEM + struct sockaddr_un srvr_addr_un; +#endif + size_t addrlen; + struct sockaddr *srvr_addr = NULL; + unsigned short port = 0; + int af = AF_LOCAL; + int pf = PF_LOCAL; + const char *name = cookie->name; + /* Not yet open or meanwhile closed due to an error. */ cookie->is_socket = 0; - cookie->fd = socket (PF_LOCAL, SOCK_STREAM, 0); + + /* Check whether this is a TCP socket or a local socket. */ + if (!strncmp (name, "tcp://", 6) && name[6]) + { + name += 6; + af = AF_INET; + pf = PF_INET; + } +#ifndef HAVE_W32_SYSTEM + else if (!strncmp (name, "socket://", 9) && name[9]) + name += 9; +#endif + + if (af == AF_LOCAL) + { +#ifdef HAVE_W32_SYSTEM + addrlen = 0; +#else + memset (&srvr_addr, 0, sizeof srvr_addr); + srvr_addr_un.sun_family = af; + strncpy (srvr_addr_un.sun_path, + name, sizeof (srvr_addr_un.sun_path)-1); + srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path)-1] = 0; + srvr_addr = (struct sockaddr *)&srvr_addr_un; + addrlen = SUN_LEN (&srvr_addr_un); +#endif + } + else + { + char *addrstr, *p; + void *addrbuf = NULL; + + addrstr = jnlib_malloc (strlen (name) + 1); + if (!addrstr) + addrlen = 0; /* This indicates an error. */ + else if (*name == '[') + { + /* Check for IPv6 literal address. */ + strcpy (addrstr, name+1); + p = strchr (addrstr, ']'); + if (!p || p[1] != ':' || !parse_portno (p+2, &port)) + { + jnlib_set_errno (EINVAL); + addrlen = 0; + } + else + { + *p = 0; +#ifdef WITH_IPV6 + af = AF_INET6; + pf = PF_INET6; + memset (&srvr_addr_in6, 0, sizeof srvr_addr_in6); + srvr_addr_in6.sin6_family = af; + srvr_addr_in6.sin6_port = htons (port); + addrbuf = &srvr_addr_in6.sin6_addr; + srvr_addr = (struct sockaddr *)&srvr_addr_in6; + addrlen = sizeof srvr_addr_in6; +#else + jnlib_set_errno (EAFNOSUPPORT); + addrlen = 0; +#endif + } + } + else + { + /* Check for IPv4 literal address. */ + strcpy (addrstr, name); + p = strchr (addrstr, ':'); + if (!p || !parse_portno (p+1, &port)) + { + jnlib_set_errno (EINVAL); + addrlen = 0; + } + else + { + *p = 0; + memset (&srvr_addr_in, 0, sizeof srvr_addr_in); + srvr_addr_in.sin_family = af; + srvr_addr_in.sin_port = htons (port); + addrbuf = &srvr_addr_in.sin_addr; + srvr_addr = (struct sockaddr *)&srvr_addr_in; + addrlen = sizeof srvr_addr_in; + } + } + + if (addrlen) + { +#ifdef HAVE_INET_PTON + if (inet_pton (af, addrstr, addrbuf) != 1) + addrlen = 0; +#else /*!HAVE_INET_PTON*/ + /* We need to use the old function. If we are here v6 + support isn't enabled anyway and thus we can do fine + without. Note that Windows has a compatible inet_pton + function named inetPton, but only since Vista. */ + srvr_addr_in.sin_addr.s_addr = inet_addr (addrstr); + if (srvr_addr_in.sin_addr.s_addr == INADDR_NONE) + addrlen = 0; +#endif /*!HAVE_INET_PTON*/ + } + + jnlib_free (addrstr); + } + + cookie->fd = addrlen? socket (pf, SOCK_STREAM, 0) : -1; if (cookie->fd == -1) { if (!cookie->quiet && !running_detached @@ -149,22 +310,13 @@ } else { - struct sockaddr_un addr; - size_t addrlen; - - memset (&addr, 0, sizeof addr); - addr.sun_family = PF_LOCAL; - strncpy (addr.sun_path, cookie->name, sizeof (addr.sun_path)-1); - addr.sun_path[sizeof (addr.sun_path)-1] = 0; - addrlen = SUN_LEN (&addr); - - if (connect (cookie->fd, (struct sockaddr *) &addr, addrlen) == -1) + if (connect (cookie->fd, srvr_addr, addrlen) == -1) { if (!cookie->quiet && !running_detached && isatty (es_fileno (es_stderr))) es_fprintf (es_stderr, "can't connect to `%s': %s\n", cookie->name, strerror(errno)); - close (cookie->fd); + sock_close (cookie->fd); cookie->fd = -1; } } @@ -174,9 +326,9 @@ if (!running_detached) { /* Due to all the problems with apps not running - detached but being called with stderr closed or - used for a different purposes, it does not make - sense to switch to stderr. We therefore disable it. */ + detached but being called with stderr closed or used + for a different purposes, it does not make sense to + switch to stderr. We therefore disable it. */ if (!cookie->quiet) { /* fputs ("switching logging to stderr\n", stderr);*/ @@ -191,12 +343,11 @@ cookie->is_socket = 1; } } -#endif /*HAVE_W32_SYSTEM*/ - + log_socket = cookie->fd; if (cookie->fd != -1 && !writen (cookie->fd, buffer, size)) return (ssize_t)size; /* Okay. */ - + if (!running_detached && cookie->fd != -1 && isatty (es_fileno (es_stderr))) { @@ -209,11 +360,11 @@ } if (cookie->is_socket && cookie->fd != -1) { - close (cookie->fd); + sock_close (cookie->fd); cookie->fd = -1; log_socket = -1; } - + return (ssize_t)size; } @@ -224,7 +375,7 @@ struct fun_cookie_s *cookie = cookie_arg; if (cookie->fd != -1 && cookie->fd != 2) - close (cookie->fd); + sock_close (cookie->fd); jnlib_free (cookie); log_socket = -1; return 0; @@ -254,18 +405,13 @@ fd = es_fileno (es_stderr); } + want_socket = 0; + if (name && !strncmp (name, "tcp://", 6) && name[6]) + want_socket = 1; #ifndef HAVE_W32_SYSTEM - if (name) - { - want_socket = (!strncmp (name, "socket://", 9) && name[9]); - if (want_socket) - name += 9; - } - else + else if (name && !strncmp (name, "socket://", 9) && name[9]) + want_socket = 2; #endif /*HAVE_W32_SYSTEM*/ - { - want_socket = 0; - } /* Setup a new stream. */ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-08-09 09:36:49 UTC (rev 5385) +++ trunk/configure.ac 2010-08-09 15:40:29 UTC (rev 5386) @@ -1203,7 +1203,7 @@ AC_CHECK_FUNCS([memicmp stpcpy strsep strlwr strtoul memmove stricmp strtol \ memrchr isascii timegm getrusage setrlimit stat setlocale \ flockfile funlockfile fopencookie funopen getpwnam getpwuid \ - getenv ]) + getenv inet_pton]) # end jnlib checks. Modified: trunk/tools/watchgnupg.c =================================================================== --- trunk/tools/watchgnupg.c 2010-08-09 09:36:49 UTC (rev 5385) +++ trunk/tools/watchgnupg.c 2010-08-09 15:40:29 UTC (rev 5386) @@ -30,6 +30,8 @@ #include #include #include +#include +#include #include #include @@ -40,7 +42,7 @@ #define MYVERSION_LINE PGM " (GnuPG) " VERSION #define BUGREPORT_LINE "\nReport bugs to .\n" #else -#define MYVERSION_LINE PGM +#define MYVERSION_LINE PGM " (standalone build) " __DATE__ #define BUGREPORT_LINE "" #endif #if !defined(SUN_LEN) || !defined(PF_LOCAL) || !defined(AF_LOCAL) @@ -189,17 +191,19 @@ { fputs (MYVERSION_LINE "\n" "Copyright (C) 2004 Free Software Foundation, Inc.\n" - "This program comes with ABSOLUTELY NO WARRANTY.\n" - "This is free software, and you are welcome to redistribute it\n" - "under certain conditions. See the file COPYING for details.\n", + "License GPLv3+: " + "GNU GPL version 3 or later \n" + "This is free software: you are free to change and redistribute it.\n" + "There is NO WARRANTY, to the extent permitted by law.\n", stdout); - if (with_help) fputs ("\n" - "Usage: " PGM " [OPTIONS] SOCKETNAME\n" - "Open the local socket SOCKETNAME and display log messages\n" + "Usage: " PGM " [OPTIONS] SOCKETNAME|PORT\n" + "Open the local socket SOCKETNAME (or the TCP port PORT)\n" + "and display log messages\n" "\n" " --force delete an already existing socket file\n" + " --tcp listen on a TCP port instead of a local socket\n" " --verbose enable extra informational output\n" " --version print version of the program and exit\n" " --help display this help and exit\n" @@ -213,9 +217,13 @@ { int last_argc = -1; int force = 0; + int tcp = 0; - struct sockaddr_un srvr_addr; + struct sockaddr_un srvr_addr_un; + struct sockaddr_in srvr_addr_in; + struct sockaddr *srvr_addr = NULL; socklen_t addrlen; + unsigned short port; int server; int flags; client_t client_list = NULL; @@ -246,6 +254,11 @@ force = 1; argc--; argv++; } + else if (!strcmp (*argv, "--tcp")) + { + tcp = 1; + argc--; argv++; + } } if (argc != 1) @@ -254,13 +267,19 @@ exit (1); } + port = tcp? atoi (*argv) : 0; if (verbose) - fprintf (stderr, "opening socket `%s'\n", *argv); + { + if (tcp) + fprintf (stderr, "listening on port %hu\n", port); + else + fprintf (stderr, "opening socket `%s'\n", *argv); + } setvbuf (stdout, NULL, _IOLBF, 0); - server = socket (PF_LOCAL, SOCK_STREAM, 0); + server = socket (tcp? PF_INET : PF_LOCAL, SOCK_STREAM, 0); if (server == -1) die ("socket() failed: %s\n", strerror (errno)); @@ -273,24 +292,38 @@ if ( fcntl (server, F_SETFL, (flags | O_NONBLOCK)) == -1) die ("fcntl (F_SETFL) failed: %s\n", strerror (errno)); - - memset (&srvr_addr, 0, sizeof srvr_addr); - srvr_addr.sun_family = AF_LOCAL; - strncpy (srvr_addr.sun_path, *argv, sizeof (srvr_addr.sun_path) - 1); - srvr_addr.sun_path[sizeof (srvr_addr.sun_path) - 1] = 0; - addrlen = SUN_LEN (&srvr_addr); - + if (tcp) + { + memset (&srvr_addr_in, 0, sizeof srvr_addr_in); + srvr_addr_in.sin_family = AF_INET; + srvr_addr_in.sin_port = htons (port); + srvr_addr_in.sin_addr.s_addr = htonl (INADDR_ANY); + srvr_addr = (struct sockaddr *)&srvr_addr_in; + addrlen = sizeof srvr_addr_in; + } + else + { + memset (&srvr_addr_un, 0, sizeof srvr_addr_un); + srvr_addr_un.sun_family = AF_LOCAL; + strncpy (srvr_addr_un.sun_path, *argv, sizeof (srvr_addr_un.sun_path)-1); + srvr_addr_un.sun_path[sizeof (srvr_addr_un.sun_path) - 1] = 0; + srvr_addr = (struct sockaddr *)&srvr_addr_un; + addrlen = SUN_LEN (&srvr_addr_un); + } again: - if (bind (server, (struct sockaddr *) &srvr_addr, addrlen)) + if (bind (server, srvr_addr, addrlen)) { - if (errno == EADDRINUSE && force) + if (!tcp && errno == EADDRINUSE && force) { force = 0; - remove (srvr_addr.sun_path); + remove (srvr_addr_un.sun_path); goto again; } - die ("bind to `%s' failed: %s\n", *argv, strerror (errno)); + if (tcp) + die ("bind to port %hu failed: %s\n", port, strerror (errno)); + else + die ("bind to `%s' failed: %s\n", *argv, strerror (errno)); } if (listen (server, 5)) From cvs at cvs.gnupg.org Tue Aug 10 16:27:46 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 10 Aug 2010 16:27:46 +0200 Subject: [svn] GnuPG - r5387 - trunk Message-ID: Author: wk Date: 2010-08-10 16:27:45 +0200 (Tue, 10 Aug 2010) New Revision: 5387 Modified: trunk/configure.ac Log: Print a note about wldap32 Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-08-09 15:40:29 UTC (rev 5386) +++ trunk/configure.ac 2010-08-10 14:27:45 UTC (rev 5387) @@ -1569,8 +1569,16 @@ *** You need a LDAP library to build this program. *** Check out *** http://www.openldap.org -*** for a suitable implementation. +*** for a suitable implementation. ***]]) + if test "$have_w32ce_system" = yes; then + AC_MSG_NOTICE([[ +*** Note that CeGCC might be broken, a package fixing this is: +*** http://files.kolab.org/local/windows-ce/ +*** source/wldap32_0.1-mingw32ce.orig.tar.gz +*** binary/wldap32-ce-arm-dev_0.1-1_all.deb +***]]) + fi fi if test "$missing_pth" = "yes"; then AC_MSG_NOTICE([[ From cvs at cvs.gnupg.org Wed Aug 11 12:20:54 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 11 Aug 2010 12:20:54 +0200 Subject: [svn] GnuPG - r5388 - trunk/tools Message-ID: Author: wk Date: 2010-08-11 12:20:53 +0200 (Wed, 11 Aug 2010) New Revision: 5388 Modified: trunk/tools/ChangeLog trunk/tools/gpgtar-create.c Log: Support "-" for --output. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2010-08-10 14:27:45 UTC (rev 5387) +++ trunk/tools/ChangeLog 2010-08-11 10:20:53 UTC (rev 5388) @@ -1,3 +1,8 @@ +2010-08-11 Werner Koch + + * gpgtar-create.c (gpgtar_create): Allow "-" for stdout in + opt.outfile. Switch es_stdout to binary mode. + 2010-08-09 Werner Koch * watchgnupg.c: Inlcude in.h and inet.h. Modified: trunk/tools/gpgtar-create.c =================================================================== --- trunk/tools/gpgtar-create.c 2010-08-10 14:27:45 UTC (rev 5387) +++ trunk/tools/gpgtar-create.c 2010-08-11 10:20:53 UTC (rev 5388) @@ -843,7 +843,10 @@ if (opt.outfile) { - outstream = es_fopen (opt.outfile, "wb"); + if (!strcmp (opt.outfile, "-")) + outstream = es_stdout; + else + outstream = es_fopen (opt.outfile, "wb"); if (!outstream) { err = gpg_error_from_syserror (); @@ -857,6 +860,9 @@ outstream = es_stdout; } + if (outstream == es_stdout) + es_set_binary (es_stdout); + for (hdr = scanctrl->flist; hdr; hdr = hdr->next) { err = write_file (outstream, hdr); From cvs at cvs.gnupg.org Wed Aug 11 15:06:36 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 11 Aug 2010 15:06:36 +0200 Subject: [svn] GnuPG - r5389 - branches/STABLE-BRANCH-2-0/agent Message-ID: Author: wk Date: 2010-08-11 15:06:35 +0200 (Wed, 11 Aug 2010) New Revision: 5389 Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog branches/STABLE-BRANCH-2-0/agent/call-scd.c Log: Pass on comment lines from scdaemon. Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-08-11 10:20:53 UTC (rev 5388) +++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-08-11 13:06:35 UTC (rev 5389) @@ -1,3 +1,9 @@ +2010-08-11 Werner Koch + + * call-scd.c (agent_card_scd): Pass assuan comment lines to the + caller. + (ASSUAN_CONVEY_COMMENTS): Provide replacement if needed. + 2010-05-12 Werner Koch * preset-passphrase.c (forget_passphrase): Actually implement Modified: branches/STABLE-BRANCH-2-0/agent/call-scd.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/call-scd.c 2010-08-11 10:20:53 UTC (rev 5388) +++ branches/STABLE-BRANCH-2-0/agent/call-scd.c 2010-08-11 13:06:35 UTC (rev 5389) @@ -42,6 +42,15 @@ #define MAX_OPEN_FDS 20 #endif +/* This Assuan flag is only available since libassuan 2.0.2. Because + comments lines are comments anyway we can use a replacement which + might not do anything. assuan_{g,s}et_flag don't return an error + thus there won't be any ABI problem. */ +#ifndef ASSUAN_CONVEY_COMMENTS +#define ASSUAN_CONVEY_COMMENTS 4 +#endif + + /* Definition of module local data of the CTRL structure. */ struct scd_local_s { @@ -1129,6 +1138,7 @@ { int rc; struct inq_needpin_s inqparm; + int saveflag; rc = start_scd (ctrl); if (rc) @@ -1138,10 +1148,13 @@ inqparm.getpin_cb = getpin_cb; inqparm.getpin_cb_arg = getpin_cb_arg; inqparm.passthru = assuan_context; + saveflag = assuan_get_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS); + assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, 1); rc = assuan_transact (ctrl->scd_local->ctx, cmdline, pass_data_thru, assuan_context, inq_needpin, &inqparm, pass_status_thru, assuan_context); + assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, saveflag); if (rc) { return unlock_scd (ctrl, rc); From cvs at cvs.gnupg.org Wed Aug 11 15:10:09 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 11 Aug 2010 15:10:09 +0200 Subject: [svn] assuan - r384 - in trunk: . doc src Message-ID: Author: wk Date: 2010-08-11 15:10:08 +0200 (Wed, 11 Aug 2010) New Revision: 384 Modified: trunk/NEWS trunk/doc/assuan.texi trunk/src/ChangeLog trunk/src/assuan-defs.h trunk/src/assuan-pipe-connect.c trunk/src/assuan-socket-connect.c trunk/src/assuan.h.in trunk/src/client.c trunk/src/context.c Log: Add ASSUAN_CONVEY_COMMENTS flag. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-08-09 10:48:47 UTC (rev 383) +++ trunk/src/ChangeLog 2010-08-11 13:10:08 UTC (rev 384) @@ -1,3 +1,17 @@ +2010-08-11 Werner Koch + + * assuan.h.in (ASSUAN_CONVEY_COMMENTS): New. + * assuan-defs.h (struct assuan_context_s): Add flags.CONVEY_COMMENTS. + * context.c (assuan_set_flag, assuan_get_flag): Support this flag. + (_assuan_read_from_server): Add arg CONVEY_COMMENTS. Change all + callers. + * client.c (assuan_transact): Implement new flags. + +2010-08-09 Werner Koch + + * assuan-socket-connect.c (assuan_socket_connect): Fix ipv6 + literal IP case. + 2010-08-03 Marcus Brinkmann * gpgcedev.c (GPGCEDEV_IOCTL_ASSIGN_RVID): New call ASSIGN_RVID. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-08-09 10:48:47 UTC (rev 383) +++ trunk/NEWS 2010-08-11 13:10:08 UTC (rev 384) @@ -1,7 +1,14 @@ Noteworthy changes in version 2.0.2 ------------------------------------------------ + * A new flag may now be used to convey comments via assuan_transact. + * Interface changes relative to the 2.0.1 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ASSUAN_CONVEY_COMMENTS NEW. + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Noteworthy changes in version 2.0.1 (2010-08-09) ------------------------------------------------ Modified: trunk/doc/assuan.texi =================================================================== --- trunk/doc/assuan.texi 2010-08-09 10:48:47 UTC (rev 383) +++ trunk/doc/assuan.texi 2010-08-11 13:10:08 UTC (rev 384) @@ -251,7 +251,7 @@ @item S @var{keyword} Informational output by the server, still processing the request. A client may not send such lines to the server while processing an Inquiry -command. +command. @var{keyword} shall start with a letter or an underscore. @item # Comment line issued only for debugging purposes. Totally ignored. Modified: trunk/src/assuan-defs.h =================================================================== --- trunk/src/assuan-defs.h 2010-08-09 10:48:47 UTC (rev 383) +++ trunk/src/assuan-defs.h 2010-08-11 13:10:08 UTC (rev 384) @@ -87,6 +87,7 @@ unsigned int no_waitpid : 1; unsigned int confidential : 1; unsigned int no_fixsignals : 1; + unsigned int convey_comments : 1; } flags; /* If set, this is called right before logging an I/O line. */ @@ -281,7 +282,8 @@ /*-- client.c --*/ gpg_error_t _assuan_read_from_server (assuan_context_t ctx, - assuan_response_t *okay, int *off); + assuan_response_t *okay, int *off, + int convey_comments); /*-- assuan-error.c --*/ Modified: trunk/src/assuan-pipe-connect.c =================================================================== --- trunk/src/assuan-pipe-connect.c 2010-08-09 10:48:47 UTC (rev 383) +++ trunk/src/assuan-pipe-connect.c 2010-08-11 13:10:08 UTC (rev 384) @@ -96,7 +96,7 @@ int off; gpg_error_t err; - err = _assuan_read_from_server (ctx, &response, &off); + err = _assuan_read_from_server (ctx, &response, &off, 0); if (err) TRACE1 (ctx, ASSUAN_LOG_SYSIO, "initial_handshake", ctx, "can't connect server: %s", gpg_strerror (err)); Modified: trunk/src/assuan-socket-connect.c =================================================================== --- trunk/src/assuan-socket-connect.c 2010-08-09 10:48:47 UTC (rev 383) +++ trunk/src/assuan-socket-connect.c 2010-08-11 13:10:08 UTC (rev 384) @@ -100,7 +100,7 @@ file:// - This is the same as the defualt just with an explicit schemata. + This is the same as the default just with an explicit schemata. assuan://: assuan://[]: @@ -175,7 +175,7 @@ if (!addrstr) return _assuan_error (ctx, gpg_err_code_from_syserror ()); - if (*addrstr == '[') + if (*name == '[') { strcpy (addrstr, name+1); p = strchr (addrstr, ']'); @@ -276,7 +276,7 @@ assuan_response_t response; int off; - err = _assuan_read_from_server (ctx, &response, &off); + err = _assuan_read_from_server (ctx, &response, &off, 0); if (err) TRACE1 (ctx, ASSUAN_LOG_SYSIO, "assuan_socket_connect", ctx, "can't connect to server: %s\n", gpg_strerror (err)); Modified: trunk/src/assuan.h.in =================================================================== --- trunk/src/assuan.h.in 2010-08-09 10:48:47 UTC (rev 383) +++ trunk/src/assuan.h.in 2010-08-11 13:10:08 UTC (rev 384) @@ -161,6 +161,9 @@ #define ASSUAN_CONFIDENTIAL 2 /* This flag suppresses fix up of signal handlers for pipes. */ #define ASSUAN_NO_FIXSIGNALS 3 +/* This flag changes assuan_transact to return comment lines via the + status callback. The default is to skip comment lines. */ +#define ASSUAN_CONVEY_COMMENTS 4 /* For context CTX, set the flag FLAG to VALUE. Values for flags are usually 1 or 0 but certain flags might allow for other values; Modified: trunk/src/client.c =================================================================== --- trunk/src/client.c 2010-08-09 10:48:47 UTC (rev 383) +++ trunk/src/client.c 2010-08-11 13:10:08 UTC (rev 384) @@ -195,7 +195,7 @@ gpg_error_t _assuan_read_from_server (assuan_context_t ctx, assuan_response_t *response, - int *off) + int *off, int convey_comments) { gpg_error_t rc; char *line; @@ -209,7 +209,7 @@ if (!rc) rc = assuan_client_parse_response (ctx, line, linelen, response, off); } - while (!rc && *response == ASSUAN_RESPONSE_COMMENT); + while (!rc && *response == ASSUAN_RESPONSE_COMMENT && !convey_comments); return rc; } @@ -258,7 +258,8 @@ return 0; /* Don't expect a response for a comment line. */ again: - rc = _assuan_read_from_server (ctx, &response, &off); + rc = _assuan_read_from_server (ctx, &response, &off, + ctx->flags.convey_comments); if (rc) return rc; /* error reading from server */ @@ -283,7 +284,7 @@ if (!inquire_cb) { assuan_write_line (ctx, "END"); /* get out of inquire mode */ - _assuan_read_from_server (ctx, &response, &off); /* dummy read */ + _assuan_read_from_server (ctx, &response, &off, 0); /* dummy read */ rc = _assuan_error (ctx, GPG_ERR_ASS_NO_INQUIRE_CB); } else @@ -302,6 +303,14 @@ if (!rc) goto again; } + else if (response == ASSUAN_RESPONSE_COMMENT && ctx->flags.convey_comments) + { + line -= off; /* Send line with the comment marker. */ + if (status_cb) + rc = status_cb (status_cb_arg, line); + if (!rc) + goto again; + } else if (response == ASSUAN_RESPONSE_END) { if (!data_cb) Modified: trunk/src/context.c =================================================================== --- trunk/src/context.c 2010-08-09 10:48:47 UTC (rev 383) +++ trunk/src/context.c 2010-08-11 13:10:08 UTC (rev 384) @@ -80,6 +80,10 @@ case ASSUAN_NO_FIXSIGNALS: ctx->flags.no_fixsignals = value; break; + + case ASSUAN_CONVEY_COMMENTS: + ctx->flags.convey_comments = value; + break; } } @@ -108,6 +112,10 @@ case ASSUAN_NO_FIXSIGNALS: res = ctx->flags.no_fixsignals; break; + + case ASSUAN_CONVEY_COMMENTS: + res = ctx->flags.convey_comments; + break; } return TRACE_SUC1 ("flag_value=%i", res); From cvs at cvs.gnupg.org Wed Aug 11 15:11:05 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 11 Aug 2010 15:11:05 +0200 Subject: [svn] GnuPG - r5390 - trunk/agent Message-ID: Author: wk Date: 2010-08-11 15:11:04 +0200 (Wed, 11 Aug 2010) New Revision: 5390 Modified: trunk/agent/ChangeLog trunk/agent/call-scd.c Log: Pass on comments from SCD. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2010-08-11 13:06:35 UTC (rev 5389) +++ trunk/agent/ChangeLog 2010-08-11 13:11:04 UTC (rev 5390) @@ -1,3 +1,9 @@ +2010-08-11 Werner Koch + + * call-scd.c (agent_card_scd): Pass assuan comment lines to the + caller. + (ASSUAN_CONVEY_COMMENTS): Provide replacement if needed. + 2010-08-09 Werner Koch * Makefile.am (t_common_ldadd): Add NETLIBS for sake of the TCP Modified: trunk/agent/call-scd.c =================================================================== --- trunk/agent/call-scd.c 2010-08-11 13:06:35 UTC (rev 5389) +++ trunk/agent/call-scd.c 2010-08-11 13:11:04 UTC (rev 5390) @@ -44,6 +44,15 @@ #define MAX_OPEN_FDS 20 #endif +/* This Assuan flag is only available since libassuan 2.0.2. Because + comments lines are comments anyway we can use a replacement which + might not do anything. assuan_{g,s}et_flag don't return an error + thus there won't be any ABI problem. */ +#ifndef ASSUAN_CONVEY_COMMENTS +#define ASSUAN_CONVEY_COMMENTS 4 +#endif + + /* Definition of module local data of the CTRL structure. */ struct scd_local_s { @@ -1121,6 +1130,7 @@ { int rc; struct inq_needpin_s inqparm; + int saveflag; rc = start_scd (ctrl); if (rc) @@ -1130,10 +1140,13 @@ inqparm.getpin_cb = getpin_cb; inqparm.getpin_cb_arg = getpin_cb_arg; inqparm.passthru = assuan_context; + saveflag = assuan_get_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS); + assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, 1); rc = assuan_transact (ctrl->scd_local->ctx, cmdline, pass_data_thru, assuan_context, inq_needpin, &inqparm, pass_status_thru, assuan_context); + assuan_set_flag (ctrl->scd_local->ctx, ASSUAN_CONVEY_COMMENTS, saveflag); if (rc) { return unlock_scd (ctrl, rc); From cvs at cvs.gnupg.org Wed Aug 11 16:01:11 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 11 Aug 2010 16:01:11 +0200 Subject: [svn] assuan - r385 - in trunk: doc src Message-ID: Author: wk Date: 2010-08-11 16:01:10 +0200 (Wed, 11 Aug 2010) New Revision: 385 Modified: trunk/doc/assuan.texi trunk/src/client.c trunk/src/context.c Log: doc changes Modified: trunk/doc/assuan.texi =================================================================== --- trunk/doc/assuan.texi 2010-08-11 13:10:08 UTC (rev 384) +++ trunk/doc/assuan.texi 2010-08-11 14:01:10 UTC (rev 385) @@ -822,9 +822,12 @@ not desirable. By setting this flag, a call to @code{waitpid} will be suppressed and the caller is responsible to cleanup the child process. @item ASSUAN_CONFIDENTIAL -Uses to return the state of the confidential logging mode. +Use to return the state of the confidential logging mode. @item ASSUAN_NO_FIXSIGNALS Do not modify signal handler for @code{SIGPIPE}. + at item ASSUAN_CONVEY_COMMENTS +If enabled comment lines are passed to the status callback of the + at code{assuan_transact}. @end table @end deftp @end deftypefun Modified: trunk/src/client.c =================================================================== --- trunk/src/client.c 2010-08-11 13:10:08 UTC (rev 384) +++ trunk/src/client.c 2010-08-11 14:01:10 UTC (rev 385) @@ -228,11 +228,10 @@ * * FIXME: Write documentation * - * Return value: 0 on success or error code. The error code may be - * the one one returned by the server in error lines or from the - * callback functions. Take care: When a callback returns an error - * this function returns immediately with an error and thus the caller - * will altter return an Assuan error (write erro in most cases). + * Return value: 0 on success or an error code. The error code may be + * the one one returned by the server via error lines or from the + * callback functions. Take care: If a callback returns an error + * this function returns immediately with this error. **/ gpg_error_t assuan_transact (assuan_context_t ctx, Modified: trunk/src/context.c =================================================================== --- trunk/src/context.c 2010-08-11 13:10:08 UTC (rev 384) +++ trunk/src/context.c 2010-08-11 14:01:10 UTC (rev 385) @@ -122,7 +122,7 @@ } -/* Same as assuan_set_flag (ctx, ASSUAN_NO_WAITPID, 1). */ +/* Same as assuan_set_flag (ctx, ASSUAN_CONFIDENTIAL, 1). */ void assuan_begin_confidential (assuan_context_t ctx) { @@ -130,7 +130,7 @@ } -/* Same as assuan_set_flag (ctx, ASSUAN_NO_WAITPID, 0). */ +/* Same as assuan_set_flag (ctx, ASSUAN_CONFIDENTIAL, 0). */ void assuan_end_confidential (assuan_context_t ctx) { From cvs at cvs.gnupg.org Wed Aug 11 16:17:26 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 11 Aug 2010 16:17:26 +0200 Subject: [svn] GnuPG - r5391 - in branches/STABLE-BRANCH-2-0: . agent g10 Message-ID: Author: wk Date: 2010-08-11 16:17:25 +0200 (Wed, 11 Aug 2010) New Revision: 5391 Modified: branches/STABLE-BRANCH-2-0/NEWS branches/STABLE-BRANCH-2-0/agent/ChangeLog branches/STABLE-BRANCH-2-0/agent/call-pinentry.c branches/STABLE-BRANCH-2-0/announce.txt branches/STABLE-BRANCH-2-0/configure.ac branches/STABLE-BRANCH-2-0/g10/ChangeLog branches/STABLE-BRANCH-2-0/g10/mainproc.c Log: Pass on assuan comment lines from scd. Fix confidential flag setting. Print another status_error. Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-08-11 13:11:04 UTC (rev 5390) +++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-08-11 14:17:25 UTC (rev 5391) @@ -1,5 +1,8 @@ 2010-08-11 Werner Koch + * call-pinentry.c (agent_askpin, agent_get_passphrase): Fix + setting of confidential flag. + * call-scd.c (agent_card_scd): Pass assuan comment lines to the caller. (ASSUAN_CONVEY_COMMENTS): Provide replacement if needed. Modified: branches/STABLE-BRANCH-2-0/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-08-11 13:11:04 UTC (rev 5390) +++ branches/STABLE-BRANCH-2-0/g10/ChangeLog 2010-08-11 14:17:25 UTC (rev 5391) @@ -1,3 +1,8 @@ +2010-07-20 Werner Koch + + * mainproc.c (print_pkenc_list): Print a STATUS_ERROR. Fixes + bug#1255. + 2010-06-18 Werner Koch * parse-packet.c (skip_packet, parse_gpg_control): Take care of Modified: branches/STABLE-BRANCH-2-0/NEWS =================================================================== --- branches/STABLE-BRANCH-2-0/NEWS 2010-08-11 13:11:04 UTC (rev 5390) +++ branches/STABLE-BRANCH-2-0/NEWS 2010-08-11 14:17:25 UTC (rev 5391) @@ -1,3 +1,7 @@ +Noteworthy changes in version 2.0.17 (unreleased) +------------------------------------------------- + + Noteworthy changes in version 2.0.16 (2010-07-19) ------------------------------------------------- @@ -4,8 +8,8 @@ * If the agent's --use-standard-socket option is active, all tools try to start and daemonize the agent on the fly. In the past this was only supported on W32; on non-W32 systems the new configure - option --use-standard-socket may now be used to use this feature by - default. + option --enable-standard-socket may now be used to use this feature + by default. * The gpg-agent commands KILLAGENT and RELOADAGENT are now available on all platforms. Modified: branches/STABLE-BRANCH-2-0/agent/call-pinentry.c =================================================================== --- branches/STABLE-BRANCH-2-0/agent/call-pinentry.c 2010-08-11 13:11:04 UTC (rev 5390) +++ branches/STABLE-BRANCH-2-0/agent/call-pinentry.c 2010-08-11 14:17:25 UTC (rev 5391) @@ -705,6 +705,7 @@ struct entry_parm_s parm; const char *errtext = NULL; int is_pin = 0; + int saveflag; if (opt.batch) return 0; /* fixme: we should return BAD PIN */ @@ -782,8 +783,11 @@ errtext = NULL; } + saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); + assuan_begin_confidential (entry_ctx); rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, inq_quality, entry_ctx, NULL, NULL); + assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); /* Most pinentries out in the wild return the old Assuan error code for canceled which gets translated to an assuan Cancel error and not to the code for a user cancel. Fix this here. */ @@ -845,6 +849,7 @@ int rc; char line[ASSUAN_LINELENGTH]; struct entry_parm_s parm; + int saveflag; *retpass = NULL; if (opt.batch) @@ -895,9 +900,11 @@ if (!parm.buffer) return unlock_pinentry (out_of_core ()); + saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); assuan_begin_confidential (entry_ctx); rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, inq_quality, entry_ctx, NULL, NULL); + assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); /* Most pinentries out in the wild return the old Assuan error code for canceled which gets translated to an assuan Cancel error and not to the code for a user cancel. Fix this here. */ Modified: branches/STABLE-BRANCH-2-0/announce.txt =================================================================== --- branches/STABLE-BRANCH-2-0/announce.txt 2010-08-11 13:11:04 UTC (rev 5390) +++ branches/STABLE-BRANCH-2-0/announce.txt 2010-08-11 14:17:25 UTC (rev 5391) @@ -5,7 +5,7 @@ Hello! We are pleased to announce the availability of a new stable GnuPG-2 -release: Version 2.0.15. +release: Version 2.0.16. The GNU Privacy Guard (GnuPG) is GNU's tool for secure communication and data storage. It can be used to encrypt data, create digital @@ -31,12 +31,16 @@ What's New =========== - * New command --passwd for GPG. + * If the agent's --use-standard-socket option is active, all tools + try to start and daemonize the agent on the fly. In the past this + was only supported on W32; on non-W32 systems the new configure + option --use-standard-socket may now be used to use this feature by + default. - * Fixes a regression in 2.0.14 which prevented unprotection of new - or changed gpg-agent passphrases. + * The gpg-agent commands KILLAGENT and RELOADAGENT are now available + on all platforms. - * Uses libassuan 2.0 which is available as a DSO. + * Minor bug fixes. Getting the Software @@ -45,7 +49,7 @@ Please follow the instructions found at http://www.gnupg.org/download/ or read on: -GnuPG 2.0.15 may be downloaded from one of the GnuPG mirror sites or +GnuPG 2.0.16 may be downloaded from one of the GnuPG mirror sites or direct from ftp://ftp.gnupg.org/gcrypt/gnupg/ . The list of mirrors can be found at http://www.gnupg.org/mirrors.html . Note, that GnuPG is not available at ftp.gnu.org. @@ -53,14 +57,14 @@ On the FTP server and its mirrors you should find the following files in the gnupg/ directory: - gnupg-2.0.15.tar.bz2 (3884k) - gnupg-2.0.15.tar.bz2.sig + gnupg-2.0.16.tar.bz2 (3910k) + gnupg-2.0.16.tar.bz2.sig GnuPG source compressed using BZIP2 and OpenPGP signature. - gnupg-2.0.14-2.0.15.diff.bz2 (40k) + gnupg-2.0.15-2.0.16.diff.bz2 (51k) - A patch file to upgrade a 2.0.14 GnuPG source tree. This patch + A patch file to upgrade a 2.0.15 GnuPG source tree. This patch does not include updates of the language files. Note, that we don't distribute gzip compressed tarballs for GnuPG-2. @@ -75,9 +79,9 @@ * If you already have a trusted version of GnuPG installed, you can simply check the supplied signature. For example to check the - signature of the file gnupg-2.0.15.tar.bz2 you would use this command: + signature of the file gnupg-2.0.16.tar.bz2 you would use this command: - gpg --verify gnupg-2.0.15.tar.bz2.sig + gpg --verify gnupg-2.0.16.tar.bz2.sig This checks whether the signature file matches the source file. You should see a message indicating that the signature is good and @@ -101,15 +105,15 @@ * If you are not able to use an old version of GnuPG, you have to verify the SHA-1 checksum. Assuming you downloaded the file - gnupg-2.0.14.tar.bz2, you would run the sha1sum command like this: + gnupg-2.0.16.tar.bz2, you would run the sha1sum command like this: - sha1sum gnupg-2.0.15.tar.bz2 + sha1sum gnupg-2.0.16.tar.bz2 and check that the output matches the first line from the following list: -3596668fb9cc8ec0714463a5009f990fc23434b0 gnupg-2.0.15.tar.bz2 -ed35765ae081706c8856fd491201f4f9576135fd gnupg-2.0.14-2.0.15.diff.bz2 +e7eb4f60026884bd90803b531472bc518804b95d gnupg-2.0.16.tar.bz2 +be77c0ba597b9ad9e38941e85ba1750890067227 gnupg-2.0.15-2.0.16.diff.bz2 Internationalization Modified: branches/STABLE-BRANCH-2-0/configure.ac =================================================================== --- branches/STABLE-BRANCH-2-0/configure.ac 2010-08-11 13:11:04 UTC (rev 5390) +++ branches/STABLE-BRANCH-2-0/configure.ac 2010-08-11 14:17:25 UTC (rev 5391) @@ -24,8 +24,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [2.0.16]) -m4_define([my_issvn], [no]) +m4_define([my_version], [2.0.17]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) Modified: branches/STABLE-BRANCH-2-0/g10/mainproc.c =================================================================== --- branches/STABLE-BRANCH-2-0/g10/mainproc.c 2010-08-11 13:11:04 UTC (rev 5390) +++ branches/STABLE-BRANCH-2-0/g10/mainproc.c 2010-08-11 14:17:25 UTC (rev 5391) @@ -475,8 +475,11 @@ } } else if (list->reason) + { log_info(_("public key decryption failed: %s\n"), g10_errstr(list->reason)); + write_status_error ("pkdecrypt_failed", list->reason); + } } } From cvs at cvs.gnupg.org Thu Aug 12 13:43:47 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 12 Aug 2010 13:43:47 +0200 Subject: [svn] GnuPG - r5392 - in trunk: agent common dirmngr Message-ID: Author: wk Date: 2010-08-12 13:43:46 +0200 (Thu, 12 Aug 2010) New Revision: 5392 Modified: trunk/agent/ChangeLog trunk/agent/call-pinentry.c trunk/common/ChangeLog trunk/common/sysutils.c trunk/dirmngr/ChangeLog trunk/dirmngr/crlcache.c trunk/dirmngr/dirmngr.c trunk/dirmngr/dirmngr.h trunk/dirmngr/server.c Log: Fix dirmngr problems on CE. Add new dirmngr commands. Minor other fixes. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2010-08-11 14:17:25 UTC (rev 5391) +++ trunk/agent/ChangeLog 2010-08-12 11:43:46 UTC (rev 5392) @@ -1,5 +1,8 @@ 2010-08-11 Werner Koch + * call-pinentry.c (agent_get_passphrase, agent_askpin): Fix + setting of confidential flag. + * call-scd.c (agent_card_scd): Pass assuan comment lines to the caller. (ASSUAN_CONVEY_COMMENTS): Provide replacement if needed. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-08-11 14:17:25 UTC (rev 5391) +++ trunk/common/ChangeLog 2010-08-12 11:43:46 UTC (rev 5392) @@ -1,3 +1,7 @@ +2010-08-12 Werner Koch + + * sysutils.c (gnupg_remove) [W32CE]: Fix returned error. + 2010-08-09 Werner Koch * logging.c (WITH_IPV6): New macro. Modified: trunk/dirmngr/ChangeLog =================================================================== --- trunk/dirmngr/ChangeLog 2010-08-11 14:17:25 UTC (rev 5391) +++ trunk/dirmngr/ChangeLog 2010-08-12 11:43:46 UTC (rev 5392) @@ -1,3 +1,13 @@ +2010-08-12 Werner Koch + + * crlcache.c (update_dir, crl_cache_insert): s/unlink/gnupg_remove/. + + * dirmngr.c (dirmngr_sighup_action): New. + + * server.c (cmd_killdirmngr, cmd_reloaddirmngr): New. + (struct server_local_s): Add field STOPME. + (start_command_handler): Act on STOPME. + 2010-08-06 Werner Koch * dirmngr.c (JNLIB_NEED_AFLOCAL): Define macro. @@ -3,5 +13,4 @@ (main): Use SUN_LEN macro. (main) [W32]: Allow EEXIST in addition to EADDRINUSE. - (JNLIB_NEED_AFLOCAL): 2010-08-05 Werner Koch Modified: trunk/agent/call-pinentry.c =================================================================== --- trunk/agent/call-pinentry.c 2010-08-11 14:17:25 UTC (rev 5391) +++ trunk/agent/call-pinentry.c 2010-08-12 11:43:46 UTC (rev 5392) @@ -705,6 +705,7 @@ struct entry_parm_s parm; const char *errtext = NULL; int is_pin = 0; + int saveflag; if (opt.batch) return 0; /* fixme: we should return BAD PIN */ @@ -782,8 +783,11 @@ errtext = NULL; } + saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); + assuan_begin_confidential (entry_ctx); rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, inq_quality, entry_ctx, NULL, NULL); + assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); /* Most pinentries out in the wild return the old Assuan error code for canceled which gets translated to an assuan Cancel error and not to the code for a user cancel. Fix this here. */ @@ -845,6 +849,7 @@ int rc; char line[ASSUAN_LINELENGTH]; struct entry_parm_s parm; + int saveflag; *retpass = NULL; if (opt.batch) @@ -895,9 +900,11 @@ if (!parm.buffer) return unlock_pinentry (out_of_core ()); + saveflag = assuan_get_flag (entry_ctx, ASSUAN_CONFIDENTIAL); assuan_begin_confidential (entry_ctx); rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm, inq_quality, entry_ctx, NULL, NULL); + assuan_set_flag (entry_ctx, ASSUAN_CONFIDENTIAL, saveflag); /* Most pinentries out in the wild return the old Assuan error code for canceled which gets translated to an assuan Cancel error and not to the code for a user cancel. Fix this here. */ Modified: trunk/common/sysutils.c =================================================================== --- trunk/common/sysutils.c 2010-08-11 14:17:25 UTC (rev 5391) +++ trunk/common/sysutils.c 2010-08-12 11:43:46 UTC (rev 5392) @@ -530,8 +530,8 @@ xfree (wfname); } if (!rc) - gpg_err_set_errno (EIO); - return !rc; + return -1; /* ERRNO is automagically provided by gpg-error.h. */ + return 0; #else return remove (fname); #endif Modified: trunk/dirmngr/crlcache.c =================================================================== --- trunk/dirmngr/crlcache.c 2010-08-11 14:17:25 UTC (rev 5391) +++ trunk/dirmngr/crlcache.c 2010-08-12 11:43:46 UTC (rev 5392) @@ -274,7 +274,7 @@ if (okay) { log_info (_("removing cache file `%s'\n"), cdbname); - if (unlink (cdbname)) + if (gnupg_remove (cdbname)) { log_error ("failed to remove `%s': %s\n", cdbname, strerror (errno)); @@ -934,7 +934,7 @@ #ifdef HAVE_W32_SYSTEM /* No atomic mv on W32 systems. */ - unlink (fname); + gnupg_remove (fname); #endif if (rename (tmpfname, fname)) { @@ -2166,7 +2166,7 @@ if (opt.verbose) log_info (_("creating cache file `%s'\n"), newfname); #ifdef HAVE_W32_SYSTEM - unlink (newfname); + gnupg_remove (newfname); #endif if (rename (fname, newfname)) { Modified: trunk/dirmngr/dirmngr.c =================================================================== --- trunk/dirmngr/dirmngr.c 2010-08-11 14:17:25 UTC (rev 5391) +++ trunk/dirmngr/dirmngr.c 2010-08-12 11:43:46 UTC (rev 5392) @@ -1578,7 +1578,22 @@ } +/* A global function which allows us to trigger the reload stuff from + other places. */ +void +dirmngr_sighup_action (void) +{ + log_info (_("SIGHUP received - " + "re-reading configuration and flushing caches\n")); + reread_configuration (); + cert_cache_deinit (0); + crl_cache_deinit (); + cert_cache_init (); + crl_cache_init (); +} + + /* The signal handler. */ static void handle_signal (int signo) @@ -1587,13 +1602,7 @@ { #ifndef HAVE_W32_SYSTEM case SIGHUP: - log_info (_("SIGHUP received - " - "re-reading configuration and flushing caches\n")); - reread_configuration (); - cert_cache_deinit (0); - crl_cache_deinit (); - cert_cache_init (); - crl_cache_init (); + dirmngr_sighup_action (); break; case SIGUSR1: Modified: trunk/dirmngr/dirmngr.h =================================================================== --- trunk/dirmngr/dirmngr.h 2010-08-11 14:17:25 UTC (rev 5391) +++ trunk/dirmngr/dirmngr.h 2010-08-12 11:43:46 UTC (rev 5392) @@ -169,6 +169,7 @@ /*-- dirmngr.c --*/ void dirmngr_exit( int ); /* Wrapper for exit() */ void dirmngr_init_default_ctrl (ctrl_t ctrl); +void dirmngr_sighup_action (void); /*-- server.c --*/ ldap_server_t get_ldapservers_from_ctrl (ctrl_t ctrl); Modified: trunk/dirmngr/server.c =================================================================== --- trunk/dirmngr/server.c 2010-08-11 14:17:25 UTC (rev 5391) +++ trunk/dirmngr/server.c 2010-08-12 11:43:46 UTC (rev 5392) @@ -60,6 +60,10 @@ /* Per-session LDAP serfver. */ ldap_server_t ldapservers; + + /* If this flag is set to true this dirmngr process will be + terminated after the end of this session. */ + int stopme; }; @@ -1218,7 +1222,7 @@ "\n" "Put a certificate into the internal cache. This command might be\n" "useful if a client knows in advance certificates required for a\n" - "test and wnats to make sure they get added to the internal cache.\n" + "test and wants to make sure they get added to the internal cache.\n" "It is also helpful for debugging. To get the actual certificate,\n" "this command immediately inquires it using\n" "\n" @@ -1376,7 +1380,76 @@ } + +static const char hlp_killdirmngr[] = + "KILLDIRMNGR\n" + "\n" + "This command allows a user - given sufficient permissions -\n" + "to kill this dirmngr process.\n"; +static gpg_error_t +cmd_killdirmngr (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + (void)line; + + if (opt.system_daemon) + { + if (opt.system_service) + return set_error (GPG_ERR_NOT_SUPPORTED, + "can't do that whilst running as system service"); +#ifndef HAVE_W32_SYSTEM + { + gpg_err_code_t ec; + assuan_peercred_t cred; + + ec = gpg_err_code (assuan_get_peercred (ctx, &cred)); + if (!ec && cred.uid) + ec = GPG_ERR_EPERM; /* Only root may terminate. */ + if (ec) + return set_error (ec, "no permission to kill this process"); + } +#endif + } + + ctrl->server_local->stopme = 1; + return gpg_error (GPG_ERR_EOF); +} + + +static const char hlp_reloaddirmngr[] = + "RELOADDIRMNGR\n" + "\n" + "This command is an alternative to SIGHUP\n" + "to reload the configuration."; +static gpg_error_t +cmd_reloaddirmngr (assuan_context_t ctx, char *line) +{ + (void)ctx; + (void)line; + + if (opt.system_daemon) + { +#ifndef HAVE_W32_SYSTEM + { + gpg_err_code_t ec; + assuan_peercred_t cred; + + ec = gpg_err_code (assuan_get_peercred (ctx, &cred)); + if (!ec && cred.uid) + ec = GPG_ERR_EPERM; /* Only root may terminate. */ + if (ec) + return set_error (ec, "no permission to reload this process"); + } +#endif + } + + dirmngr_sighup_action (); + return 0; +} + + + /* Tell the assuan library about our commands. */ static int @@ -1397,6 +1470,8 @@ { "CACHECERT", cmd_cachecert, hlp_cachecert }, { "VALIDATE", cmd_validate, hlp_validate }, { "GETINFO", cmd_getinfo, hlp_getinfo }, + { "KILLDIRMNGR",cmd_killdirmngr,hlp_killdirmngr }, + { "RELOADDIRMNGR",cmd_reloaddirmngr,hlp_reloaddirmngr }, { NULL, NULL } }; int i, j, rc; @@ -1552,6 +1627,9 @@ ctrl->server_local->assuan_ctx = NULL; assuan_release (ctx); + if (ctrl->server_local->stopme) + dirmngr_exit (0); + if (ctrl->refcount) log_error ("oops: connection control structure still referenced (%d)\n", ctrl->refcount); From cvs at cvs.gnupg.org Thu Aug 12 18:57:14 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 12 Aug 2010 18:57:14 +0200 Subject: [svn] GnuPG - r5393 - trunk/dirmngr Message-ID: Author: wk Date: 2010-08-12 18:57:14 +0200 (Thu, 12 Aug 2010) New Revision: 5393 Modified: trunk/dirmngr/server.c Log: Fix last change Modified: trunk/dirmngr/server.c =================================================================== --- trunk/dirmngr/server.c 2010-08-12 11:43:46 UTC (rev 5392) +++ trunk/dirmngr/server.c 2010-08-12 16:57:14 UTC (rev 5393) @@ -1404,7 +1404,7 @@ assuan_peercred_t cred; ec = gpg_err_code (assuan_get_peercred (ctx, &cred)); - if (!ec && cred.uid) + if (!ec && cred->uid) ec = GPG_ERR_EPERM; /* Only root may terminate. */ if (ec) return set_error (ec, "no permission to kill this process"); @@ -1436,7 +1436,7 @@ assuan_peercred_t cred; ec = gpg_err_code (assuan_get_peercred (ctx, &cred)); - if (!ec && cred.uid) + if (!ec && cred->uid) ec = GPG_ERR_EPERM; /* Only root may terminate. */ if (ec) return set_error (ec, "no permission to reload this process"); From cvs at cvs.gnupg.org Fri Aug 13 12:02:13 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 13 Aug 2010 12:02:13 +0200 Subject: [svn] GnuPG - r5394 - in trunk: . dirmngr Message-ID: Author: wk Date: 2010-08-13 12:02:12 +0200 (Fri, 13 Aug 2010) New Revision: 5394 Added: trunk/dirmngr/w32-ldap-help.h Modified: trunk/autogen.sh trunk/dirmngr/ChangeLog trunk/dirmngr/dirmngr_ldap.c Log: Fixed LDAP access on CE Modified: trunk/dirmngr/ChangeLog =================================================================== --- trunk/dirmngr/ChangeLog 2010-08-12 16:57:14 UTC (rev 5393) +++ trunk/dirmngr/ChangeLog 2010-08-13 10:02:12 UTC (rev 5394) @@ -1,3 +1,11 @@ +2010-08-13 Werner Koch + + * dirmngr_ldap.c (fetch_ldap): Call ldap_unbind. + + * w32-ldap-help.h: New. + * dirmngr_ldap.c [W32CE]: Include w32-ldap-help.h and use the + mapped ldap functions. + 2010-08-12 Werner Koch * crlcache.c (update_dir, crl_cache_insert): s/unlink/gnupg_remove/. Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2010-08-12 16:57:14 UTC (rev 5393) +++ trunk/autogen.sh 2010-08-13 10:02:12 UTC (rev 5394) @@ -40,6 +40,8 @@ DIE=no FORCE= +tmp=`dirname $0` +tsdir=`cd "$tmp"; pwd` if test x"$1" = x"--force"; then FORCE=" --force" shift @@ -89,8 +91,6 @@ # ***** W32 build script ******* # Used to cross-compile for Windows. if [ "$myhost" = "w32" ]; then - tmp=`dirname $0` - tsdir=`cd "$tmp"; pwd` shift if [ ! -f $tsdir/scripts/config.guess ]; then echo "$tsdir/scripts/config.guess not found" >&2 @@ -140,7 +140,7 @@ fi fi - ./configure --enable-maintainer-mode --prefix=${w32root} \ + $tsdir/configure --enable-maintainer-mode --prefix=${w32root} \ --host=${host} --build=${build} \ --with-gpg-error-prefix=${w32root} \ --with-ksba-prefix=${w32root} \ @@ -159,8 +159,6 @@ # ***** AMD64 cross build script ******* # Used to cross-compile for AMD64 (for testing) if [ "$myhost" = "amd64" ]; then - tmp=`dirname $0` - tsdir=`cd "$tmp"; pwd` shift if [ ! -f $tsdir/scripts/config.guess ]; then echo "$tsdir/scripts/config.guess not found" >&2 Modified: trunk/dirmngr/dirmngr_ldap.c =================================================================== --- trunk/dirmngr/dirmngr_ldap.c 2010-08-12 16:57:14 UTC (rev 5393) +++ trunk/dirmngr/dirmngr_ldap.c 2010-08-13 10:02:12 UTC (rev 5394) @@ -1,21 +1,21 @@ /* dirmngr-ldap.c - The LDAP helper for dirmngr. - * Copyright (C) 2004 g10 Code GmbH + * Copyright (C) 2004 g10 Code GmbH + * Copyright (C) 2010 Free Software Foundation, Inc. * - * This file is part of DirMngr. + * This file is part of GnuPG. * - * DirMngr is free software; you can redistribute it and/or modify + * 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 + * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * - * DirMngr is distributed in the hope that it will be useful, + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * along with this program; if not, see . */ #include @@ -69,6 +69,33 @@ # include "./ldap-wrapper.h" #endif +#ifdef HAVE_W32CE_SYSTEM +# include "w32-ldap-help.h" +# define my_ldap_init(a,b) \ + _dirmngr_ldap_init ((a), (b)) +# define my_ldap_simple_bind_s(a,b,c) \ + _dirmngr_ldap_simple_bind_s ((a),(b),(c)) +# define my_ldap_search_st(a,b,c,d,e,f,g,h) \ + _dirmngr_ldap_search_st ((a), (b), (c), (d), (e), (f), (g), (h)) +# define my_ldap_first_attribute(a,b,c) \ + _dirmngr_ldap_first_attribute ((a),(b),(c)) +# define my_ldap_next_attribute(a,b,c) \ + _dirmngr_ldap_next_attribute ((a),(b),(c)) +# define my_ldap_get_values_len(a,b,c) \ + _dirmngr_ldap_get_values_len ((a),(b),(c)) +# define my_ldap_free_attr(a) \ + xfree ((a)) +#else +# define my_ldap_init(a,b) ldap_init ((a), (b)) +# define my_ldap_simple_bind_s(a,b,c) ldap_simple_bind_s ((a), (b), (c)) +# define my_ldap_search_st(a,b,c,d,e,f,g,h) \ + ldap_search_st ((a), (b), (c), (d), (e), (f), (g), (h)) +# define my_ldap_first_attribute(a,b,c) ldap_first_attribute ((a),(b),(c)) +# define my_ldap_next_attribute(a,b,c) ldap_next_attribute ((a),(b),(c)) +# define my_ldap_get_values_len(a,b,c) ldap_get_values_len ((a),(b),(c)) +# define my_ldap_free_attr(a) ldap_memfree ((a)) +#endif + #define DEFAULT_LDAP_TIMEOUT 100 /* Arbitrary long timeout. */ @@ -147,7 +174,9 @@ /* Prototypes. */ +#ifndef HAVE_W32_SYSTEM static void catch_alarm (int dummy); +#endif static int process_url (my_opt_t myopt, const char *url); @@ -200,6 +229,7 @@ int only_search_timeout = 0; struct my_opt_s my_opt_buffer; my_opt_t myopt = &my_opt_buffer; + char *malloced_buffer1 = NULL; memset (&my_opt_buffer, 0, sizeof my_opt_buffer); @@ -276,7 +306,13 @@ if (myopt->proxy) { - myopt->host = xstrdup (myopt->proxy); + malloced_buffer1 = xtrystrdup (myopt->proxy); + if (!malloced_buffer1) + { + log_error ("error copying string: %s\n", strerror (errno)); + return 1; + } + myopt->host = malloced_buffer1; p = strchr (myopt->host, ':'); if (p) { @@ -323,20 +359,19 @@ if (process_url (myopt, *argv)) any_err = 1; - - /* FIXME: Do we need to release stuff? */ + xfree (malloced_buffer1); return any_err; } - +#ifndef HAVE_W32_SYSTEM static void catch_alarm (int dummy) { (void)dummy; _exit (10); } +#endif - static void set_timeout (my_opt_t myopt) { @@ -379,10 +414,10 @@ } - for (pth_enter (), attr = ldap_first_attribute (ld, item, &berctx), + for (pth_enter (), attr = my_ldap_first_attribute (ld, item, &berctx), pth_leave (); attr; - pth_enter (), attr = ldap_next_attribute (ld, item, berctx), + pth_enter (), attr = my_ldap_next_attribute (ld, item, berctx), pth_leave ()) { struct berval **values; @@ -415,20 +450,20 @@ *cp2 = ';'; if (cmpres) { - ldap_memfree (attr); + my_ldap_free_attr (attr); continue; /* Not found: Try next attribute. */ } } pth_enter (); - values = ldap_get_values_len (ld, item, attr); + values = my_ldap_get_values_len (ld, item, attr); pth_leave (); if (!values) { if (myopt->verbose) log_info (_("attribute `%s' not found\n"), attr); - ldap_memfree (attr); + my_ldap_free_attr (attr); continue; } @@ -458,7 +493,7 @@ log_error (_("error writing to stdout: %s\n"), strerror (errno)); ldap_value_free_len (values); - ldap_memfree (attr); + my_ldap_free_attr (attr); ber_free (berctx, 0); return -1; } @@ -482,7 +517,7 @@ log_error (_("error writing to stdout: %s\n"), strerror (errno)); ldap_value_free_len (values); - ldap_memfree (attr); + my_ldap_free_attr (attr); ber_free (berctx, 0); return -1; } @@ -494,7 +529,7 @@ log_error (_("error writing to stdout: %s\n"), strerror (errno)); ldap_value_free_len (values); - ldap_memfree (attr); + my_ldap_free_attr (attr); ber_free (berctx, 0); return -1; } @@ -504,7 +539,7 @@ break; /* Print only the first value. */ } ldap_value_free_len (values); - ldap_memfree (attr); + my_ldap_free_attr (attr); if (want_attr || !myopt->multi) break; /* We only want to return the first attribute. */ } @@ -584,7 +619,7 @@ set_timeout (myopt); pth_enter (); - ld = ldap_init (host, port); + ld = my_ldap_init (host, port); pth_leave (); if (!ld) { @@ -593,23 +628,24 @@ return -1; } pth_enter (); - ret = ldap_simple_bind_s (ld, myopt->user, myopt->pass); + /* Fixme: Can we use MYOPT->user or is it shared with other theeads?. */ + ret = my_ldap_simple_bind_s (ld, myopt->user, myopt->pass); pth_leave (); if (ret) { log_error (_("binding to `%s:%d' failed: %s\n"), host, port, strerror (errno)); - /* FIXME: Need deinit (ld)? */ + ldap_unbind (ld); return -1; } set_timeout (myopt); pth_enter (); - rc = ldap_search_st (ld, dn, ludp->lud_scope, filter, - myopt->multi && !myopt->attr && ludp->lud_attrs? - ludp->lud_attrs:attrs, - 0, - &myopt->timeout, &msg); + rc = my_ldap_search_st (ld, dn, ludp->lud_scope, filter, + myopt->multi && !myopt->attr && ludp->lud_attrs? + ludp->lud_attrs:attrs, + 0, + &myopt->timeout, &msg); pth_leave (); if (rc == LDAP_SIZELIMIT_EXCEEDED && myopt->multi) { @@ -621,8 +657,12 @@ } else if (rc) { +#ifdef HAVE_W32CE_SYSTEM + log_error ("searching `%s' failed: %d\n", url, rc); +#else log_error (_("searching `%s' failed: %s\n"), url, ldap_err2string (rc)); +#endif if (rc != LDAP_NO_SUCH_OBJECT) { /* FIXME: Need deinit (ld)? */ @@ -634,7 +674,7 @@ rc = print_ldap_entries (myopt, ld, msg, myopt->multi? NULL:attr); ldap_msgfree (msg); - /* FIXME: Need deinit (ld)? */ + ldap_unbind (ld); return rc; } Added: trunk/dirmngr/w32-ldap-help.h =================================================================== --- trunk/dirmngr/w32-ldap-help.h (rev 0) +++ trunk/dirmngr/w32-ldap-help.h 2010-08-13 10:02:12 UTC (rev 5394) @@ -0,0 +1,169 @@ +/* w32-ldap-help.h - Map utf8 based API into a wchar_t API. + o* Copyright (C) 2010 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 3 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, see . + */ + +#ifndef W32_LDAP_HELP_H +#define W32_LDAP_HELP_H + +#ifndef HAVE_W32CE_SYSTEM +# error This is only required for W32CE. +#endif + + +static inline LDAP * +_dirmngr_ldap_init (const char *host, unsigned short port) +{ + LDAP *ld; + wchar_t *whost = NULL; + + if (host) + { + whost = utf8_to_wchar (host); + if (!whost) + return NULL; + } + ld = ldap_init (whost, port); + xfree (whost); + return ld; +} + + +static inline ULONG +_dirmngr_ldap_simple_bind_s (LDAP *ld, const char *user, const char *pass) +{ + ULONG ret; + wchar_t *wuser, *wpass; + + wuser = user? utf8_to_wchar (user) : NULL; + wpass = pass? utf8_to_wchar (pass) : NULL; + /* We can't easily map errnos to ldap_errno, thus we pass a NULL to + the function in the hope that the server will throw an error. */ + ret = ldap_simple_bind_s (ld, wuser, wpass); + xfree (wpass); + xfree (wuser); + return ret; +} + + +static inline ULONG +_dirmngr_ldap_search_st (LDAP *ld, const char *base, ULONG scope, + const char *filter, char **attrs, + ULONG attrsonly, struct timeval *timeout, + LDAPMessage **res) +{ + ULONG ret = LDAP_NO_MEMORY; + wchar_t *wbase = NULL; + wchar_t *wfilter = NULL; + wchar_t **wattrs = NULL; + int i; + + if (base) + { + wbase = utf8_to_wchar (base); + if (!wbase) + goto leave; + } + if (filter) + { + wfilter = utf8_to_wchar (filter); + if (!wfilter) + goto leave; + } + if (attrs) + { + for (i=0; attrs[i]; i++) + ; + wattrs = xtrycalloc (i+1, sizeof *wattrs); + if (!wattrs) + goto leave; + for (i=0; attrs[i]; i++) + { + wattrs[i] = utf8_to_wchar (attrs[i]); + if (!wattrs[i]) + goto leave; + } + } + + ret = ldap_search_st (ld, wbase, scope, wfilter, wattrs, attrsonly, + (struct l_timeval *)timeout, res); + + leave: + if (wattrs) + { + for (i=0; wattrs[i]; i++) + xfree (wattrs[i]); + xfree (wattrs); + } + xfree (wfilter); + xfree (wbase); + return ret; +} + + +static inline char * +_dirmngr_ldap_first_attribute (LDAP *ld, LDAPMessage *msg, BerElement **elem) +{ + wchar_t *wattr; + char *attr; + + wattr = ldap_first_attribute (ld, msg, elem); + if (!wattr) + return NULL; + attr = wchar_to_utf8 (wattr); + ldap_memfree (wattr); + return attr; +} + + +static inline char * +_dirmngr_ldap_next_attribute (LDAP *ld, LDAPMessage *msg, BerElement *elem) +{ + wchar_t *wattr; + char *attr; + + wattr = ldap_next_attribute (ld, msg, elem); + if (!wattr) + return NULL; + attr = wchar_to_utf8 (wattr); + ldap_memfree (wattr); + return attr; +} + +static inline BerValue ** +_dirmngr_ldap_get_values_len (LDAP *ld, LDAPMessage *msg, const char *attr) +{ + BerValue **ret; + wchar_t *wattr; + + if (attr) + { + wattr = utf8_to_wchar (attr); + if (!wattr) + return NULL; + } + else + wattr = NULL; + + ret = ldap_get_values_len (ld, msg, wattr); + xfree (wattr); + + return ret; +} + + +#endif /*W32_LDAP_HELP_H*/ From cvs at cvs.gnupg.org Fri Aug 13 13:42:15 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 13 Aug 2010 13:42:15 +0200 Subject: [svn] GnuPG - r5395 - in trunk: common dirmngr tools Message-ID: Author: wk Date: 2010-08-13 13:42:14 +0200 (Fri, 13 Aug 2010) New Revision: 5395 Modified: trunk/common/ChangeLog trunk/common/Makefile.am trunk/dirmngr/ChangeLog trunk/dirmngr/Makefile.am trunk/tools/ChangeLog trunk/tools/Makefile.am Log: Minor Makefile fixes to let it build on all platforms Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-08-13 10:02:12 UTC (rev 5394) +++ trunk/common/ChangeLog 2010-08-13 11:42:14 UTC (rev 5395) @@ -1,3 +1,8 @@ +2010-08-13 Werner Koch + + * Makefile.am (audit-events.h, status-codes.h): Fix srcdir problem + amd depend on Makefile.am instead of Makefile. + 2010-08-12 Werner Koch * sysutils.c (gnupg_remove) [W32CE]: Fix returned error. Modified: trunk/dirmngr/ChangeLog =================================================================== --- trunk/dirmngr/ChangeLog 2010-08-13 10:02:12 UTC (rev 5394) +++ trunk/dirmngr/ChangeLog 2010-08-13 11:42:14 UTC (rev 5395) @@ -1,5 +1,7 @@ 2010-08-13 Werner Koch + * Makefile.am (dirmngr_SOURCES): Add w32-ldap-help.h. + * dirmngr_ldap.c (fetch_ldap): Call ldap_unbind. * w32-ldap-help.h: New. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2010-08-13 10:02:12 UTC (rev 5394) +++ trunk/tools/ChangeLog 2010-08-13 11:42:14 UTC (rev 5395) @@ -1,3 +1,7 @@ +2010-08-13 Werner Koch + + * Makefile.am (gpgkey2ssh_LDADD): Add NETLIBS. + 2010-08-11 Werner Koch * gpgtar-create.c (gpgtar_create): Allow "-" for stdout in Modified: trunk/common/Makefile.am =================================================================== --- trunk/common/Makefile.am 2010-08-13 10:02:12 UTC (rev 5394) +++ trunk/common/Makefile.am 2010-08-13 11:42:14 UTC (rev 5395) @@ -139,16 +139,16 @@ # is a distributed built source. If we would not do that we may end # up with two files and then it is not clear which version of the # files will be picked up. -audit-events.h: Makefile mkstrtable.awk exaudit.awk audit.h +audit-events.h: Makefile.am mkstrtable.awk exaudit.awk audit.h $(AWK) -f $(srcdir)/exaudit.awk $(srcdir)/audit.h \ | $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \ - -v namespace=eventstr_ > $(srcdir)/$@ + -v namespace=eventstr_ > $(srcdir)/audit-events.h # Create the status-codes.h include file from status.h -status-codes.h: Makefile mkstrtable.awk exstatus.awk status.h +status-codes.h: Makefile.am mkstrtable.awk exstatus.awk status.h $(AWK) -f $(srcdir)/exstatus.awk $(srcdir)/status.h \ | $(AWK) -f $(srcdir)/mkstrtable.awk -v textidx=3 -v nogettext=1 \ - -v namespace=statusstr_ > $(srcdir)/$@ + -v namespace=statusstr_ > $(srcdir)/status-codes.h endif # Modified: trunk/dirmngr/Makefile.am =================================================================== --- trunk/dirmngr/Makefile.am 2010-08-13 10:02:12 UTC (rev 5394) +++ trunk/dirmngr/Makefile.am 2010-08-13 11:42:14 UTC (rev 5395) @@ -46,7 +46,7 @@ dirmngr_SOURCES = dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \ ldapserver.h ldapserver.c certcache.c certcache.h \ - cdb.h cdblib.c ldap.c misc.c dirmngr-err.h \ + cdb.h cdblib.c ldap.c misc.c dirmngr-err.h w32-ldap-help.h \ ocsp.c ocsp.h validate.c validate.h ldap-wrapper.h $(ldap_url) if USE_LDAPWRAPPER Modified: trunk/tools/Makefile.am =================================================================== --- trunk/tools/Makefile.am 2010-08-13 10:02:12 UTC (rev 5394) +++ trunk/tools/Makefile.am 2010-08-13 11:42:14 UTC (rev 5395) @@ -79,14 +79,15 @@ gpgsplit_LDADD = $(common_libs) \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \ - $(ZLIBS) $(LIBINTL) $(LIBICONV) + $(ZLIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c no-libgcrypt.c # 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) $(opt_libassuan_libs) \ - $(LIBINTL) $(GPG_ERROR_LIBS) $(LIBICONV) $(W32SOCKLIBS) + $(LIBINTL) $(GPG_ERROR_LIBS) $(NETLIBS) \ + $(LIBICONV) $(W32SOCKLIBS) gpgparsemail_SOURCES = gpgparsemail.c rfc822parse.c rfc822parse.h gpgparsemail_LDADD = @@ -94,7 +95,7 @@ symcryptrun_SOURCES = symcryptrun.c symcryptrun_LDADD = $(LIBUTIL_LIBS) $(common_libs) $(pwquery_libs) \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) \ - $(LIBICONV) $(W32SOCKLIBS) + $(LIBICONV) $(NETLIBS) $(W32SOCKLIBS) watchgnupg_SOURCES = watchgnupg.c watchgnupg_LDADD = $(NETLIBS) @@ -111,14 +112,15 @@ # common via use of BUG() in an inline function, which # some compilers do not eliminate. gpgkey2ssh_LDADD = $(common_libs) \ - $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) + $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) \ + $(NETLIBS) endif if !DISABLE_REGEX gpg_check_pattern_SOURCES = gpg-check-pattern.c gpg_check_pattern_CFLAGS = $(LIBGCRYPT_CFLAGS) $(GPG_ERROR_CFLAGS) gpg_check_pattern_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \ - $(LIBINTL) $(LIBICONV) $(W32SOCKLIBS) + $(LIBINTL) $(NETLIBS) $(LIBICONV) $(W32SOCKLIBS) endif gpgtar_SOURCES = \ @@ -129,7 +131,7 @@ no-libgcrypt.c gpgtar_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS) #gpgtar_LDADD = $(commonpth_libs) $(PTH_LIBS) $(GPG_ERROR_LIBS) -gpgtar_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(W32SOCKLIBS) +gpgtar_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(W32SOCKLIBS) # Make sure that all libs are build before we use them. This is From cvs at cvs.gnupg.org Mon Aug 16 10:45:50 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 16 Aug 2010 10:45:50 +0200 Subject: [svn] gcry - r1441 - in trunk: . cipher src tests Message-ID: Author: wk Date: 2010-08-16 10:45:49 +0200 (Mon, 16 Aug 2010) New Revision: 1441 Modified: trunk/cipher/cipher.c trunk/configure.ac trunk/src/ChangeLog trunk/src/gcrypt.h.in trunk/tests/ChangeLog trunk/tests/Makefile.am Log: Insert sys/select.h to be POSIXly correct. Typo fixes. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-07-19 13:56:04 UTC (rev 1440) +++ trunk/src/ChangeLog 2010-08-16 08:45:49 UTC (rev 1441) @@ -1,3 +1,7 @@ +2010-08-16 Werner Koch + + * gcrypt.h.in [!WIN32]: Add INSERT_SYS_SELECT_H autoconf substitute. + 2010-07-09 Werner Koch * gcrypt.h.in [!__GNUC__ && W32]: Typedef ssize_t and pid_t to Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2010-07-19 13:56:04 UTC (rev 1440) +++ trunk/tests/ChangeLog 2010-08-16 08:45:49 UTC (rev 1441) @@ -1,3 +1,7 @@ +2010-07-19 Werner Koch + + * Makefile.am (LDADD): Add GPG_ERROR_LIBS to help a new wannabe ld. + 2010-06-10 Werner Koch * t-mpi-bit.c (mpi2bitstr_nlz): Handle case for LENGTH==0. Modified: trunk/cipher/cipher.c =================================================================== --- trunk/cipher/cipher.c 2010-07-19 13:56:04 UTC (rev 1440) +++ trunk/cipher/cipher.c 2010-08-16 08:45:49 UTC (rev 1441) @@ -194,7 +194,7 @@ struct { unsigned int key:1; /* Set to 1 if a key has been set. */ - unsigned int iv:1; /* Set to 1 if ae IV has been set. */ + unsigned int iv:1; /* Set to 1 if a IV has been set. */ } marks; /* The initialization vector. To help code optimization we make Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-07-19 13:56:04 UTC (rev 1440) +++ trunk/configure.ac 2010-08-16 08:45:49 UTC (rev 1441) @@ -607,7 +607,13 @@ AC_HEADER_STDC AC_CHECK_HEADERS(unistd.h sys/select.h sys/msg.h) +INSERT_SYS_SELECT_H= +if test x"$ac_cv_header_sys_select_h" = xyes; then + INSERT_SYS_SELECT_H=" include " +fi +AC_SUBST(INSERT_SYS_SELECT_H) + ########################################## #### Checks for typedefs, structures, #### #### and compiler characteristics. #### Modified: trunk/src/gcrypt.h.in =================================================================== --- trunk/src/gcrypt.h.in 2010-07-19 13:56:04 UTC (rev 1440) +++ trunk/src/gcrypt.h.in 2010-08-16 08:45:49 UTC (rev 1441) @@ -41,6 +41,7 @@ #else # include # include +#@INSERT_SYS_SELECT_H@ #endif /*!_WIN32*/ @FALLBACK_SOCKLEN_T@ Modified: trunk/tests/Makefile.am =================================================================== --- trunk/tests/Makefile.am 2010-07-19 13:56:04 UTC (rev 1440) +++ trunk/tests/Makefile.am 2010-08-16 08:45:49 UTC (rev 1441) @@ -36,7 +36,7 @@ AM_CPPFLAGS = -I../src -I$(top_srcdir)/src AM_CFLAGS = $(GPG_ERROR_CFLAGS) -LDADD = ../src/libgcrypt.la $(DL_LIBS) ../compat/libcompat.la +LDADD = ../src/libgcrypt.la $(DL_LIBS) ../compat/libcompat.la $(GPG_ERROR_LIB) EXTRA_PROGRAMS = testapi pkbench noinst_PROGRAMS = $(TESTS) fipsdrv rsacvt From cvs at cvs.gnupg.org Mon Aug 16 13:03:45 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 16 Aug 2010 13:03:45 +0200 Subject: [svn] GnuPG - r5396 - in trunk: . common dirmngr doc sm Message-ID: Author: wk Date: 2010-08-16 13:03:43 +0200 (Mon, 16 Aug 2010) New Revision: 5396 Modified: trunk/NEWS trunk/common/ChangeLog trunk/common/asshelp.c trunk/common/asshelp.h trunk/dirmngr/dirmngr.c trunk/doc/dirmngr.texi trunk/sm/ChangeLog trunk/sm/call-dirmngr.c trunk/sm/gpgsm.c trunk/sm/gpgsm.h trunk/sm/server.c Log: Auto-start dirmngr. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-08-13 11:42:14 UTC (rev 5395) +++ trunk/common/ChangeLog 2010-08-16 11:03:43 UTC (rev 5396) @@ -1,3 +1,11 @@ +2010-08-16 Werner Koch + + * asshelp.c (lock_agent_t): Rename to lock_spawn_t. + (lock_agent_spawning, unlock_agent_spawning): Factor code out to ... + (lock_spawning, unlock_spawning): .. new. + (start_new_gpg_agent): Make more use of ERRSOURCE. + (start_new_dirmngr): New. + 2010-08-13 Werner Koch * Makefile.am (audit-events.h, status-codes.h): Fix srcdir problem Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2010-08-13 11:42:14 UTC (rev 5395) +++ trunk/sm/ChangeLog 2010-08-16 11:03:43 UTC (rev 5396) @@ -1,3 +1,16 @@ +2010-08-16 Werner Koch + + * call-dirmngr.c (start_dirmngr_ext): Use new start_new_dirmngr + function. + + * gpgsm.c: Mark option --prefer-system-dirmngr obsolete. + (main): Enable dirmngr by default. + + * gpgsm.h (struct opt): Remove field PREFER_SYSTEM_DIRMNGR. + + * server.c (gpgsm_server): Use dirmngr_socket_name instead of the + envvar for the hello line info. + 2010-06-21 Werner Koch * minip12.c (p12_build): Change arg CERT to const void ptr. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-08-13 11:42:14 UTC (rev 5395) +++ trunk/NEWS 2010-08-16 11:03:43 UTC (rev 5396) @@ -29,9 +29,13 @@ option --enable-standard-socket may now be used to use this feature by default. - * Dirmngr is now a part of this package. + * Dirmngr is now a part of this package. Dirmngr is now also + expected to run as a system service and the configuraion + directories are changed to the gnupg name space. + * Given sufficient permissions Dirmngr is started automagically. + Noteworthy changes in version 2.0.13 (2009-09-04) ------------------------------------------------- Modified: trunk/common/asshelp.c =================================================================== --- trunk/common/asshelp.c 2010-08-13 11:42:14 UTC (rev 5395) +++ trunk/common/asshelp.c 2010-08-16 11:03:43 UTC (rev 5396) @@ -37,9 +37,9 @@ /* The type we use for lock_agent_spawning. */ #ifdef HAVE_W32_SYSTEM -# define lock_agent_t HANDLE +# define lock_spawn_t HANDLE #else -# define lock_agent_t dotlock_t +# define lock_spawn_t dotlock_t #endif @@ -216,21 +216,26 @@ } -/* Lock the agent spawning process. The caller needs to provide the - address of a variable to store the lock information. */ +/* Lock a spawning process. The caller needs to provide the address + of a variable to store the lock information and the name or the + process. */ static gpg_error_t -lock_agent_spawning (lock_agent_t *lock, const char *homedir) +lock_spawning (lock_spawn_t *lock, const char *homedir, const char *name) { #ifdef HAVE_W32_SYSTEM int waitrc; - + (void)homedir; /* Not required. */ - *lock = CreateMutexW (NULL, FALSE, L"GnuPG_spawn_agent_sentinel"); + *lock = CreateMutexW + (NULL, FALSE, + !strcmp (name, "agent")? L"GnuPG_spawn_agent_sentinel": + !strcmp (name, "dirmngr")? L"GnuPG_spawn_dirmngr_sentinel": + /* */ L"GnuPG_spawn_unknown_sentinel"); if (!*lock) { - log_error ("failed to create the spawn_agent mutex: %s\n", - w32_strerror (-1)); + log_error ("failed to create the spawn_%s mutex: %s\n", + name, w32_strerror (-1)); return gpg_error (GPG_ERR_GENERAL); } @@ -239,17 +244,22 @@ return 0; if (waitrc == WAIT_TIMEOUT) - log_info ("error waiting for the spawn_agent mutex: timeout\n"); + log_info ("error waiting for the spawn_%s mutex: timeout\n", name); else - log_info ("error waiting for the spawn_agent mutex: " - "(code=%d) %s\n", waitrc, w32_strerror (-1)); + log_info ("error waiting for the spawn_%s mutex: (code=%d) %s\n", + name, waitrc, w32_strerror (-1)); return gpg_error (GPG_ERR_GENERAL); #else /*!HAVE_W32_SYSTEM*/ char *fname; *lock = NULL; - fname = make_filename (homedir, "gnupg_spawn_agent_sentinel", NULL); + fname = make_filename + (homedir, + !strcmp (name, "agent")? "gnupg_spawn_agent_sentinel": + !strcmp (name, "dirmngr")? "gnupg_spawn_dirmngr_sentinel": + /* */ "gnupg_spawn_unknown_sentinel", + NULL); if (!fname) return gpg_error_from_syserror (); @@ -270,23 +280,39 @@ /* Unlock the spawning process. */ static void -unlock_agent_spawning (lock_agent_t *lock) +unlock_spawning (lock_spawn_t *lock, const char *name) { if (*lock) { #ifdef HAVE_W32_SYSTEM if (!ReleaseMutex (*lock)) - log_error ("failed to release the spawn_agent mutex: %s\n", - w32_strerror (-1)); + log_error ("failed to release the spawn_%s mutex: %s\n", + name, w32_strerror (-1)); CloseHandle (*lock); #else /*!HAVE_W32_SYSTEM*/ + (void)name; destroy_dotlock (*lock); #endif /*!HAVE_W32_SYSTEM*/ *lock = NULL; } } +/* Lock the agent spawning process. The caller needs to provide the + address of a variable to store the lock information. */ +static gpg_error_t +lock_agent_spawning (lock_spawn_t *lock, const char *homedir) +{ + return lock_spawning (lock, homedir, "agent"); +} + +static void +unlock_agent_spawning (lock_spawn_t *lock) +{ + unlock_spawning (lock, "agent"); +} + + /* Try to connect to the agent via socket or fork it off and work by pipes. Handle the server's initial greeting. Returns a new assuan context at R_CTX or an error code. */ @@ -336,8 +362,12 @@ if (err) { /* With no success start a new server. */ + if (!agent_program || !*agent_program) + agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); + if (verbose) - log_info (_("no running gpg-agent - starting one\n")); + log_info (_("no running %s - starting `%s'\n"), + "gpg-agent", agent_program); if (status_cb) status_cb (status_cb_arg, STATUS_PROGRESS, @@ -345,7 +375,8 @@ if (fflush (NULL)) { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); + gpg_error_t tmperr = gpg_err_make (errsource, + gpg_err_code_from_syserror ()); log_error ("error flushing pending output: %s\n", strerror (errno)); xfree (sockname); @@ -353,9 +384,6 @@ return tmperr; } - if (!agent_program || !*agent_program) - agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); - argv[0] = "--use-standard-socket-p"; argv[1] = NULL; err = gnupg_spawn_process_fd (agent_program, argv, -1, -1, -1, &pid); @@ -376,7 +404,7 @@ standard socket, an environment variable is not required and thus we we can savely start the agent here. */ - lock_agent_t lock; + lock_spawn_t lock; argv[0] = "--daemon"; argv[1] = "--use-standard-socket"; @@ -394,8 +422,8 @@ int i; if (verbose) - log_info (_("waiting %d seconds for the agent " - "to come up\n"), 5); + log_info (_("waiting %d seconds for the %s " + "to come up\n"), 5, "agent" ); for (i=0; i < 5; i++) { gnupg_sleep (1); @@ -481,7 +509,7 @@ { log_error ("can't connect to the agent: %s\n", gpg_strerror (err)); assuan_release (ctx); - return gpg_error (GPG_ERR_NO_AGENT); + return gpg_err_make (errsource, GPG_ERR_NO_AGENT); } if (debug) @@ -503,3 +531,107 @@ return 0; } + +/* Try to connect to the dirmngr via a socket. On platforms + supporting it, start it up if needed. Returns a new assuan context + at R_CTX or an error code. */ +gpg_error_t +start_new_dirmngr (assuan_context_t *r_ctx, + gpg_err_source_t errsource, + const char *homedir, + const char *dirmngr_program, + int verbose, int debug, + gpg_error_t (*status_cb)(ctrl_t, int, ...), + ctrl_t status_cb_arg) +{ + gpg_error_t err; + assuan_context_t ctx; + const char *sockname; + lock_spawn_t lock; + + *r_ctx = NULL; + + err = assuan_new (&ctx); + if (err) + { + log_error ("error allocating assuan context: %s\n", gpg_strerror (err)); + return err; + } + + sockname = dirmngr_socket_name (); + err = assuan_socket_connect (ctx, sockname, 0, 0); + if (err) + { + const char *argv[2]; + + /* With no success try start a new Dirmngr. On most systems + this will fail because the Dirmngr is expected to be a system + service. However on Wince we don't distinguish users and + thus we can start it. A future extension might be to use the + userv system to start the Dirmngr as a system service. */ + if (!dirmngr_program || !*dirmngr_program) + dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR); + + if (verbose) + log_info (_("no running %s - starting `%s'\n"), + "dirmngr", dirmngr_program); + + if (status_cb) + status_cb (status_cb_arg, STATUS_PROGRESS, + "starting_dirmngr ? 0 0", NULL); + + if (fflush (NULL)) + { + gpg_error_t tmperr = gpg_err_make (errsource, + gpg_err_code_from_syserror ()); + log_error ("error flushing pending output: %s\n", + strerror (errno)); + assuan_release (ctx); + return tmperr; + } + + argv[0] = "--daemon"; + argv[1] = NULL; + + if (!(err = lock_spawning (&lock, homedir, "dirmngr")) + && assuan_socket_connect (ctx, sockname, 0, 0)) + { + err = gnupg_spawn_process_detached (dirmngr_program, argv,NULL); + if (err) + log_error ("failed to start the dirmngr `%s': %s\n", + dirmngr_program, gpg_strerror (err)); + else + { + int i; + + if (verbose) + log_info (_("waiting %d seconds for the %s to come up\n"), + 5, "dirmngr" ); + for (i=0; i < 5; i++) + { + gnupg_sleep (1); + err = assuan_socket_connect (ctx, sockname, 0, 0); + if (!err) + break; + } + } + } + + unlock_spawning (&lock, "dirmngr"); + } + + if (err) + { + log_error ("connecting dirmngr at `%s' failed: %s\n", + sockname, gpg_strerror (err)); + assuan_release (ctx); + return gpg_err_make (errsource, GPG_ERR_NO_DIRMNGR); + } + + if (debug) + log_debug ("connection to the dirmngr established\n"); + + *r_ctx = ctx; + return 0; +} + Modified: trunk/common/asshelp.h =================================================================== --- trunk/common/asshelp.h 2010-08-13 11:42:14 UTC (rev 5395) +++ trunk/common/asshelp.h 2010-08-16 11:03:43 UTC (rev 5396) @@ -49,5 +49,17 @@ gpg_error_t (*status_cb)(ctrl_t, int, ...), ctrl_t status_cb_arg); +/* This function is used to connect to the dirmngr. On some platforms + the function is able starts a dirmngr process if needed. */ +gpg_error_t +start_new_dirmngr (assuan_context_t *r_ctx, + gpg_err_source_t errsource, + const char *homedir, + const char *dirmngr_program, + int verbose, int debug, + gpg_error_t (*status_cb)(ctrl_t, int, ...), + ctrl_t status_cb_arg); + + #endif /*GNUPG_COMMON_ASSHELP_H*/ Modified: trunk/dirmngr/dirmngr.c =================================================================== --- trunk/dirmngr/dirmngr.c 2010-08-13 11:42:14 UTC (rev 5395) +++ trunk/dirmngr/dirmngr.c 2010-08-16 11:03:43 UTC (rev 5396) @@ -194,7 +194,7 @@ ARGPARSE_s_i (oMaxReplies, "max-replies", N_("|N|do not return more than N items in one query")), - ARGPARSE_s_s (oSocketName, "socket-name", N_("|FILE|listen on socket FILE")), + ARGPARSE_s_s (oSocketName, "socket-name", "@"), /* Only for debugging. */ ARGPARSE_s_u (oFakedSystemTime, "faked-system-time", "@"), /*(epoch time)*/ ARGPARSE_p_u (oDebug, "debug", "@"), @@ -897,6 +897,7 @@ if (cmd == aServer) { + /* Note that this server mode is maily useful for debugging. */ if (argc) wrong_args ("--server"); @@ -1002,6 +1003,9 @@ es_fflush (NULL); + /* Note: We keep the dirmngr_info output only for the sake of + existing scripts which might use this to detect a successful + start of the dirmngr. */ #ifdef HAVE_W32_SYSTEM pid = getpid (); printf ("set DIRMNGR_INFO=%s;%lu;1\n", socket_name, (ulong) pid); @@ -1032,7 +1036,7 @@ dirmngr_exit (1); } /* Print the environment string, so that the caller can use - shell's eval to set it */ + shell's eval to set it. But see above. */ if (csh_style) { *strchr (infostr, '=') = ' '; Modified: trunk/doc/dirmngr.texi =================================================================== --- trunk/doc/dirmngr.texi 2010-08-13 11:42:14 UTC (rev 5395) +++ trunk/doc/dirmngr.texi 2010-08-16 11:03:43 UTC (rev 5396) @@ -469,7 +469,7 @@ @end example Please ignore the output; it is not needed anymore. Check the log file -to see whether all trusted root certificates have benn loaded correctly. +to see whether all trusted root certificates have been loaded correctly. @c @@ -519,16 +519,9 @@ @section Examples -The way to start the dirmngr in the foreground (as done by tools if no -dirmngr is running in the background) is to use: +Dirmngr is supposed to be used as a system wide daemon, it should be +started like: - at example - dirmngr --server -v - at end example - -If a dirmngr is supposed to be used as a system wide daemon, it should -be started like: - @example dirmngr --daemon @end example @@ -539,7 +532,15 @@ socket used but they are only for compatibilty reasons with old GnuPG versions and may be ignored. +For debugging purposes it is also possible to start Dirmngr in the +foreground: + at example + dirmngr --server -v + at end example + + + @c @c Assuan Protocol @c Modified: trunk/sm/call-dirmngr.c =================================================================== --- trunk/sm/call-dirmngr.c 2010-08-13 11:42:14 UTC (rev 5395) +++ trunk/sm/call-dirmngr.c 2010-08-16 11:03:43 UTC (rev 5396) @@ -1,5 +1,6 @@ -/* call-dirmngr.c - communication with the dromngr - * Copyright (C) 2002, 2003, 2005, 2007, 2008 Free Software Foundation, Inc. +/* call-dirmngr.c - Communication with the dirmngr + * Copyright (C) 2002, 2003, 2005, 2007, 2008, + * 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -33,6 +34,7 @@ #include "i18n.h" #include "keydb.h" +#include "asshelp.h" struct membuf { @@ -52,8 +54,6 @@ static int dirmngr_ctx_locked; static int dirmngr2_ctx_locked; -static int force_pipe_server = 0; - struct inq_certificate_parm_s { ctrl_t ctrl; assuan_context_t ctx; @@ -184,15 +184,12 @@ -/* Try to connect to the agent via socket or fork it off and work by - pipes. Handle the server's initial greeting */ -static int +/* Return a new assuan context for a Dirmngr connection. */ +static gpg_error_t start_dirmngr_ext (ctrl_t ctrl, assuan_context_t *ctx_r) { - int rc; - char *infostr, *p; - assuan_context_t ctx = NULL; - int try_default = 0; + gpg_error_t err; + assuan_context_t ctx; if (opt.disable_dirmngr) return gpg_error (GPG_ERR_NO_DIRMNGR); @@ -203,129 +200,15 @@ /* Note: if you change this to multiple connections, you also need to take care of the implicit option sending caching. */ -#ifdef HAVE_W32_SYSTEM - infostr = NULL; - opt.prefer_system_dirmngr = 1; -#else - infostr = force_pipe_server? NULL : getenv ("DIRMNGR_INFO"); -#endif /*HAVE_W32_SYSTEM*/ - if (infostr && !*infostr) - infostr = NULL; - else if (infostr) - infostr = xstrdup (infostr); + err = start_new_dirmngr (&ctx, GPG_ERR_SOURCE_DEFAULT, + opt.homedir, opt.dirmngr_program, + opt.verbose, DBG_ASSUAN, + gpgsm_status2, ctrl); + prepare_dirmngr (ctrl, ctx, err); + if (err) + return err; - if (opt.prefer_system_dirmngr && !force_pipe_server && !infostr) - { - infostr = xstrdup (dirmngr_socket_name ()); - try_default = 1; - } - - rc = assuan_new (&ctx); - if (rc) - { - log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc)); - return rc; - } - - if (!infostr) - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; - - if (!opt.dirmngr_program || !*opt.dirmngr_program) - opt.dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR); - if ( !(pgmname = strrchr (opt.dirmngr_program, '/'))) - pgmname = opt.dirmngr_program; - else - pgmname++; - - if (opt.verbose) - log_info (_("no running dirmngr - starting `%s'\n"), - opt.dirmngr_program); - - if (fflush (NULL)) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("error flushing pending output: %s\n", strerror (errno)); - return tmperr; - } - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = assuan_fd_from_posix_fd (log_get_fd ()); - no_close_list[i++] = assuan_fd_from_posix_fd (fileno (stderr)); - no_close_list[i] = -1; - - /* connect to the agent and perform initial handshaking */ - rc = assuan_pipe_connect (ctx, opt.dirmngr_program, argv, - no_close_list, NULL, NULL, 0); - } - else - { - int prot; - int pid; - - if (!try_default) - { - if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr) - { - log_error (_("malformed DIRMNGR_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_dirmngr_ext (ctrl, ctx_r); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != PATHSEP_C) - p++; - prot = *p? atoi (p+1) : 0; - if (prot != 1) - { - log_error (_("dirmngr protocol version %d is not supported\n"), - prot); - xfree (infostr); - force_pipe_server = 1; - return start_dirmngr_ext (ctrl, ctx_r); - } - } - else - pid = -1; - - rc = assuan_socket_connect (ctx, infostr, pid, 0); -#ifdef HAVE_W32_SYSTEM - if (rc) - log_debug ("connecting dirmngr at `%s' failed\n", infostr); -#endif - - xfree (infostr); -#ifndef HAVE_W32_SYSTEM - if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED) - { - log_info (_("can't connect to the dirmngr - trying fall back\n")); - force_pipe_server = 1; - return start_dirmngr_ext (ctrl, ctx_r); - } -#endif /*!HAVE_W32_SYSTEM*/ - } - - prepare_dirmngr (ctrl, ctx, rc); - - if (rc) - { - assuan_release (ctx); - log_error ("can't connect to the dirmngr: %s\n", gpg_strerror (rc)); - return gpg_error (GPG_ERR_NO_DIRMNGR); - } *ctx_r = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to dirmngr established\n"); return 0; } Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2010-08-13 11:42:14 UTC (rev 5395) +++ trunk/sm/gpgsm.c 2010-08-16 11:03:43 UTC (rev 5396) @@ -240,8 +240,7 @@ ARGPARSE_s_s (oRecipient, "recipient", N_("|USER-ID|encrypt for USER-ID")), - ARGPARSE_s_n (oPreferSystemDirmngr,"prefer-system-dirmngr", - N_("use system's dirmngr if available")), + ARGPARSE_s_n (oPreferSystemDirmngr,"prefer-system-dirmngr", "@"), ARGPARSE_s_n (oDisableCRLChecks, "disable-crl-checks", N_("never consult a CRL")), @@ -941,10 +940,6 @@ 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; @@ -1280,7 +1275,7 @@ case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break; case oDisableDirmngr: opt.disable_dirmngr = 1; break; - case oPreferSystemDirmngr: opt.prefer_system_dirmngr = 1; break; + case oPreferSystemDirmngr: /* Obsolete */; break; case oProtectToolProgram: opt.protect_tool_program = pargs.r.ret_str; break; @@ -1659,9 +1654,6 @@ printf ("disable-policy-checks:%lu:\n", GC_OPT_FLAG_NONE); printf ("auto-issuer-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE); printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); -#ifndef HAVE_W32_SYSTEM - printf ("prefer-system-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); -#endif printf ("cipher-algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, DEFAULT_CIPHER_ALGO); printf ("p12-charset:%lu:\n", GC_OPT_FLAG_DEFAULT); Modified: trunk/sm/gpgsm.h =================================================================== --- trunk/sm/gpgsm.h 2010-08-13 11:42:14 UTC (rev 5395) +++ trunk/sm/gpgsm.h 2010-08-16 11:03:43 UTC (rev 5396) @@ -69,7 +69,6 @@ char *lc_messages; const char *dirmngr_program; - int prefer_system_dirmngr; /* Prefer using a system wide drimngr. */ int disable_dirmngr; /* Do not do any dirmngr calls. */ const char *protect_tool_program; char *outfile; /* name of output file */ Modified: trunk/sm/server.c =================================================================== --- trunk/sm/server.c 2010-08-13 11:42:14 UTC (rev 5395) +++ trunk/sm/server.c 2010-08-16 11:03:43 UTC (rev 5396) @@ -1293,7 +1293,6 @@ { char *tmp = NULL; const char *s1 = getenv ("GPG_AGENT_INFO"); - const char *s2 = getenv ("DIRMNGR_INFO"); if (asprintf (&tmp, "Home: %s\n" @@ -1304,7 +1303,7 @@ opt.homedir, opt.config_filename, s1?s1:"[not set]", - s2?s2:"[not set]", + dirmngr_socket_name (), hello) > 0) { assuan_set_hello_line (ctx, tmp); From cvs at cvs.gnupg.org Wed Aug 18 16:14:28 2010 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 18 Aug 2010 16:14:28 +0200 Subject: [svn] gpgme - r1487 - in trunk: . src Message-ID: Author: marcus Date: 2010-08-18 16:14:27 +0200 (Wed, 18 Aug 2010) New Revision: 1487 Modified: trunk/NEWS trunk/src/ChangeLog trunk/src/error.c trunk/src/gpgme.def trunk/src/gpgme.h.in trunk/src/libgpgme.vers Log: 2010-08-18 Marcus Brinkmann * gpgme.def: Add gpgme_err_code_from_syserror and gpgme_err_set_errno. * libgpgme.vers: Likewise. * gpgme.h.in (gpgme_error_from_errno): Fix return type to gpgme_error_t. (gpgme_err_code_from_syserror, gpgme_err_set_errno): New prototype. (gpgme_error_from_syserror): New inline function (why are gpgme_err_make_from_errno and gpgme_error_from_errno not inline functions?). * error.c (gpgme_error_from_errno): Fix return type to gpgme_error_t. (gpgme_err_set_errno, gpgme_err_code_from_syserror): New functions. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-08-04 07:47:05 UTC (rev 1486) +++ trunk/src/ChangeLog 2010-08-18 14:14:27 UTC (rev 1487) @@ -1,3 +1,16 @@ +2010-08-18 Marcus Brinkmann + + * gpgme.def: Add gpgme_err_code_from_syserror and gpgme_err_set_errno. + * libgpgme.vers: Likewise. + * gpgme.h.in (gpgme_error_from_errno): Fix return type to + gpgme_error_t. + (gpgme_err_code_from_syserror, gpgme_err_set_errno): New prototype. + (gpgme_error_from_syserror): New inline function (why are + gpgme_err_make_from_errno and gpgme_error_from_errno not inline + functions?). + * error.c (gpgme_error_from_errno): Fix return type to gpgme_error_t. + (gpgme_err_set_errno, gpgme_err_code_from_syserror): New functions. + 2010-08-03 Marcus Brinkmann * gpgme-tool.c (result_encrypt_to_xml, result_sign_to_xml) Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-08-04 07:47:05 UTC (rev 1486) +++ trunk/NEWS 2010-08-18 14:14:27 UTC (rev 1487) @@ -7,7 +7,11 @@ * Interface changes relative to the 1.3.0 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - GPGME_EXPORT_MODE_MINIMAL NEW. + GPGME_EXPORT_MODE_MINIMAL NEW + gpgme_err_code_from_syserror NEW + gpgme_err_set_errno NEW + gpgme_error_from_errno CHANGED: Return gpgme_error_t (compatible type). + gpgme_error_from_syserror NEW ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Modified: trunk/src/error.c =================================================================== --- trunk/src/error.c 2010-08-04 07:47:05 UTC (rev 1486) +++ trunk/src/error.c 2010-08-18 14:14:27 UTC (rev 1487) @@ -74,6 +74,25 @@ return gpg_err_code_from_errno (code); } + +/* Retrieve the error code directly from the ERRNO variable. This + returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped + (report this) and GPG_ERR_MISSING_ERRNO if ERRNO has the value 0. */ +gpgme_err_code_t +gpgme_err_code_from_syserror (void) +{ + return gpg_err_code_from_syserror (); +} + + +/* Set the ERRNO variable. This function is the preferred way to set + ERRNO due to peculiarities on WindowsCE. */ +void +gpgme_err_set_errno (int err) +{ + gpg_err_set_errno (err); +} + /* Return an error value with the error source SOURCE and the system error ERR. */ @@ -85,7 +104,7 @@ /* Return an error value with the system error ERR. */ -gpgme_err_code_t +gpgme_error_t gpgme_error_from_errno (int err) { return gpgme_error (gpg_err_code_from_errno (err)); Modified: trunk/src/gpgme.def =================================================================== --- trunk/src/gpgme.def 2010-08-04 07:47:05 UTC (rev 1486) +++ trunk/src/gpgme.def 2010-08-18 14:14:27 UTC (rev 1487) @@ -199,5 +199,8 @@ gpgme_op_passwd_start @152 gpgme_op_passwd @153 + gpgme_err_code_from_syserror @154 + gpgme_err_set_errno @155 + ; END Modified: trunk/src/gpgme.h.in =================================================================== --- trunk/src/gpgme.h.in 2010-08-04 07:47:05 UTC (rev 1486) +++ trunk/src/gpgme.h.in 2010-08-18 14:14:27 UTC (rev 1487) @@ -164,31 +164,42 @@ beginning of the error string as fits into the buffer. */ int gpgme_strerror_r (gpg_error_t err, char *buf, size_t buflen); - /* Return a pointer to a string containing a description of the error source in the error value ERR. */ const char *gpgme_strsource (gpgme_error_t err); - /* Retrieve the error code for the system error ERR. This returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report this). */ gpgme_err_code_t gpgme_err_code_from_errno (int err); - /* Retrieve the system error for the error code CODE. This returns 0 if CODE is not a system error code. */ int gpgme_err_code_to_errno (gpgme_err_code_t code); - +/* Retrieve the error code directly from the ERRNO variable. This + returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped + (report this) and GPG_ERR_MISSING_ERRNO if ERRNO has the value 0. */ +gpgme_err_code_t gpgme_err_code_from_syserror (void); + +/* Set the ERRNO variable. This function is the preferred way to set + ERRNO due to peculiarities on WindowsCE. */ +void gpgme_err_set_errno (int err); + /* Return an error value with the error source SOURCE and the system - error ERR. */ + error ERR. FIXME: Should be inline. */ gpgme_error_t gpgme_err_make_from_errno (gpgme_err_source_t source, int err); +/* Return an error value with the system error ERR. FIXME: Should be inline. */ +gpgme_error_t gpgme_error_from_errno (int err); -/* Return an error value with the system error ERR. */ -gpgme_err_code_t gpgme_error_from_errno (int err); +static _GPGME_INLINE gpgme_error_t +gpgme_error_from_syserror (void) +{ + return gpgme_error (gpgme_err_code_from_syserror ()); +} + /* The possible encoding mode of gpgme_data_t objects. */ typedef enum Modified: trunk/src/libgpgme.vers =================================================================== --- trunk/src/libgpgme.vers 2010-08-04 07:47:05 UTC (rev 1486) +++ trunk/src/libgpgme.vers 2010-08-18 14:14:27 UTC (rev 1487) @@ -204,6 +204,9 @@ gpgme_trust_item_get_string_attr; gpgme_trust_item_release; + gpgme_err_code_from_syserror; + gpgme_err_set_errno; + local: *; From cvs at cvs.gnupg.org Wed Aug 18 21:25:18 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 18 Aug 2010 21:25:18 +0200 Subject: [svn] GnuPG - r5397 - in trunk: agent common doc g10 scd sm tools Message-ID: Author: wk Date: 2010-08-18 21:25:15 +0200 (Wed, 18 Aug 2010) New Revision: 5397 Modified: trunk/agent/ChangeLog trunk/agent/gpg-agent.c trunk/common/ChangeLog trunk/common/estream.c trunk/common/estream.h trunk/common/logging.c trunk/common/logging.h trunk/doc/ChangeLog trunk/doc/tools.texi trunk/g10/ChangeLog trunk/g10/gpg.c trunk/scd/ChangeLog trunk/scd/scdaemon.c trunk/sm/ChangeLog trunk/sm/gpgsm.c trunk/tools/ChangeLog trunk/tools/gpg-connect-agent.c trunk/tools/gpgconf-comp.c trunk/tools/gpgconf.c trunk/tools/gpgconf.h Log: Fix regression in logging. Add a registry key to enable catch-all remote debugging for W32. Replace more stdio stuff by estream. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/agent/ChangeLog 2010-08-18 19:25:15 UTC (rev 5397) @@ -1,3 +1,7 @@ +2010-08-16 Werner Koch + + * gpg-agent.c: Repalce remaining printf by es_printf. + 2010-08-11 Werner Koch * call-pinentry.c (agent_get_passphrase, agent_askpin): Fix Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/common/ChangeLog 2010-08-18 19:25:15 UTC (rev 5397) @@ -1,5 +1,16 @@ +2010-08-18 Werner Koch + + * logging.c (writen): Add arg IS_SOCKET. + (fun_writer): Pass the is_socket flag. + (do_logv) [W32]: Allow for a default log stream + + * estream.c (struct estream_internal): Remove obsolete fields + PRINT_FP, PRINT_ERRNO, PRINT_ERR and all remaining code cruft. + 2010-08-16 Werner Koch + * estream.c (es_printf_unlocked, es_printf): New. + * asshelp.c (lock_agent_t): Rename to lock_spawn_t. (lock_agent_spawning, unlock_agent_spawning): Factor code out to ... (lock_spawning, unlock_spawning): .. new. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/doc/ChangeLog 2010-08-18 19:25:15 UTC (rev 5397) @@ -1,3 +1,7 @@ +2010-08-18 Werner Koch + + * tools.texi (watchgnupg): Add examples section. + 2010-06-10 Werner Koch * Makefile.am (gnupg_TEXINFOS): Add dirmngr.texi. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/g10/ChangeLog 2010-08-18 19:25:15 UTC (rev 5397) @@ -1,3 +1,9 @@ +2010-08-16 Werner Koch + + * gpg.c (list_config, gpgconf_list): Use es_printf. + (print_hex, print_hashline, print_algo_numbers) + (print_algo_names): Use es_printf. + 2010-07-20 Werner Koch * mainproc.c (print_pkenc_list): Write a STATUS_ERROR. Fixes Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/scd/ChangeLog 2010-08-18 19:25:15 UTC (rev 5397) @@ -1,3 +1,7 @@ +2010-08-16 Werner Koch + + * scdaemon.c: Replace remaining printf by es_printf. + 2010-06-09 Werner Koch * scdaemon.c (main): s/log_set_get_tid_callback/log_set_pid_suffix_cb/. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/sm/ChangeLog 2010-08-18 19:25:15 UTC (rev 5397) @@ -1,5 +1,7 @@ 2010-08-16 Werner Koch + * gpgsm.c (main) : Use es_printf. + * call-dirmngr.c (start_dirmngr_ext): Use new start_new_dirmngr function. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/tools/ChangeLog 2010-08-18 19:25:15 UTC (rev 5397) @@ -1,3 +1,13 @@ +2010-08-16 Werner Koch + + * gpgconf.c (get_outfp): Change to use estream. + (main): Replace fprintf by es_fprintf. + * gpgconf-comp.c (gc_component_list_components) + (gc_check_programs, gc_component_list_options) + (gc_component_change_options, gc_component_check_options) + (list_one_option, gc_process_gpgconf_conf): Replace FILE* args by + estream_t. + 2010-08-13 Werner Koch * Makefile.am (gpgkey2ssh_LDADD): Add NETLIBS. Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/agent/gpg-agent.c 2010-08-18 19:25:15 UTC (rev 5397) @@ -823,9 +823,9 @@ if (greeting) { - fprintf (stderr, "%s %s; %s\n", - strusage(11), strusage(13), strusage(14) ); - fprintf (stderr, "%s\n", strusage(15) ); + es_fprintf (es_stderr, "%s %s; %s\n", + strusage(11), strusage(13), strusage(14) ); + es_fprintf (es_stderr, "%s\n", strusage(15) ); } #ifdef IS_DEVELOPMENT_VERSION /* We don't want to print it here because gpg-agent is useful of its @@ -874,12 +874,12 @@ filename = make_filename (opt.homedir, "gpg-agent.conf", NULL ); filename_esc = percent_escape (filename, NULL); - printf ("gpgconf-gpg-agent.conf:%lu:\"%s\n", + es_printf ("gpgconf-gpg-agent.conf:%lu:\"%s\n", GC_OPT_FLAG_DEFAULT, filename_esc); xfree (filename); xfree (filename_esc); - printf ("verbose:%lu:\n" + es_printf ("verbose:%lu:\n" "quiet:%lu:\n" "debug-level:%lu:\"none:\n" "log-file:%lu:\n", @@ -887,35 +887,35 @@ GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME ); - printf ("default-cache-ttl:%lu:%d:\n", + es_printf ("default-cache-ttl:%lu:%d:\n", GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, DEFAULT_CACHE_TTL ); - printf ("default-cache-ttl-ssh:%lu:%d:\n", + es_printf ("default-cache-ttl-ssh:%lu:%d:\n", GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, DEFAULT_CACHE_TTL_SSH ); - printf ("max-cache-ttl:%lu:%d:\n", + es_printf ("max-cache-ttl:%lu:%d:\n", GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MAX_CACHE_TTL ); - printf ("max-cache-ttl-ssh:%lu:%d:\n", + es_printf ("max-cache-ttl-ssh:%lu:%d:\n", GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MAX_CACHE_TTL_SSH ); - printf ("enforce-passphrase-constraints:%lu:\n", + es_printf ("enforce-passphrase-constraints:%lu:\n", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); - printf ("min-passphrase-len:%lu:%d:\n", + es_printf ("min-passphrase-len:%lu:%d:\n", GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MIN_PASSPHRASE_LEN ); - printf ("min-passphrase-nonalpha:%lu:%d:\n", + es_printf ("min-passphrase-nonalpha:%lu:%d:\n", GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MIN_PASSPHRASE_NONALPHA); - printf ("check-passphrase-pattern:%lu:\n", + es_printf ("check-passphrase-pattern:%lu:\n", GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME); - printf ("max-passphrase-days:%lu:%d:\n", + es_printf ("max-passphrase-days:%lu:%d:\n", GC_OPT_FLAG_DEFAULT|GC_OPT_FLAG_RUNTIME, MAX_PASSPHRASE_DAYS); - printf ("enable-passphrase-history:%lu:\n", + es_printf ("enable-passphrase-history:%lu:\n", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); - printf ("no-grab:%lu:\n", + es_printf ("no-grab:%lu:\n", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); - printf ("ignore-cache-for-signing:%lu:\n", + es_printf ("ignore-cache-for-signing:%lu:\n", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); - printf ("allow-mark-trusted:%lu:\n", + es_printf ("allow-mark-trusted:%lu:\n", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); - printf ("disable-scdaemon:%lu:\n", + es_printf ("disable-scdaemon:%lu:\n", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME); agent_exit (0); @@ -1026,7 +1026,7 @@ fflush (NULL); #ifdef HAVE_W32_SYSTEM pid = getpid (); - printf ("set GPG_AGENT_INFO=%s;%lu;1\n", socket_name, (ulong)pid); + es_printf ("set GPG_AGENT_INFO=%s;%lu;1\n", socket_name, (ulong)pid); #else /*!HAVE_W32_SYSTEM*/ pid = fork (); if (pid == (pid_t)-1) @@ -1098,24 +1098,24 @@ if (env_file_name) { - FILE *fp; + estream_t fp; - fp = fopen (env_file_name, "w"); + fp = es_fopen (env_file_name, "w"); if (!fp) log_error (_("error creating `%s': %s\n"), env_file_name, strerror (errno)); else { - fputs (infostr, fp); - putc ('\n', fp); + es_fputs (infostr, fp); + es_putc ('\n', fp); if (opt.ssh_support) { - fputs (infostr_ssh_sock, fp); - putc ('\n', fp); - fputs (infostr_ssh_pid, fp); - putc ('\n', fp); + es_fputs (infostr_ssh_sock, fp); + es_putc ('\n', fp); + es_fputs (infostr_ssh_pid, fp); + es_putc ('\n', fp); } - fclose (fp); + es_fclose (fp); } } @@ -1163,22 +1163,24 @@ if (csh_style) { *strchr (infostr, '=') = ' '; - printf ("setenv %s\n", infostr); + es_printf ("setenv %s\n", infostr); if (opt.ssh_support) { *strchr (infostr_ssh_sock, '=') = ' '; - printf ("setenv %s\n", infostr_ssh_sock); + es_printf ("setenv %s\n", infostr_ssh_sock); *strchr (infostr_ssh_pid, '=') = ' '; - printf ("setenv %s\n", infostr_ssh_pid); + es_printf ("setenv %s\n", infostr_ssh_pid); } } else { - printf ( "%s; export GPG_AGENT_INFO;\n", infostr); + es_printf ( "%s; export GPG_AGENT_INFO;\n", infostr); if (opt.ssh_support) { - printf ("%s; export SSH_AUTH_SOCK;\n", infostr_ssh_sock); - printf ("%s; export SSH_AGENT_PID;\n", infostr_ssh_pid); + es_printf ("%s; export SSH_AUTH_SOCK;\n", + infostr_ssh_sock); + es_printf ("%s; export SSH_AGENT_PID;\n", + infostr_ssh_pid); } } xfree (infostr); Modified: trunk/common/estream.c =================================================================== --- trunk/common/estream.c 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/common/estream.c 2010-08-18 19:25:15 UTC (rev 5397) @@ -218,7 +218,7 @@ es_cookie_seek_function_t func_seek; es_cookie_close_function_t func_close; int strategy; - int fd; + int fd; /* Value to return by es_fileno(). */ struct { unsigned int err: 1; @@ -227,11 +227,8 @@ unsigned int deallocate_buffer: 1; unsigned int is_stdstream:1; /* This is a standard stream. */ unsigned int stdstream_fd:2; /* 0, 1 or 2 for a standard stream. */ - unsigned int print_err: 1; /* Error in print_fun_writer. */ unsigned int printable_fname_inuse: 1; /* es_fname_get has been used. */ - int print_errno; /* Errno from print_fun_writer. */ - size_t print_ntotal; /* Bytes written from in print_fun_writer. */ - FILE *print_fp; /* Stdio stream used by print_fun_writer. */ + size_t print_ntotal; /* Bytes written from in print_writer. */ }; @@ -899,7 +896,8 @@ int no_close; /* If set we won't close the file pointer. */ } *estream_cookie_fp_t; -/* Create function for fd objects. */ + +/* Create function for FILE objects. */ static int es_func_fp_create (void **cookie, FILE *fp, unsigned int modeflags, int no_close) @@ -924,7 +922,7 @@ *cookie = fp_cookie; err = 0; } - + return err; } @@ -948,12 +946,10 @@ /* Write function for FILE* objects. */ static ssize_t es_func_fp_write (void *cookie, const void *buffer, size_t size) - { estream_cookie_fp_t file_cookie = cookie; size_t bytes_written; - if (file_cookie->fp) { #ifdef HAVE_W32_SYSTEM @@ -1285,10 +1281,7 @@ stream->intern->func_close = functions.func_close; stream->intern->strategy = _IOFBF; stream->intern->fd = fd; - stream->intern->print_err = 0; - stream->intern->print_errno = 0; stream->intern->print_ntotal = 0; - stream->intern->print_fp = NULL; stream->intern->indicators.err = 0; stream->intern->indicators.eof = 0; stream->intern->is_stdstream = 0; @@ -1319,14 +1312,6 @@ es_cookie_close_function_t func_close; int err, tmp_err; - if (stream->intern->print_fp) - { - int save_errno = errno; - fclose (stream->intern->print_fp); - stream->intern->print_fp = NULL; - _set_errno (save_errno); - } - func_close = stream->intern->func_close; err = 0; @@ -3205,6 +3190,38 @@ return ret; } + +int +es_printf_unlocked (const char *ES__RESTRICT format, ...) +{ + int ret; + + va_list ap; + va_start (ap, format); + ret = es_print (es_stdout, format, ap); + va_end (ap); + + return ret; +} + + +int +es_printf (const char *ES__RESTRICT format, ...) +{ + int ret; + estream_t stream = es_stdout; + + va_list ap; + va_start (ap, format); + ESTREAM_LOCK (stream); + ret = es_print (stream, format, ap); + ESTREAM_UNLOCK (stream); + va_end (ap); + + return ret; +} + + /* A variant of asprintf. The function returns the allocated buffer or NULL on error; ERRNO is set in the error case. The caller should use es_free to release the buffer. This function actually Modified: trunk/common/estream.h =================================================================== --- trunk/common/estream.h 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/common/estream.h 2010-08-18 19:25:15 UTC (rev 5397) @@ -121,6 +121,8 @@ #define es_free _ESTREAM_PREFIX(es_free) #define es_fprintf _ESTREAM_PREFIX(es_fprintf) #define es_fprintf_unlocked _ESTREAM_PREFIX(es_fprintf_unlocked) +#define es_printf _ESTREAM_PREFIX(es_printf) +#define es_printf_unlocked _ESTREAM_PREFIX(es_printf_unlocked) #define es_vfprintf _ESTREAM_PREFIX(es_vfprint) #define es_vfprintf_unlocked _ESTREAM_PREFIX(es_vfprint_unlocked) #define es_setvbuf _ESTREAM_PREFIX(es_setvbuf) @@ -345,6 +347,11 @@ const char *ES__RESTRICT format, ...) _ESTREAM_GCC_A_PRINTF(2,3); +int es_printf (const char *ES__RESTRICT format, ...) + _ESTREAM_GCC_A_PRINTF(1,2); +int es_printf_unlocked (const char *ES__RESTRICT format, ...) + _ESTREAM_GCC_A_PRINTF(1,2); + int es_vfprintf (estream_t ES__RESTRICT stream, const char *ES__RESTRICT format, va_list ap) _ESTREAM_GCC_A_PRINTF(2,0); Modified: trunk/common/logging.c =================================================================== --- trunk/common/logging.c 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/common/logging.c 2010-08-18 19:25:15 UTC (rev 5397) @@ -120,19 +120,24 @@ /* Write NBYTES of BUFFER to file descriptor FD. */ static int -writen (int fd, const void *buffer, size_t nbytes) +writen (int fd, const void *buffer, size_t nbytes, int is_socket) { const char *buf = buffer; size_t nleft = nbytes; int nwritten; +#ifndef HAVE_W32_SYSTEM + (void)is_socket; /* Not required. */ +#endif while (nleft > 0) { #ifdef HAVE_W32_SYSTEM - nwritten = send (fd, buf, nleft, 0); -#else - nwritten = write (fd, buf, nleft); + if (is_socket) + nwritten = send (fd, buf, nleft, 0); + else #endif + nwritten = write (fd, buf, nleft); + if (nwritten < 0 && errno == EINTR) continue; if (nwritten < 0) @@ -171,6 +176,9 @@ { struct fun_cookie_s *cookie = cookie_arg; + /* FIXME: Use only estream with a callback for socket writing. This + avoids the ugly mix of fd and estream code. */ + /* Note that we always try to reconnect to the socket but print error messages only the first time an error occured. If RUNNING_DETACHED is set we don't fall back to stderr and even do @@ -345,7 +353,7 @@ } log_socket = cookie->fd; - if (cookie->fd != -1 && !writen (cookie->fd, buffer, size)) + if (cookie->fd != -1 && !writen (cookie->fd, buffer, size, cookie->is_socket)) return (ssize_t)size; /* Okay. */ if (!running_detached && cookie->fd != -1 @@ -561,7 +569,16 @@ { if (!logstream) { +#ifdef HAVE_W32_SYSTEM + char *tmp; + + tmp = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", + "DefaultLogFile"); + log_set_file (tmp); + jnlib_free (tmp); +#else log_set_file (NULL); /* Make sure a log stream has been set. */ +#endif assert (logstream); } Modified: trunk/common/logging.h =================================================================== --- trunk/common/logging.h 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/common/logging.h 2010-08-18 19:25:15 UTC (rev 5397) @@ -24,6 +24,7 @@ #include #include "estream.h" #include "mischelp.h" +#include "w32help.h" /* Flag values for log_set_prefix. */ #define JNLIB_LOG_WITH_PREFIX 1 Modified: trunk/doc/tools.texi =================================================================== --- trunk/doc/tools.texi 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/doc/tools.texi 2010-08-18 19:25:15 UTC (rev 5397) @@ -42,12 +42,13 @@ @end ifset @mansect description -Most of the main utilities are able to write their log files to a -Unix Domain socket if configured that way. @command{watchgnupg} is a simple -listener for such a socket. It ameliorates the output with a time -stamp and makes sure that long lines are not interspersed with log -output from other utilities. +Most of the main utilities are able to write their log files to a Unix +Domain socket if configured that way. @command{watchgnupg} is a simple +listener for such a socket. It ameliorates the output with a time stamp +and makes sure that long lines are not interspersed with log output from +other utilities. This tool is not available for Windows. + @noindent @command{watchgnupg} is commonly invoked as @@ -70,6 +71,10 @@ @opindex force Delete an already existing socket file. + at item --tcp @var{n} +Instead of reading from a local socket, listen for connects on TCP port + at var{n}. + @item --verbose @opindex verbose Enable extra informational output. @@ -84,6 +89,41 @@ @end table + at noindent + at mansect examples + at chapheading Examples + + at example +$ watchgnupg --force /home/foo/.gnupg/S.log + at end example + +This waits for connections on the local socket + at file{/home/foo/.gnupg/S.log} and shows all log entries. To make this +work the option @option{log-file} needs to be used with all modules +which logs are to be shown. The value for that option must be given +with a special prefix (e.g. in the conf file): + + at example +log-file socket:///home/foo/.gnupg/S.log + at end example + +For debugging purposes it is also possible to do remote logging. Take +care if you use this feature because the information is send in the +clear over the network. Use this syntax in the conf files: + + at example +log-file tcp://192.168.1.1:4711 + at end example + +You may use any port and not just 4711 as shown above; only IP addresses +are supported (v4 and v6) and no host names. You need to start + at command{watchgnupg} with the @option{tcp} option. Note that under +Windows the registry entry @var{HKCU\Software\GNU\GnuPG:DefaultLogFile} +can be used to change the default log output from @code{stderr} to +whatever is given by that entry. However the only useful entry is a TCP +name for remote debugging. + + @mansect see also @ifset isman @command{gpg}(1), Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/g10/gpg.c 2010-08-18 19:25:15 UTC (rev 5397) @@ -1449,8 +1449,8 @@ if(first) first=0; else - printf(";"); - printf("%d",i); + es_printf (";"); + es_printf ("%d",i); } } } @@ -1468,8 +1468,8 @@ if(first) first=0; else - printf(";"); - printf("%s",mapper(i)); + es_printf (";"); + es_printf ("%s",mapper(i)); } } } @@ -1508,10 +1508,10 @@ { print_sanitized_string2 (stdout, sl->d, ':',';'); if(sl->next) - printf(";"); + es_printf(";"); } - printf("\n"); + es_printf("\n"); } any=1; @@ -1519,33 +1519,33 @@ if(show_all || ascii_strcasecmp(name,"version")==0) { - printf("cfg:version:"); + es_printf("cfg:version:"); es_write_sanitized (es_stdout, VERSION, strlen(VERSION), ":", NULL); - printf("\n"); + es_printf ("\n"); any=1; } if(show_all || ascii_strcasecmp(name,"pubkey")==0) { - printf("cfg:pubkey:"); + es_printf ("cfg:pubkey:"); print_algo_numbers (openpgp_pk_test_algo); - printf("\n"); + es_printf ("\n"); any=1; } if(show_all || ascii_strcasecmp(name,"cipher")==0) { - printf("cfg:cipher:"); + es_printf ("cfg:cipher:"); print_algo_numbers(openpgp_cipher_test_algo); - printf("\n"); + es_printf ("\n"); any=1; } if (show_all || !ascii_strcasecmp (name,"ciphername")) { - printf ("cfg:ciphername:"); + es_printf ("cfg:ciphername:"); print_algo_names (openpgp_cipher_test_algo,openpgp_cipher_algo_name); - printf ("\n"); + es_printf ("\n"); any = 1; } @@ -1553,9 +1553,9 @@ || ascii_strcasecmp(name,"digest")==0 || ascii_strcasecmp(name,"hash")==0) { - printf("cfg:digest:"); + es_printf ("cfg:digest:"); print_algo_numbers(openpgp_md_test_algo); - printf("\n"); + es_printf ("\n"); any=1; } @@ -1563,17 +1563,17 @@ || !ascii_strcasecmp(name,"digestname") || !ascii_strcasecmp(name,"hashname")) { - printf ("cfg:digestname:"); + es_printf ("cfg:digestname:"); print_algo_names (openpgp_md_test_algo, gcry_md_algo_name); - printf("\n"); + es_printf ("\n"); any=1; } if(show_all || ascii_strcasecmp(name,"compress")==0) { - printf("cfg:compress:"); + es_printf ("cfg:compress:"); print_algo_numbers(check_compress_algo); - printf("\n"); + es_printf ("\n"); any=1; } @@ -1587,7 +1587,7 @@ for (p=list; p && (p2 = strchr (p, '\n')); p = p2+1) { *p2 = 0; - printf("cfg:ccid-reader-id:%s\n", p); + es_printf ("cfg:ccid-reader-id:%s\n", p); } free (list); #endif @@ -1613,23 +1613,24 @@ { char *configfile_esc = percent_escape (configfile, NULL); - printf ("gpgconf-gpg.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, configfile_esc ? configfile_esc : "/dev/null"); - printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE); - printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE); - printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE); - printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE); - printf ("default-key:%lu:\n", GC_OPT_FLAG_NONE); - printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE); - printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE); - printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE); - printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT); - printf ("group:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("gpgconf-gpg.conf:%lu:\"%s\n", + GC_OPT_FLAG_DEFAULT, + configfile_esc ? configfile_esc : "/dev/null"); + es_printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("default-key:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("auto-key-locate:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT); + es_printf ("group:%lu:\n", GC_OPT_FLAG_NONE); /* The next one is an info only item and should match the macros at the top of keygen.c */ - printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, - "RSA-2048"); + es_printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, + "RSA-2048"); xfree (configfile_esc); } @@ -2992,11 +2993,12 @@ if( nogreeting ) greeting = 0; - if( greeting ) { - fprintf(stderr, "%s %s; %s\n", - strusage(11), strusage(13), strusage(14) ); - fprintf(stderr, "%s\n", strusage(15) ); - } + if( greeting ) + { + es_fprintf (es_stderr, "%s %s; %s\n", + strusage(11), strusage(13), strusage(14) ); + es_fprintf (es_stderr, "%s\n", strusage(15) ); + } #ifdef IS_DEVELOPMENT_VERSION if (!opt.batch) { @@ -4092,33 +4094,33 @@ display, but there are a few other similar assumptions in the display code. */ static void -print_hex( gcry_md_hd_t md, int algo, const char *fname ) +print_hex (gcry_md_hd_t md, int algo, const char *fname) { int i,n,count,indent=0; const byte *p; - if(fname) - indent=printf("%s: ",fname); + if (fname) + indent = es_printf("%s: ",fname); - if(indent>40) + if (indent>40) { printf("\n"); indent=0; } - if(algo==DIGEST_ALGO_RMD160) - indent+=printf("RMD160 = "); - else if(algo>0) - indent+=printf("%6s = ", gcry_md_algo_name (algo)); + if (algo==DIGEST_ALGO_RMD160) + indent += es_printf("RMD160 = "); + else if (algo>0) + indent += es_printf("%6s = ", gcry_md_algo_name (algo)); else - algo=abs(algo); + algo = abs(algo); - count=indent; + count = indent; p = gcry_md_read (md, algo); n = gcry_md_get_algo_dlen (algo); - count += printf ("%02X",*p++); + count += es_printf ("%02X",*p++); for(i=1;i79) { - printf("\n%*s",indent," "); - count=indent; + es_printf ("\n%*s",indent," "); + count = indent; } else - count+=printf(" "); + count += es_printf(" "); - if(!(i%8)) - count+=printf(" "); + if (!(i%8)) + count += es_printf(" "); } else if (n==20) { @@ -4141,58 +4143,59 @@ { if(count+4>79) { - printf("\n%*s",indent," "); + es_printf ("\n%*s",indent," "); count=indent; } else - count+=printf(" "); + count += es_printf(" "); } - if(!(i%10)) - count+=printf(" "); + if (!(i%10)) + count += es_printf(" "); } else { if(!(i%4)) { - if(count+8>79) + if (count+8>79) { - printf("\n%*s",indent," "); + es_printf ("\n%*s",indent," "); count=indent; } else - count+=printf(" "); + count += es_printf(" "); } } - count+=printf("%02X",*p); + count += es_printf("%02X",*p); } - printf("\n"); + es_printf ("\n"); } static void print_hashline( gcry_md_hd_t md, int algo, const char *fname ) { - int i, n; - const byte *p; + int i, n; + const byte *p; - if ( fname ) { - for (p = fname; *p; p++ ) { - if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' ) - printf("%%%02X", *p ); - else - putchar( *p ); + if ( fname ) + { + for (p = fname; *p; p++ ) + { + if ( *p <= 32 || *p > 127 || *p == ':' || *p == '%' ) + es_printf ("%%%02X", *p ); + else + es_putc (*p, es_stdout); } } - putchar(':'); - printf("%d:", algo ); - p = gcry_md_read (md, algo); - n = gcry_md_get_algo_dlen (algo); - for(i=0; i < n ; i++, p++ ) - printf("%02X", *p ); - putchar(':'); - putchar('\n'); + es_putc (':', es_stdout); + es_printf ("%d:", algo); + p = gcry_md_read (md, algo); + n = gcry_md_get_algo_dlen (algo); + for(i=0; i < n ; i++, p++ ) + es_printf ("%02X", *p); + es_fputs (":\n", es_stdout); } static void Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/scd/scdaemon.c 2010-08-18 19:25:15 UTC (rev 5397) @@ -617,9 +617,9 @@ if (greeting) { - fprintf (stderr, "%s %s; %s\n", - strusage(11), strusage(13), strusage(14) ); - fprintf (stderr, "%s\n", strusage(15) ); + es_fprintf (es_stderr, "%s %s; %s\n", + strusage(11), strusage(13), strusage(14) ); + es_fprintf (es_stderr, "%s\n", strusage(15) ); } #ifdef IS_DEVELOPMENT_VERSION log_info ("NOTE: this is a development version!\n"); @@ -651,30 +651,30 @@ filename = make_filename (opt.homedir, "scdaemon.conf", NULL); filename_esc = percent_escape (filename, NULL); - printf ("gpgconf-scdaemon.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, filename_esc); + es_printf ("gpgconf-scdaemon.conf:%lu:\"%s\n", + GC_OPT_FLAG_DEFAULT, filename_esc); xfree (filename_esc); xfree (filename); - printf ("verbose:%lu:\n" - "quiet:%lu:\n" - "debug-level:%lu:\"none:\n" - "log-file:%lu:\n", - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_NONE, - GC_OPT_FLAG_DEFAULT, - GC_OPT_FLAG_NONE ); + es_printf ("verbose:%lu:\n" + "quiet:%lu:\n" + "debug-level:%lu:\"none:\n" + "log-file:%lu:\n", + GC_OPT_FLAG_NONE, + GC_OPT_FLAG_NONE, + GC_OPT_FLAG_DEFAULT, + GC_OPT_FLAG_NONE ); - printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE ); - printf ("ctapi-driver:%lu:\n", GC_OPT_FLAG_NONE ); - printf ("pcsc-driver:%lu:\"%s:\n", + es_printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE ); + es_printf ("ctapi-driver:%lu:\n", GC_OPT_FLAG_NONE ); + es_printf ("pcsc-driver:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, DEFAULT_PCSC_DRIVER ); #ifdef HAVE_LIBUSB - printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE ); + es_printf ("disable-ccid:%lu:\n", GC_OPT_FLAG_NONE ); #endif - printf ("deny-admin:%lu:\n", GC_OPT_FLAG_NONE ); - printf ("disable-keypad:%lu:\n", GC_OPT_FLAG_NONE ); - printf ("card-timeout:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, 0); + es_printf ("deny-admin:%lu:\n", GC_OPT_FLAG_NONE ); + es_printf ("disable-keypad:%lu:\n", GC_OPT_FLAG_NONE ); + es_printf ("card-timeout:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, 0); scd_exit (0); } @@ -831,11 +831,11 @@ if (csh_style) { *strchr (infostr, '=') = ' '; - printf ( "setenv %s\n", infostr); + es_printf ( "setenv %s\n", infostr); } else { - printf ( "%s; export SCDAEMON_INFO;\n", infostr); + es_printf ( "%s; export SCDAEMON_INFO;\n", infostr); } xfree (infostr); exit (0); Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/sm/gpgsm.c 2010-08-18 19:25:15 UTC (rev 5397) @@ -908,7 +908,7 @@ log_set_prefix ("gpgsm", 1); /* Make sure that our subsystems are ready. */ - i18n_init(); + i18n_init (); init_common_subsystems (&argc, &argv); /* Check that the libraries are suitable. Do it here because the @@ -1429,9 +1429,9 @@ if (greeting) { - fprintf(stderr, "%s %s; %s\n", - strusage(11), strusage(13), strusage(14) ); - fprintf(stderr, "%s\n", strusage(15) ); + es_fprintf (es_stderr, "%s %s; %s\n", + strusage(11), strusage(13), strusage(14) ); + es_fprintf (es_stderr, "%s\n", strusage(15) ); } # ifdef IS_DEVELOPMENT_VERSION if (!opt.batch) @@ -1638,33 +1638,33 @@ { /* List options and default values in the GPG Conf format. */ char *config_filename_esc = percent_escape (opt.config_filename, NULL); - printf ("gpgconf-gpgsm.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, config_filename_esc); + es_printf ("gpgconf-gpgsm.conf:%lu:\"%s\n", + GC_OPT_FLAG_DEFAULT, config_filename_esc); xfree (config_filename_esc); - printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE); - printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE); - printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT); - printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE); - printf ("disable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE); - printf ("disable-trusted-cert-crl-check:%lu:\n", GC_OPT_FLAG_NONE); - printf ("enable-ocsp:%lu:\n", GC_OPT_FLAG_NONE); - printf ("include-certs:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, - DEFAULT_INCLUDE_CERTS); - printf ("disable-policy-checks:%lu:\n", GC_OPT_FLAG_NONE); - printf ("auto-issuer-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE); - printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); - printf ("cipher-algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, - DEFAULT_CIPHER_ALGO); - printf ("p12-charset:%lu:\n", GC_OPT_FLAG_DEFAULT); - printf ("default-key:%lu:\n", GC_OPT_FLAG_DEFAULT); - printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_DEFAULT); - printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("debug-level:%lu:\"none:\n", GC_OPT_FLAG_DEFAULT); + es_printf ("log-file:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("disable-crl-checks:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("disable-trusted-cert-crl-check:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("enable-ocsp:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("include-certs:%lu:%d:\n", GC_OPT_FLAG_DEFAULT, + DEFAULT_INCLUDE_CERTS); + es_printf ("disable-policy-checks:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("auto-issuer-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("disable-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); + es_printf ("cipher-algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, + DEFAULT_CIPHER_ALGO); + es_printf ("p12-charset:%lu:\n", GC_OPT_FLAG_DEFAULT); + es_printf ("default-key:%lu:\n", GC_OPT_FLAG_DEFAULT); + es_printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_DEFAULT); + es_printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE); /* The next one is an info only item and should match what proc_parameters actually implements. */ - printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, - "RSA-2048"); + es_printf ("default_pubkey_algo:%lu:\"%s:\n", GC_OPT_FLAG_DEFAULT, + "RSA-2048"); } break; Modified: trunk/tools/gpg-connect-agent.c =================================================================== --- trunk/tools/gpg-connect-agent.c 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/tools/gpg-connect-agent.c 2010-08-18 19:25:15 UTC (rev 5397) @@ -994,7 +994,9 @@ if (fd >= 0 && fd < DIM (open_fd_table)) { open_fd_table[fd].inuse = 1; -#warning fixme: implement our pipe emulation. +#ifdef HAVE_W32CE_SYSTEM +# warning fixme: implement our pipe emulation. +#endif #if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM) { HANDLE prochandle, handle, newhandle; @@ -1246,11 +1248,11 @@ if (opt.exec) { - int no_close[3]; + assuan_fd_t no_close[3]; - no_close[0] = assuan_fd_from_posix_fd (fileno (stderr)); + no_close[0] = assuan_fd_from_posix_fd (es_fileno (es_stderr)); no_close[1] = assuan_fd_from_posix_fd (log_get_fd ()); - no_close[2] = -1; + no_close[2] = ASSUAN_INVALID_FD; rc = assuan_new (&ctx); if (rc) Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/tools/gpgconf-comp.c 2010-08-18 19:25:15 UTC (rev 5397) @@ -1284,7 +1284,7 @@ /* List all components that are available. */ void -gc_component_list_components (FILE *out) +gc_component_list_components (estream_t out) { gc_component_t component; gc_option_t *option; @@ -1320,9 +1320,9 @@ desc = gc_component[component].desc; desc = my_dgettext (gc_component[component].desc_domain, desc); - fprintf (out, "%s:%s:", - gc_component[component].name, gc_percent_escape (desc)); - fprintf (out, "%s\n", gc_percent_escape (pgmname)); + es_fprintf (out, "%s:%s:", + gc_component[component].name, gc_percent_escape (desc)); + es_fprintf (out, "%s\n", gc_percent_escape (pgmname)); } } } @@ -1432,7 +1432,7 @@ /* Check the options of a single component. Returns 0 if everything is OK. */ int -gc_component_check_options (int component, FILE *out, const char *conf_file) +gc_component_check_options (int component, estream_t out, const char *conf_file) { gpg_error_t err; unsigned int result; @@ -1525,24 +1525,24 @@ desc = gc_component[component].desc; desc = my_dgettext (gc_component[component].desc_domain, desc); - fprintf (out, "%s:%s:", - gc_component[component].name, gc_percent_escape (desc)); - fputs (gc_percent_escape (pgmname), out); - fprintf (out, ":%d:%d:", !(result & 1), !(result & 2)); + es_fprintf (out, "%s:%s:", + gc_component[component].name, gc_percent_escape (desc)); + es_fputs (gc_percent_escape (pgmname), out); + es_fprintf (out, ":%d:%d:", !(result & 1), !(result & 2)); for (errptr = errlines; errptr; errptr = errptr->next) { if (errptr != errlines) - fputs ("\n:::::", out); /* Continuation line. */ + es_fputs ("\n:::::", out); /* Continuation line. */ if (errptr->fname) - fputs (gc_percent_escape (errptr->fname), out); - putc (':', out); + es_fputs (gc_percent_escape (errptr->fname), out); + es_putc (':', out); if (errptr->fname) - fprintf (out, "%u", errptr->lineno); - putc (':', out); - fputs (gc_percent_escape (errptr->errtext), out); - putc (':', out); + es_fprintf (out, "%u", errptr->lineno); + es_putc (':', out); + es_fputs (gc_percent_escape (errptr->errtext), out); + es_putc (':', out); } - putc ('\n', out); + es_putc ('\n', out); } while (errlines) @@ -1558,7 +1558,7 @@ /* Check all components that are available. */ void -gc_check_programs (FILE *out) +gc_check_programs (estream_t out) { gc_component_t component; @@ -1587,7 +1587,7 @@ /* List the option OPTION. */ static void -list_one_option (const gc_option_t *option, FILE *out) +list_one_option (const gc_option_t *option, estream_t out) { const char *desc = NULL; char *arg_name = NULL; @@ -1617,16 +1617,16 @@ FIELDS. */ /* The name field. */ - fprintf (out, "%s", option->name); + es_fprintf (out, "%s", option->name); /* The flags field. */ - fprintf (out, ":%lu", option->flags); + es_fprintf (out, ":%lu", option->flags); if (opt.verbose) { - putc (' ', out); + es_putc (' ', out); if (!option->flags) - fprintf (out, "none"); + es_fprintf (out, "none"); else { unsigned long flags = option->flags; @@ -1640,8 +1640,8 @@ if (first) first = 0; else - putc (',', out); - fprintf (out, "%s", gc_flag[flag].name); + es_putc (',', out); + es_fprintf (out, "%s", gc_flag[flag].name); } flags >>= 1; flag++; @@ -1650,34 +1650,33 @@ } /* The level field. */ - fprintf (out, ":%u", option->level); + es_fprintf (out, ":%u", option->level); if (opt.verbose) - fprintf (out, " %s", gc_level[option->level].name); + es_fprintf (out, " %s", gc_level[option->level].name); /* The description field. */ - fprintf (out, ":%s", desc ? gc_percent_escape (desc) : ""); + es_fprintf (out, ":%s", desc ? gc_percent_escape (desc) : ""); /* The type field. */ - fprintf (out, ":%u", option->arg_type); + es_fprintf (out, ":%u", option->arg_type); if (opt.verbose) - fprintf (out, " %s", gc_arg_type[option->arg_type].name); + es_fprintf (out, " %s", gc_arg_type[option->arg_type].name); /* The alternate type field. */ - fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback); + es_fprintf (out, ":%u", gc_arg_type[option->arg_type].fallback); if (opt.verbose) - fprintf (out, " %s", - gc_arg_type[gc_arg_type[option->arg_type].fallback].name); + es_fprintf (out, " %s", + gc_arg_type[gc_arg_type[option->arg_type].fallback].name); /* The argument name field. */ - fprintf (out, ":%s", arg_name ? gc_percent_escape (arg_name) : ""); - if (arg_name) - xfree (arg_name); + es_fprintf (out, ":%s", arg_name ? gc_percent_escape (arg_name) : ""); + xfree (arg_name); /* The default value field. */ - fprintf (out, ":%s", option->default_value ? option->default_value : ""); + es_fprintf (out, ":%s", option->default_value ? option->default_value : ""); /* The default argument field. */ - fprintf (out, ":%s", option->default_arg ? option->default_arg : ""); + es_fprintf (out, ":%s", option->default_arg ? option->default_arg : ""); /* The value field. */ if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_NONE @@ -1685,19 +1684,19 @@ && option->value) /* The special format "1,1,1,1,...,1" is converted to a number here. */ - fprintf (out, ":%u", (unsigned int)((strlen (option->value) + 1) / 2)); + es_fprintf (out, ":%u", (unsigned int)((strlen (option->value) + 1) / 2)); else - fprintf (out, ":%s", option->value ? option->value : ""); + es_fprintf (out, ":%s", option->value ? option->value : ""); /* ADD NEW FIELDS HERE. */ - putc ('\n', out); + es_putc ('\n', out); } /* List all options of the component COMPONENT. */ void -gc_component_list_options (int component, FILE *out) +gc_component_list_options (int component, estream_t out) { const gc_option_t *option = gc_component[component].options; @@ -2980,7 +2979,7 @@ modifications are expected to already have been set to the global table. */ void -gc_component_change_options (int component, FILE *in, FILE *out) +gc_component_change_options (int component, estream_t in, estream_t out) { int err = 0; int runtime[GC_BACKEND_NR]; @@ -3004,7 +3003,7 @@ if (in) { /* Read options from the file IN. */ - while ((length = read_line (in, &line, &line_len, NULL)) > 0) + while ((length = es_read_line (in, &line, &line_len, NULL)) > 0) { char *linep; unsigned long flags = 0; @@ -3347,7 +3346,7 @@ returned on error. */ int gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults, - FILE *listfp) + estream_t listfp) { int result = 0; char *line = NULL; @@ -3560,19 +3559,19 @@ *p = 0; /* We better strip any extra stuff. */ } - fprintf (listfp, "k:%s:", gc_percent_escape (key)); - fprintf (listfp, "%s\n", group? gc_percent_escape (group):""); + es_fprintf (listfp, "k:%s:", gc_percent_escape (key)); + es_fprintf (listfp, "%s\n", group? gc_percent_escape (group):""); } /* All other lines are rule records. */ - fprintf (listfp, "r:::%s:%s:%s:", - gc_component[component_id].name, - option_info->name? option_info->name : "", - flags? flags : ""); + es_fprintf (listfp, "r:::%s:%s:%s:", + gc_component[component_id].name, + option_info->name? option_info->name : "", + flags? flags : ""); if (value != empty) - fprintf (listfp, "\"%s", gc_percent_escape (value)); + es_fprintf (listfp, "\"%s", gc_percent_escape (value)); - putc ('\n', listfp); + es_putc ('\n', listfp); } /* Check whether the key matches but do this only if we are not Modified: trunk/tools/gpgconf.c =================================================================== --- trunk/tools/gpgconf.c 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/tools/gpgconf.c 2010-08-18 19:25:15 UTC (rev 5397) @@ -118,19 +118,19 @@ /* Return the fp for the output. This is usually stdout unless --output has been used. In the latter case this function opens that file. */ -static FILE * -get_outfp (FILE **fp) +static estream_t +get_outfp (estream_t *fp) { if (!*fp) { if (opt.outfile) { - *fp = fopen (opt.outfile, "w"); + *fp = es_fopen (opt.outfile, "w"); if (!*fp) gc_error (1, errno, "can not open `%s'", opt.outfile); } else - *fp = stdout; + *fp = es_stdout; } return *fp; } @@ -144,7 +144,7 @@ const char *fname; int no_more_options = 0; enum cmd_and_opt_values cmd = 0; - FILE *outfp = NULL; + estream_t outfp = NULL; gnupg_reopen_std ("gpgconf"); set_strusage (my_strusage); @@ -211,10 +211,10 @@ case aCheckOptions: if (!fname) { - fputs (_("usage: gpgconf [options] "), stderr); - putc ('\n',stderr); - fputs (_("Need one component argument"), stderr); - putc ('\n',stderr); + es_fputs (_("usage: gpgconf [options] "), es_stderr); + es_putc ('\n', es_stderr); + es_fputs (_("Need one component argument"), es_stderr); + es_putc ('\n', es_stderr); exit (2); } else @@ -222,8 +222,8 @@ int idx = gc_component_find (fname); if (idx < 0) { - fputs (_("Component not found"), stderr); - putc ('\n', stderr); + es_fputs (_("Component not found"), es_stderr); + es_putc ('\n', es_stderr); exit (1); } gc_component_retrieve_options (idx); @@ -232,7 +232,7 @@ if (cmd == aListOptions) gc_component_list_options (idx, get_outfp (&outfp)); else if (cmd == aChangeOptions) - gc_component_change_options (idx, stdin, get_outfp (&outfp)); + gc_component_change_options (idx, es_stdin, get_outfp (&outfp)); else gc_component_check_options (idx, get_outfp (&outfp), NULL); } @@ -252,8 +252,8 @@ idx = gc_component_find (fname); if (idx < 0) { - fputs (_("Component not found"), stderr); - putc ('\n', stderr); + es_fputs (_("Component not found"), es_stderr); + es_putc ('\n', es_stderr); exit (1); } else @@ -276,10 +276,10 @@ case aApplyDefaults: if (fname) { - fputs (_("usage: gpgconf [options] "), stderr); - putc ('\n',stderr); - fputs (_("No argument allowed"), stderr); - putc ('\n',stderr); + es_fputs (_("usage: gpgconf [options] "), es_stderr); + es_putc ('\n', es_stderr); + es_fputs (_("No argument allowed"), es_stderr); + es_putc ('\n', es_stderr); exit (2); } gc_component_retrieve_options (-1); @@ -290,20 +290,20 @@ case aListDirs: /* Show the system configuration directories for gpgconf. */ get_outfp (&outfp); - fprintf (outfp, "sysconfdir:%s\n", - gc_percent_escape (gnupg_sysconfdir ())); - fprintf (outfp, "bindir:%s\n", - gc_percent_escape (gnupg_bindir ())); - fprintf (outfp, "libexecdir:%s\n", - gc_percent_escape (gnupg_libexecdir ())); - fprintf (outfp, "libdir:%s\n", - gc_percent_escape (gnupg_libdir ())); - fprintf (outfp, "datadir:%s\n", - gc_percent_escape (gnupg_datadir ())); - fprintf (outfp, "localedir:%s\n", - gc_percent_escape (gnupg_localedir ())); - fprintf (outfp, "dirmngr-socket:%s\n", - gc_percent_escape (dirmngr_socket_name ())); + es_fprintf (outfp, "sysconfdir:%s\n", + gc_percent_escape (gnupg_sysconfdir ())); + es_fprintf (outfp, "bindir:%s\n", + gc_percent_escape (gnupg_bindir ())); + es_fprintf (outfp, "libexecdir:%s\n", + gc_percent_escape (gnupg_libexecdir ())); + es_fprintf (outfp, "libdir:%s\n", + gc_percent_escape (gnupg_libdir ())); + es_fprintf (outfp, "datadir:%s\n", + gc_percent_escape (gnupg_datadir ())); + es_fprintf (outfp, "localedir:%s\n", + gc_percent_escape (gnupg_localedir ())); + es_fprintf (outfp, "dirmngr-socket:%s\n", + gc_percent_escape (dirmngr_socket_name ())); { char *infostr = getenv ("GPG_AGENT_INFO"); @@ -323,21 +323,21 @@ else *tmp = 0; } - fprintf (outfp, "agent-socket:%s\n", - infostr? gc_percent_escape (infostr) : ""); + es_fprintf (outfp, "agent-socket:%s\n", + infostr? gc_percent_escape (infostr) : ""); xfree (infostr); } { /* We need to use make_filename to expand a possible "~/". */ char *tmp = make_filename (default_homedir (), NULL); - fprintf (outfp, "homedir:%s\n", gc_percent_escape (tmp)); + es_fprintf (outfp, "homedir:%s\n", gc_percent_escape (tmp)); xfree (tmp); } break; } - if (outfp && outfp != stdout) - if (fclose (outfp)) + if (outfp != es_stdout) + if (es_fclose (outfp)) gc_error (1, errno, "error closing `%s'", opt.outfile); return 0; Modified: trunk/tools/gpgconf.h =================================================================== --- trunk/tools/gpgconf.h 2010-08-16 11:03:43 UTC (rev 5396) +++ trunk/tools/gpgconf.h 2010-08-18 19:25:15 UTC (rev 5397) @@ -48,10 +48,10 @@ void gc_component_reload (int component); /* List all components that are available. */ -void gc_component_list_components (FILE *out); +void gc_component_list_components (estream_t out); /* List all programs along with their status. */ -void gc_check_programs (FILE *out); +void gc_check_programs (estream_t out); /* Find the component with the name NAME. Returns -1 if not found. */ @@ -62,19 +62,19 @@ void gc_component_retrieve_options (int component); /* List all options of the component COMPONENT. */ -void gc_component_list_options (int component, FILE *out); +void gc_component_list_options (int component, estream_t out); /* Read the modifications from IN and apply them. */ -void gc_component_change_options (int component, FILE *in, FILE *out); +void gc_component_change_options (int component, estream_t in, estream_t out); /* Check the options of a single component. Returns 0 if everything is OK. */ -int gc_component_check_options (int component, FILE *out, +int gc_component_check_options (int component, estream_t out, const char *conf_file); /* Process global configuration file. */ int gc_process_gpgconf_conf (const char *fname, int update, int defaults, - FILE *listfp); + estream_t listfp); #endif /*GPGCONF_H*/ From cvs at cvs.gnupg.org Thu Aug 19 11:53:56 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 11:53:56 +0200 Subject: [svn] GnuPG - r5398 - in trunk: doc tools Message-ID: Author: wk Date: 2010-08-19 11:53:55 +0200 (Thu, 19 Aug 2010) New Revision: 5398 Modified: trunk/doc/gpg-agent.texi trunk/tools/ChangeLog trunk/tools/gpgconf-comp.c Log: Add component pinentry as an easy way to figure out the default pinentry. Also allows to test whether pinentry is installed. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2010-08-18 19:25:15 UTC (rev 5397) +++ trunk/tools/ChangeLog 2010-08-19 09:53:55 UTC (rev 5398) @@ -1,3 +1,10 @@ +2010-08-19 Werner Koch + + * gpgconf-comp.c: Add new backend and component for PINENTRY. + (gc_component_check_options): Use --version to test the pinentry. + (gc_component_retrieve_options, gc_component_change_options): + Ignore the pinentry component. + 2010-08-16 Werner Koch * gpgconf.c (get_outfp): Change to use estream. Modified: trunk/doc/gpg-agent.texi =================================================================== --- trunk/doc/gpg-agent.texi 2010-08-18 19:25:15 UTC (rev 5397) +++ trunk/doc/gpg-agent.texi 2010-08-19 09:53:55 UTC (rev 5398) @@ -399,7 +399,7 @@ @item --pinentry-program @var{filename} @opindex pinentry-program Use program @var{filename} as the PIN entry. The default is installation -dependent and can be shown with the @code{--version} command. +dependent. @item --pinentry-touch-file @var{filename} @opindex pinentry-touch-file @@ -415,7 +415,7 @@ @item --scdaemon-program @var{filename} @opindex scdaemon-program Use program @var{filename} as the Smartcard daemon. The default is -installation dependent and can be shown with the @code{--version} +installation dependent and can be shown with the @command{gpgconf} command. @item --disable-scdaemon Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2010-08-18 19:25:15 UTC (rev 5397) +++ trunk/tools/gpgconf-comp.c 2010-08-19 09:53:55 UTC (rev 5398) @@ -133,12 +133,15 @@ /* The GnuPG SCDaemon. */ GC_BACKEND_SCDAEMON, - /* The Aegypten directory manager. */ + /* The GnuPG directory manager. */ GC_BACKEND_DIRMNGR, - /* The LDAP server list file for the Aegypten director manager. */ + /* The LDAP server list file for the director manager. */ GC_BACKEND_DIRMNGR_LDAP_SERVER_LIST, + /* The Pinentry (not a part of GnuPG, proper). */ + GC_BACKEND_PINENTRY, + /* The number of the above entries. */ GC_BACKEND_NR } gc_backend_t; @@ -158,7 +161,7 @@ /* The module name (GNUPG_MODULE_NAME_foo) as defined by ../common/util.h. This value is used to get the actual installed - path of the program. 0 is used if no backedn program is + path of the program. 0 is used if no backend program is available. */ char module_name; @@ -189,6 +192,8 @@ NULL, "gpgconf-dirmngr.conf" }, { "DirMngr LDAP Server List", NULL, 0, NULL, "ldapserverlist-file", "LDAP Server" }, + { "Pinentry", "pinentry", GNUPG_MODULE_NAME_PINENTRY, + NULL, "gpgconf-pinentry.conf" }, }; @@ -939,6 +944,19 @@ GC_OPTION_NULL }; + +/* The options of the GC_COMPONENT_PINENTRY component. */ +static gc_option_t gc_options_pinentry[] = + { + /* A dummy option to allow gc_component_list_components to find the + pinentry backend. Needs to be a conf file. */ + { "gpgconf-pinentry.conf", GC_OPT_FLAG_NONE, GC_LEVEL_INTERNAL, + NULL, NULL, GC_ARG_TYPE_FILENAME, GC_BACKEND_PINENTRY }, + + GC_OPTION_NULL + }; + + /* Component system. Each component is a set of options that can be configured at the same time. If you change this, don't forget to @@ -960,6 +978,9 @@ /* The LDAP Directory Manager for CRLs. */ GC_COMPONENT_DIRMNGR, + /* The external Pinentry. */ + GC_COMPONENT_PINENTRY, + /* The number of components. */ GC_COMPONENT_NR } gc_component_t; @@ -988,7 +1009,8 @@ { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent }, { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon }, { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm }, - { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr } + { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr }, + { "pinentry", NULL, "PIN and Passphrase Entry", gc_options_pinentry } }; @@ -1482,7 +1504,10 @@ argv[i++] = "--options"; argv[i++] = conf_file; } - argv[i++] = "--gpgconf-test"; + if (component == GC_COMPONENT_PINENTRY) + argv[i++] = "--version"; + else + argv[i++] = "--gpgconf-test"; argv[i++] = NULL; err = gnupg_create_inbound_pipe (filedes); @@ -1556,6 +1581,7 @@ } + /* Check all components that are available. */ void gc_check_programs (estream_t out) @@ -2117,6 +2143,9 @@ gc_backend_t backend; gc_option_t *option; + if (component == GC_COMPONENT_PINENTRY) + return; /* Dummy module for now. */ + for (backend = 0; backend < GC_BACKEND_NR; backend++) backend_seen[backend] = 0; @@ -2992,6 +3021,9 @@ size_t line_len = 0; ssize_t length; + if (component == GC_COMPONENT_PINENTRY) + return; /* Dummy component for now. */ + for (backend = 0; backend < GC_BACKEND_NR; backend++) { runtime[backend] = 0; From cvs at cvs.gnupg.org Thu Aug 19 13:41:44 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 13:41:44 +0200 Subject: [svn] GnuPG - r5399 - branches/STABLE-BRANCH-2-0/tools Message-ID: Author: wk Date: 2010-08-19 13:41:43 +0200 (Thu, 19 Aug 2010) New Revision: 5399 Modified: branches/STABLE-BRANCH-2-0/tools/ChangeLog branches/STABLE-BRANCH-2-0/tools/gpgconf.c Log: Fix --check-options Modified: branches/STABLE-BRANCH-2-0/tools/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/tools/ChangeLog 2010-08-19 09:53:55 UTC (rev 5398) +++ branches/STABLE-BRANCH-2-0/tools/ChangeLog 2010-08-19 11:41:43 UTC (rev 5399) @@ -1,13 +1,17 @@ +2010-08-19 Werner Koch + + * gpgconf.c (main): Fix --check-options. + 2010-02-11 Marcus Brinkmann From 2009-09-23, 2009-11-04, 2009-11-05, 2009-12-08: - + * gpg-connect-agent.c (read_and_print_response): Add arg WITHHASH. (getinfo_pid_cb, read_and_print_response) (main): Pass true for WITHHASH for the HELP command. Update to new Assuan API. Update use of assuan_socket_connect and assuan_pipe_connect. Convert posix fd to assuan fd. - + 2010-01-10 Werner Koch * symcryptrun.c (utmp.h): Remove header; it is not used. Modified: branches/STABLE-BRANCH-2-0/tools/gpgconf.c =================================================================== --- branches/STABLE-BRANCH-2-0/tools/gpgconf.c 2010-08-19 09:53:55 UTC (rev 5398) +++ branches/STABLE-BRANCH-2-0/tools/gpgconf.c 2010-08-19 11:41:43 UTC (rev 5399) @@ -226,15 +226,18 @@ putc ('\n', stderr); exit (1); } - gc_component_retrieve_options (idx); - if (gc_process_gpgconf_conf (NULL, 1, 0, NULL)) - exit (1); - if (cmd == aListOptions) - gc_component_list_options (idx, get_outfp (&outfp)); - else if (cmd == aChangeOptions) - gc_component_change_options (idx, stdin, get_outfp (&outfp)); - else + if (cmd == aCheckOptions) gc_component_check_options (idx, get_outfp (&outfp), NULL); + else + { + gc_component_retrieve_options (idx); + if (gc_process_gpgconf_conf (NULL, 1, 0, NULL)) + exit (1); + if (cmd == aListOptions) + gc_component_list_options (idx, get_outfp (&outfp)); + else if (cmd == aChangeOptions) + gc_component_change_options (idx, stdin, get_outfp (&outfp)); + } } break; From cvs at cvs.gnupg.org Thu Aug 19 14:17:28 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 14:17:28 +0200 Subject: [svn] ksba - r324 - trunk/src Message-ID: Author: wk Date: 2010-08-19 14:17:27 +0200 (Thu, 19 Aug 2010) New Revision: 324 Modified: trunk/src/ChangeLog trunk/src/dn.c Log: Fix static buffer overflow. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-08-04 08:31:38 UTC (rev 323) +++ trunk/src/ChangeLog 2010-08-19 12:17:27 UTC (rev 324) @@ -1,3 +1,7 @@ +2010-08-19 Werner Koch + + * dn.c (append_ucs2_value): Enlarge TMP buffer. Fixes bug#1269. + 2010-08-02 Werner Koch * reader.c (ksba_reader_set_release_notify): New. Modified: trunk/src/dn.c =================================================================== --- trunk/src/dn.c 2010-08-04 08:31:38 UTC (rev 323) +++ trunk/src/dn.c 2010-08-19 12:17:27 UTC (rev 324) @@ -464,7 +464,7 @@ append_ucs2_value (const unsigned char *value, size_t length, struct stringbuf *sb) { - unsigned char tmp[2]; + unsigned char tmp[3]; const unsigned char *s; size_t n; unsigned int c; From cvs at cvs.gnupg.org Thu Aug 19 15:13:00 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 15:13:00 +0200 Subject: [svn] ksba - r325 - trunk Message-ID: Author: wk Date: 2010-08-19 15:12:59 +0200 (Thu, 19 Aug 2010) New Revision: 325 Modified: trunk/ChangeLog trunk/configure.ac Log: Prepare for gpg-error change Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-08-19 12:17:27 UTC (rev 324) +++ trunk/ChangeLog 2010-08-19 13:12:59 UTC (rev 325) @@ -1,3 +1,8 @@ +2010-08-19 Werner Koch + + * configure.ac (AH_TOP, AH_BOTTOM): New. Define + GPG_ERR_ENABLE_ERRNO_MACROS. + 2010-07-15 Werner Koch Release 1.0.8. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-08-19 12:17:27 UTC (rev 324) +++ trunk/configure.ac 2010-08-19 13:12:59 UTC (rev 325) @@ -77,8 +77,21 @@ AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package]) AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package]) +AH_TOP([ +#ifndef _KSBA_CONFIG_H_INCLUDED +#define _KSBA_CONFIG_H_INCLUDED +/* Enable gpg-error's strerror macro for W32CE. */ +#define GPG_ERR_ENABLE_ERRNO_MACROS 1 +]) +AH_BOTTOM([ + +#endif /*_KSBA_CONFIG_H_INCLUDED*/ +]) + + + # Checks for programs. missing_dir=`cd $ac_aux_dir && pwd` AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) From cvs at cvs.gnupg.org Thu Aug 19 15:19:56 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 15:19:56 +0200 Subject: [svn] assuan - r386 - in trunk: . src Message-ID: Author: wk Date: 2010-08-19 15:19:56 +0200 (Thu, 19 Aug 2010) New Revision: 386 Modified: trunk/ChangeLog trunk/configure.ac trunk/src/assuan.h.in Log: Prepare for a gpg-error change Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-08-11 14:01:10 UTC (rev 385) +++ trunk/ChangeLog 2010-08-19 13:19:56 UTC (rev 386) @@ -1,3 +1,8 @@ +2010-08-19 Werner Koch + + * configure.ac (AH_TOP, AH_BOTTOM): New. Define + GPG_ERR_ENABLE_ERRNO_MACROS. + 2010-08-09 Werner Koch Release 2.0.1 Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-08-11 14:01:10 UTC (rev 385) +++ trunk/configure.ac 2010-08-19 13:19:56 UTC (rev 386) @@ -96,7 +96,20 @@ AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes") +AH_TOP([ +#ifndef _ASSUAN_CONFIG_H_INCLUDED +#define _ASSUAN_CONFIG_H_INCLUDED +/* Enable gpg-error's strerror macro under W32CE. */ +#define GPG_ERR_ENABLE_ERRNO_MACROS 1 +]) + +AH_BOTTOM([ + +#endif /*_ASSUAN_CONFIG_H_INCLUDED*/ +]) + + # Checks for programs. missing_dir=`cd $ac_aux_dir && pwd` AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) Modified: trunk/src/assuan.h.in =================================================================== --- trunk/src/assuan.h.in 2010-08-11 14:01:10 UTC (rev 385) +++ trunk/src/assuan.h.in 2010-08-19 13:19:56 UTC (rev 386) @@ -352,7 +352,7 @@ gpg_error_t assuan_socket_connect (assuan_context_t ctx, const char *name, pid_t server_pid, unsigned int flags); -/*-- assuan-connect.c --*/ +/*-- context.c --*/ pid_t assuan_get_pid (assuan_context_t ctx); struct _assuan_peercred { From cvs at cvs.gnupg.org Thu Aug 19 15:24:50 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 15:24:50 +0200 Subject: [svn] gcry - r1442 - trunk Message-ID: Author: wk Date: 2010-08-19 15:24:49 +0200 (Thu, 19 Aug 2010) New Revision: 1442 Modified: trunk/ChangeLog trunk/configure.ac Log: Prepare for a gpg-error change Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-08-16 08:45:49 UTC (rev 1441) +++ trunk/ChangeLog 2010-08-19 13:24:49 UTC (rev 1442) @@ -1,3 +1,13 @@ +2010-08-19 Werner Koch + + * configure.ac: Define GPG_ERR_ENABLE_ERRNO_MACROS. Remove + definition of _GNU_SOURCE. + (AC_GNU_SOURCE): New. + +2010-08-16 Werner Koch + + * configure.ac (INSERT_SYS_SELECT_H): New. + 2010-07-09 Werner Koch * configure.ac: Bump LT version to C18/A7/R0 to prepare a backport Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-08-16 08:45:49 UTC (rev 1441) +++ trunk/configure.ac 2010-08-19 13:24:49 UTC (rev 1442) @@ -70,9 +70,9 @@ AH_TOP([ #ifndef _GCRYPT_CONFIG_H_INCLUDED #define _GCRYPT_CONFIG_H_INCLUDED -/* need this, because some autoconf tests rely on this (e.g. stpcpy) - * and it should be used for new programs */ -#define _GNU_SOURCE 1 + +/* Enable gpg-error's strerror macro for W32CE. */ +#define GPG_ERR_ENABLE_ERRNO_MACROS 1 ]) AH_BOTTOM([ @@ -139,6 +139,9 @@ AC_PROG_INSTALL AC_PROG_AWK +AC_GNU_SOURCE + + LT_PREREQ([2.2.6]) LT_INIT([win32-dll disable-static]) LT_LANG([Windows Resource]) From cvs at cvs.gnupg.org Thu Aug 19 15:28:50 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 15:28:50 +0200 Subject: [svn] pinentry - r235 - in trunk: . w32 Message-ID: Author: wk Date: 2010-08-19 15:28:49 +0200 (Thu, 19 Aug 2010) New Revision: 235 Modified: trunk/ChangeLog trunk/configure.ac trunk/w32/main.c Log: Prepare for a gpg-error change Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-06-08 15:40:49 UTC (rev 234) +++ trunk/ChangeLog 2010-08-19 13:28:49 UTC (rev 235) @@ -1,3 +1,8 @@ +2010-08-19 Werner Koch + + * configure.ac (AH_TOP, AH_BOTTOM): New. Define + GPG_ERR_ENABLE_ERRNO_MACROS. + 2010-06-08 Marc Mutz (wk) * qt4/pinentrydialog.cpp (PinEntryDialog): Add WindowStaysOnTopHint. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-06-08 15:40:49 UTC (rev 234) +++ trunk/configure.ac 2010-08-19 13:28:49 UTC (rev 235) @@ -51,6 +51,19 @@ AC_CANONICAL_HOST +AH_TOP([ +#ifndef PINENTRY_CONFIG_H_INCLUDED +#define PINENTRY_CONFIG_H_INCLUDED + +/* Enable gpg-error's strerror macro under W32CE. */ +#define GPG_ERR_ENABLE_ERRNO_MACROS 1 +]) + +AH_BOTTOM([ +#endif /*PINENTRY_CONFIG_H_INCLUDED*/ +]) + + dnl Checks for programs. missing_dir=`cd $ac_aux_dir && pwd` AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) Modified: trunk/w32/main.c =================================================================== --- trunk/w32/main.c 2010-06-08 15:40:49 UTC (rev 234) +++ trunk/w32/main.c 2010-08-19 13:28:49 UTC (rev 235) @@ -206,7 +206,7 @@ } -/* Raie the software input panel. */ +/* Raise the software input panel. */ #ifdef HAVE_W32CE_SYSTEM static void raise_sip (HWND dlg) From cvs at cvs.gnupg.org Thu Aug 19 15:38:38 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 15:38:38 +0200 Subject: [svn] GnuPG - r5400 - trunk Message-ID: Author: wk Date: 2010-08-19 15:38:37 +0200 (Thu, 19 Aug 2010) New Revision: 5400 Modified: trunk/configure.ac Log: Prepare for gpg-error change Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-08-19 11:41:43 UTC (rev 5399) +++ trunk/configure.ac 2010-08-19 13:38:37 UTC (rev 5400) @@ -483,6 +483,9 @@ /* Under Windows we use the gettext code from libgpg-error. */ #define GPG_ERR_ENABLE_GETTEXT_MACROS +/* Under WindowsCE we use the strerror replacement from libgpg-error. */ +#define GPG_ERR_ENABLE_ERRNO_MACROS + #endif /*GNUPG_CONFIG_H_INCLUDED*/ ]) From cvs at cvs.gnupg.org Thu Aug 19 15:39:12 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 15:39:12 +0200 Subject: [svn] gpg-error - r247 - in trunk: . src Message-ID: Author: wk Date: 2010-08-19 15:39:12 +0200 (Thu, 19 Aug 2010) New Revision: 247 Modified: trunk/ChangeLog trunk/NEWS trunk/autogen.sh trunk/configure.ac trunk/src/w32ce-add.h Log: Require new GPG_ERR_ENABLE_ERRNO_MACROS define to include the strerror define. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-07-21 08:12:25 UTC (rev 246) +++ trunk/ChangeLog 2010-08-19 13:39:12 UTC (rev 247) @@ -1,3 +1,9 @@ +2010-08-19 Werner Koch + + * configure.ac (AH_BOTTOM): Define GPG_ERR_ENABLE_ERRNO_MACROS. + * src/w32ce-add.h (strerror) [!GPG_ERR_ENABLE_ERRNO_MACROS]: Do + not define. + 2010-07-21 Werner Koch Release 1.9. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-07-21 08:12:25 UTC (rev 246) +++ trunk/NEWS 2010-08-19 13:39:12 UTC (rev 247) @@ -1,3 +1,10 @@ +Noteworthy changes in version 1.10 +---------------------------------------------- + + * Interface changes relative to the 1.9 release: + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + Noteworthy changes in version 1.9 (2010-07-21) ---------------------------------------------- Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2010-07-21 08:12:25 UTC (rev 246) +++ trunk/autogen.sh 2010-08-19 13:39:12 UTC (rev 247) @@ -125,7 +125,7 @@ fi fi - ./configure --enable-maintainer-mode --prefix=${w32root} \ + $tsdir/configure --enable-maintainer-mode --prefix=${w32root} \ --host=${host} --build=${build} "$@" exit $? Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-07-21 08:12:25 UTC (rev 246) +++ trunk/configure.ac 2010-08-19 13:39:12 UTC (rev 247) @@ -24,8 +24,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [1.9]) -m4_define([my_issvn], [no]) +m4_define([my_version], [1.10]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) @@ -105,8 +105,9 @@ #if defined(HAVE_W32_SYSTEM) && !defined(ENABLE_NLS) #define ENABLE_NLS 1 #endif -/* For building we need to define this macro. */ -#define GPG_ERR_ENABLE_GETTEXT_MACROS +/* For building we need to define these macro. */ +#define GPG_ERR_ENABLE_GETTEXT_MACROS 1 +#define GPG_ERR_ENABLE_ERRNO_MACROS 1 ]) Modified: trunk/src/w32ce-add.h =================================================================== --- trunk/src/w32ce-add.h 2010-07-21 08:12:25 UTC (rev 246) +++ trunk/src/w32ce-add.h 2010-08-19 13:39:12 UTC (rev 247) @@ -3,5 +3,6 @@ /* Substitute for strerror - this one is thread safe. */ char *_gpg_w32ce_strerror (int err); -#define strerror(a) _gpg_w32ce_strerror (a) - +#ifdef GPG_ERR_ENABLE_ERRNO_MACROS +# define strerror(a) _gpg_w32ce_strerror (a) +#endif From cvs at cvs.gnupg.org Thu Aug 19 15:41:06 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 15:41:06 +0200 Subject: [svn] gpgme - r1488 - trunk Message-ID: Author: wk Date: 2010-08-19 15:41:05 +0200 (Thu, 19 Aug 2010) New Revision: 1488 Modified: trunk/ChangeLog trunk/configure.ac Log: Change for gpg-error change. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-08-18 14:14:27 UTC (rev 1487) +++ trunk/ChangeLog 2010-08-19 13:41:05 UTC (rev 1488) @@ -1,3 +1,7 @@ +2010-08-19 Werner Koch + + * configure.ac (AH_BOTTOM): Define GPG_ERR_ENABLE_ERRNO_MACROS. + 2010-05-12 Marcus Brinkmann * configure.ac: Check for setlocale. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2010-08-18 14:14:27 UTC (rev 1487) +++ trunk/configure.ac 2010-08-19 13:41:05 UTC (rev 1488) @@ -858,6 +858,9 @@ #else # define GPGME_GCC_A_PURE #endif + +/* Under WindowsCE we need gpg-error's strerror macro. */ +#define GPG_ERR_ENABLE_ERRNO_MACROS 1 ]) From cvs at cvs.gnupg.org Thu Aug 19 15:57:21 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 15:57:21 +0200 Subject: [svn] gcry - r1443 - in trunk: cipher random Message-ID: Author: wk Date: 2010-08-19 15:57:20 +0200 (Thu, 19 Aug 2010) New Revision: 1443 Modified: trunk/cipher/ChangeLog trunk/cipher/cipher.c trunk/random/random-csprng.c Log: Fix bug 1263 Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2010-08-19 13:24:49 UTC (rev 1442) +++ trunk/cipher/ChangeLog 2010-08-19 13:57:20 UTC (rev 1443) @@ -1,3 +1,8 @@ +2010-08-19 Werner Koch + + * cipher.c (gcry_cipher_open): Remove double release of the module. + Fixes bug#1263. + 2010-06-10 Jeff Johnson (wk) * ecc.c (ecc_generate_ext): Parse transient-key flag. Modified: trunk/cipher/cipher.c =================================================================== --- trunk/cipher/cipher.c 2010-08-19 13:24:49 UTC (rev 1442) +++ trunk/cipher/cipher.c 2010-08-19 13:57:20 UTC (rev 1443) @@ -698,7 +698,6 @@ { /* Not available for use. */ err = GPG_ERR_CIPHER_ALGO; - _gcry_module_release (module); } else { Modified: trunk/random/random-csprng.c =================================================================== --- trunk/random/random-csprng.c 2010-08-19 13:24:49 UTC (rev 1442) +++ trunk/random/random-csprng.c 2010-08-19 13:57:20 UTC (rev 1443) @@ -682,7 +682,9 @@ static int lock_seed_file (int fd, const char *fname, int for_write) { +#ifdef __GCC__ #warning Check whether we can lock on Windows. +#endif #if LOCK_SEED_FILE struct flock lck; struct timeval tv; From cvs at cvs.gnupg.org Thu Aug 19 15:57:39 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 15:57:39 +0200 Subject: [svn] gcry - r1444 - branches/LIBGCRYPT-1-4-BRANCH/cipher Message-ID: Author: wk Date: 2010-08-19 15:57:38 +0200 (Thu, 19 Aug 2010) New Revision: 1444 Modified: branches/LIBGCRYPT-1-4-BRANCH/cipher/ChangeLog branches/LIBGCRYPT-1-4-BRANCH/cipher/cipher.c Log: Fix bug 1263 Modified: branches/LIBGCRYPT-1-4-BRANCH/cipher/ChangeLog =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/cipher/ChangeLog 2010-08-19 13:57:20 UTC (rev 1443) +++ branches/LIBGCRYPT-1-4-BRANCH/cipher/ChangeLog 2010-08-19 13:57:38 UTC (rev 1444) @@ -1,3 +1,8 @@ +2010-08-19 Werner Koch + + * cipher.c (gcry_cipher_open): Remove double release of the + module. Fixes bug#1263. + 2010-07-13 Werner Koch * cipher.c (do_aeswrap_encrypt, do_aeswrap_decrypt): New. Take Modified: branches/LIBGCRYPT-1-4-BRANCH/cipher/cipher.c =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/cipher/cipher.c 2010-08-19 13:57:20 UTC (rev 1443) +++ branches/LIBGCRYPT-1-4-BRANCH/cipher/cipher.c 2010-08-19 13:57:38 UTC (rev 1444) @@ -698,7 +698,6 @@ { /* Not available for use. */ err = GPG_ERR_CIPHER_ALGO; - _gcry_module_release (module); } else { From cvs at cvs.gnupg.org Thu Aug 19 16:44:32 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Aug 2010 16:44:32 +0200 Subject: [svn] pinentry - r236 - in trunk: . gtk+-2 Message-ID: Author: wk Date: 2010-08-19 16:44:31 +0200 (Thu, 19 Aug 2010) New Revision: 236 Modified: trunk/ChangeLog trunk/gtk+-2/Makefile.am Log: Add missing file to the Makefile.am Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-08-19 13:28:49 UTC (rev 235) +++ trunk/ChangeLog 2010-08-19 14:44:31 UTC (rev 236) @@ -1,5 +1,7 @@ 2010-08-19 Werner Koch + * gtk+-2/Makefile.am (pinentry_gtk_2_SOURCES): Add gseal-gtk-compat.h. + * configure.ac (AH_TOP, AH_BOTTOM): New. Define GPG_ERR_ENABLE_ERRNO_MACROS. Modified: trunk/gtk+-2/Makefile.am =================================================================== --- trunk/gtk+-2/Makefile.am 2010-08-19 13:28:49 UTC (rev 235) +++ trunk/gtk+-2/Makefile.am 2010-08-19 14:44:31 UTC (rev 236) @@ -35,4 +35,4 @@ $(LIBCAP) $(GTK2LIBS) $(libcurses) pinentry_gtk_2_SOURCES = pinentry-gtk-2.c \ - gtksecentry.c gtksecentry.h + gtksecentry.c gtksecentry.h gseal-gtk-compat.h From cvs at cvs.gnupg.org Fri Aug 20 14:18:40 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 20 Aug 2010 14:18:40 +0200 Subject: [svn] GnuPG - r5401 - in trunk: . common tools Message-ID: Author: wk Date: 2010-08-20 14:18:38 +0200 (Fri, 20 Aug 2010) New Revision: 5401 Modified: trunk/ChangeLog trunk/NEWS trunk/README trunk/common/ChangeLog trunk/common/estream.c trunk/common/estream.h trunk/common/exechelp-posix.c trunk/common/exechelp-w32.c trunk/common/exechelp-w32ce.c trunk/common/exechelp.h trunk/tools/ChangeLog trunk/tools/gpgconf-comp.c trunk/tools/gpgconf.c Log: Reworked the posix and w32 exechelpers. [The diff below has been truncated] Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2010-08-19 13:38:37 UTC (rev 5400) +++ trunk/ChangeLog 2010-08-20 12:18:38 UTC (rev 5401) @@ -1,3 +1,7 @@ +2010-08-19 Werner Koch + + * configure.ac (AH_BOTTOM): Define GPG_ERR_ENABLE_ERRNO_MACROS. + 2010-08-09 Werner Koch * configure.ac (inet_pton): Check for it. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-08-19 13:38:37 UTC (rev 5400) +++ trunk/common/ChangeLog 2010-08-20 12:18:38 UTC (rev 5401) @@ -1,3 +1,31 @@ +2010-08-20 Werner Koch + + * exechelp-w32.c (create_inheritable_pipe): Change arg to HANDLE. + + * estream.h (es_sysopen_t): New. + * estream.c (es_func_w32_create, es_func_w32_read) + (es_func_w32_write, es_func_w32_seek, es_func_w32_destroy) + (estream_functions_w32, estream_cookie_fd): New. Only for W32. + (es_sysopen, es_sysopen_nc): New. + (do_w32open, do_sysopen): New. + (es_syshd, es_syshd_unlocked): New. + (struct estream_internal): Replace filed FD by SYSHD. + (es_initialize): Clear SYSHD_VALID. + (map_w32_to_errno): New. + (es_get_fd): Remove. + (es_fileno_unlocked): Re-implement using es_syshd. + (es_initialize, es_create): Replace arg FD by SYSHD. + (es_fopen, es_mopen, es_fopenmem, do_fdopen, do_fpopen) + (es_tmpfile): Use SYSHD instead of FD. + (es_destroy): Rename to do_close. + +2010-08-19 Werner Koch + + * exechelp-posix.c (create_pipe_and_estream): New. + (gnupg_spawn_process): Rework this function and its calling + convention; it is not used anyway. + * exechelp-w32.c (gnupg_spawn_process): Ditto. + 2010-08-18 Werner Koch * logging.c (writen): Add arg IS_SOCKET. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2010-08-19 13:38:37 UTC (rev 5400) +++ trunk/tools/ChangeLog 2010-08-20 12:18:38 UTC (rev 5401) @@ -1,5 +1,16 @@ +2010-08-20 Werner Koch + + * gpgconf-comp.c (collect_error_output): Remove extra CRs. + 2010-08-19 Werner Koch + * gpgconf.c (main): Fix --check-options. + + * gpgconf-comp.c (gc_component_check_options): Replace + gnupg_spawn_process_fd by gnupg_spawn_process. + (retrieve_options_from_program): Ditto. + (collect_error_output): Change to use estream. + * gpgconf-comp.c: Add new backend and component for PINENTRY. (gc_component_check_options): Use --version to test the pinentry. (gc_component_retrieve_options, gc_component_change_options): Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-08-19 13:38:37 UTC (rev 5400) +++ trunk/NEWS 2010-08-20 12:18:38 UTC (rev 5401) @@ -35,7 +35,9 @@ * Given sufficient permissions Dirmngr is started automagically. + * Fixed output of "gpgconf --check-options". + Noteworthy changes in version 2.0.13 (2009-09-04) ------------------------------------------------- Modified: trunk/README =================================================================== --- trunk/README 2010-08-19 13:38:37 UTC (rev 5400) +++ trunk/README 2010-08-20 12:18:38 UTC (rev 5401) @@ -16,7 +16,7 @@ GnuPG is GNU's tool for secure communication and data storage. It can be used to encrypt data and to create digital signatures. It includes an advanced key management facility and is compliant with the proposed -OpenPGP Internet standard as described in RFC2440 and the S/MIME +OpenPGP Internet standard as described in RFC4880 and the S/MIME standard as described by several RFCs. GnuPG is distributed under the terms of the GNU General Public Modified: trunk/common/estream.c =================================================================== --- trunk/common/estream.c 2010-08-19 13:38:37 UTC (rev 5400) +++ trunk/common/estream.c 2010-08-20 12:18:38 UTC (rev 5401) @@ -126,9 +126,9 @@ #endif #ifdef HAVE_W32_SYSTEM -# define IS_INVALID_FD(a) ((void*)(a) == (void*)(-1)) +# define IS_INVALID_FD(a) ((void*)(a) == (void*)(-1)) /* ?? FIXME. */ #else -# define IS_INVALID_FD(a) ((a) == -1) +# define IS_INVALID_FD(a) ((a) == -1) #endif @@ -197,6 +197,7 @@ # define ESTREAM_SYS_YIELD() do { } while (0) #endif + /* Misc definitions. */ #define ES_DEFAULT_OPEN_MODE (S_IRUSR | S_IWUSR) @@ -218,7 +219,7 @@ es_cookie_seek_function_t func_seek; es_cookie_close_function_t func_close; int strategy; - int fd; /* Value to return by es_fileno(). */ + es_syshd_t syshd; /* A copy of the sytem handle. */ struct { unsigned int err: 1; @@ -317,8 +318,40 @@ free (p); } +#ifdef HAVE_W32_SYSTEM +static int +map_w32_to_errno (DWORD w32_err) +{ + switch (w32_err) + { + case 0: + return 0; + case ERROR_FILE_NOT_FOUND: + return ENOENT; + case ERROR_PATH_NOT_FOUND: + return ENOENT; + + case ERROR_ACCESS_DENIED: + return EPERM; + + case ERROR_INVALID_HANDLE: + case ERROR_INVALID_BLOCK: + return EINVAL; + + case ERROR_NOT_ENOUGH_MEMORY: + return ENOMEM; + + case ERROR_NO_DATA: + return EPIPE; + + default: + return EIO; + } +} +#endif /*HAVE_W32_SYSTEM*/ + /* * List manipulation. */ @@ -744,7 +777,7 @@ -/* Implementation of fd I/O. */ +/* Implementation of file descriptor based I/O. */ /* Cookie for fd objects. */ typedef struct estream_cookie_fd @@ -887,6 +920,217 @@ +#ifdef HAVE_W32_SYSTEM +/* Implementation of W32 handle based I/O. */ + +/* Cookie for fd objects. */ +typedef struct estream_cookie_w32 +{ + HANDLE hd; /* The handle we are using for actual output. */ + int no_close; /* If set we won't close the handle. */ +} *estream_cookie_w32_t; + + +/* Create function for w32 handle objects. */ +static int +es_func_w32_create (void **cookie, HANDLE hd, + unsigned int modeflags, int no_close) +{ + estream_cookie_w32_t w32_cookie; + int err; + + w32_cookie = mem_alloc (sizeof (*w32_cookie)); + if (!w32_cookie) + err = -1; + else + { + /* CR/LF translations are not supported when using the bare W32 + API. If that is really required we need to implemented that + in the upper layer. */ + (void)modeflags; + + w32_cookie->hd = hd; + w32_cookie->no_close = no_close; + *cookie = w32_cookie; + err = 0; + } + + return err; +} + +/* Read function for W32 handle objects. */ +static ssize_t +es_func_w32_read (void *cookie, void *buffer, size_t size) +{ + estream_cookie_w32_t w32_cookie = cookie; + ssize_t bytes_read; + + if (w32_cookie->hd == INVALID_HANDLE_VALUE) + { + ESTREAM_SYS_YIELD (); + bytes_read = 0; + } + else + { + do + { +#ifdef HAVE_PTH + /* Note: Our pth_read actually uses HANDLE! */ + bytes_read = pth_read ((int)w32_cookie->hd, buffer, size); +#else + DWORD nread, ec; + + if (!ReadFile (w32_cookie->hd, buffer, size, &nread, NULL)) + { + ec = GetLastError (); + if (ec == ERROR_BROKEN_PIPE) + bytes_read = 0; /* Like our pth_read we handle this as EOF. */ + else + { + _set_errno (map_w32_to_errno (ec)); + log_debug ("estream: ReadFile returned %d\n", + (int)GetLastError ()); + bytes_read = -1; + } + } + else + bytes_read = (int)nread; +#endif + } + while (bytes_read == -1 && errno == EINTR); + } + + return bytes_read; +} + +/* Write function for W32 handle objects. */ +static ssize_t +es_func_w32_write (void *cookie, const void *buffer, size_t size) +{ + estream_cookie_w32_t w32_cookie = cookie; + ssize_t bytes_written; + + if (w32_cookie->hd == INVALID_HANDLE_VALUE) + { + ESTREAM_SYS_YIELD (); + bytes_written = size; /* Yeah: Success writing to the bit bucket. */ + } + else + { + do + { +#ifdef HAVE_PTH + /* Note: Our pth_write actually uses HANDLE! */ + bytes_written = pth_write ((int)w32_cookie->hd, buffer, size); +#else + DWORD nwritten; + + if (!WriteFile (w32_cookie->hd, buffer, size, &nwritten, NULL)) + { + _set_errno (map_w32_to_errno (GetLastError ())); + bytes_written = -1; + } + else + bytes_written = (int)nwritten; +#endif + } + while (bytes_written == -1 && errno == EINTR); + } + + return bytes_written; +} + +/* Seek function for W32 handle objects. */ +static int +es_func_w32_seek (void *cookie, off_t *offset, int whence) +{ + estream_cookie_w32_t w32_cookie = cookie; + DWORD method; + LARGE_INTEGER distance, newoff; + + if (w32_cookie->hd == INVALID_HANDLE_VALUE) + { + _set_errno (ESPIPE); + return -1; + } + + if (whence == SEEK_SET) + { + method = FILE_BEGIN; + distance.QuadPart = (unsigned long long)(*offset); + } + else if (whence == SEEK_CUR) + { + method = FILE_CURRENT; + distance.QuadPart = (long long)(*offset); + } + else if (whence == SEEK_END) + { + method = FILE_END; + distance.QuadPart = (long long)(*offset); + } + else + { + _set_errno (EINVAL); + return -1; + } +#ifdef HAVE_W32CE_SYSTEM +# warning need to use SetFilePointer +#else + if (!SetFilePointerEx (w32_cookie->hd, distance, &newoff, method)) + { + _set_errno (map_w32_to_errno (GetLastError ())); + return -1; + } +#endif + *offset = (unsigned long long)newoff.QuadPart; + return 0; +} + +/* Destroy function for W32 handle objects. */ +static int +es_func_w32_destroy (void *cookie) +{ + estream_cookie_w32_t w32_cookie = cookie; + int err; + + if (w32_cookie) + { + if (w32_cookie->hd == INVALID_HANDLE_VALUE) + err = 0; + else if (w32_cookie->no_close) + err = 0; + else + { + if (!CloseHandle (w32_cookie->hd)) + { + _set_errno (map_w32_to_errno (GetLastError ())); + err = -1; + } + else + err = 0; + } + mem_free (w32_cookie); + } + else + err = 0; + + return err; +} + + +static es_cookie_io_functions_t estream_functions_w32 = + { + es_func_w32_read, + es_func_w32_write, + es_func_w32_seek, + es_func_w32_destroy + }; +#endif /*HAVE_W32_SYSTEM*/ + + + + /* Implementation of FILE* I/O. */ /* Cookie for fp objects. */ @@ -1049,7 +1293,7 @@ /* Implementation of file I/O. */ -/* Create function for file objects. */ +/* Create function for fd objects. */ static int es_func_file_create (void **cookie, int *filedes, const char *path, unsigned int modeflags) @@ -1269,7 +1513,8 @@ /* Initialize STREAM. */ static void es_initialize (estream_t stream, - void *cookie, int fd, es_cookie_io_functions_t functions, + void *cookie, es_syshd_t *syshd, + es_cookie_io_functions_t functions, unsigned int modeflags) { stream->intern->cookie = cookie; @@ -1280,7 +1525,7 @@ stream->intern->func_seek = functions.func_seek; stream->intern->func_close = functions.func_close; stream->intern->strategy = _IOFBF; - stream->intern->fd = fd; + stream->intern->syshd = *syshd; stream->intern->print_ntotal = 0; stream->intern->indicators.err = 0; stream->intern->indicators.eof = 0; @@ -1329,7 +1574,7 @@ /* Create a new stream object, initialize it. */ static int -es_create (estream_t *stream, void *cookie, int fd, +es_create (estream_t *stream, void *cookie, es_syshd_t *syshd, es_cookie_io_functions_t functions, unsigned int modeflags, int with_locked_list) { @@ -1361,7 +1606,7 @@ stream_new->intern = stream_internal_new; ESTREAM_MUTEX_INITIALIZE (stream_new->intern->lock); - es_initialize (stream_new, cookie, fd, functions, modeflags); + es_initialize (stream_new, cookie, syshd, functions, modeflags); err = es_list_add (stream_new, with_locked_list); if (err) @@ -1385,9 +1630,9 @@ /* Deinitialize a stream object and destroy it. */ static int -es_destroy (estream_t stream, int with_locked_list) +do_close (estream_t stream, int with_locked_list) { - int err = 0; + int err; if (stream) { @@ -1396,6 +1641,8 @@ mem_free (stream->intern); mem_free (stream); } + else + err = 0; return err; } @@ -1897,6 +2144,7 @@ unsigned char *data; size_t data_len; int err; + es_syshd_t syshd; line_new = NULL; line_stream = NULL; @@ -1910,7 +2158,8 @@ if (err) goto out; - err = es_create (&line_stream, line_stream_cookie, -1, + memset (&syshd, 0, sizeof syshd); + err = es_create (&line_stream, line_stream_cookie, &syshd, estream_functions_mem, O_RDWR, 0); if (err) goto out; @@ -1996,7 +2245,7 @@ out: if (line_stream) - es_destroy (line_stream, 0); + do_close (line_stream, 0); else if (line_stream_cookie) es_func_mem_destroy (line_stream_cookie); @@ -2152,12 +2401,6 @@ } -static int -es_get_fd (estream_t stream) -{ - return stream->intern->fd; -} - /* API. */ @@ -2172,6 +2415,8 @@ return err; } + + estream_t es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode) { @@ -2181,6 +2426,7 @@ void *cookie; int err; int fd; + es_syshd_t syshd; stream = NULL; cookie = NULL; @@ -2193,9 +2439,12 @@ err = es_func_file_create (&cookie, &fd, path, modeflags); if (err) goto out; + + syshd.type = ES_SYSHD_FD; + syshd.u.fd = fd; create_called = 1; - err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0); + err = es_create (&stream, cookie, &syshd, estream_functions_fd, modeflags, 0); if (err) goto out; @@ -2211,6 +2460,7 @@ } + estream_t es_mopen (unsigned char *ES__RESTRICT data, size_t data_n, size_t data_len, unsigned int grow, @@ -2222,6 +2472,7 @@ estream_t stream; void *cookie; int err; + es_syshd_t syshd; cookie = 0; stream = NULL; @@ -2237,8 +2488,10 @@ if (err) goto out; + memset (&syshd, 0, sizeof syshd); create_called = 1; - err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0); + err = es_create (&stream, cookie, &syshd, + estream_functions_mem, modeflags, 0); out: @@ -2249,12 +2502,14 @@ } + estream_t es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode) { unsigned int modeflags; estream_t stream = NULL; void *cookie = NULL; + es_syshd_t syshd; /* Memory streams are always read/write. We use MODE only to get the append flag. */ @@ -2269,14 +2524,15 @@ memlimit)) return NULL; - if (es_create (&stream, cookie, -1, estream_functions_mem, modeflags, 0)) + memset (&syshd, 0, sizeof syshd); + if (es_create (&stream, cookie, &syshd, estream_functions_mem, modeflags, 0)) (*estream_functions_mem.func_close) (cookie); return stream; } - + estream_t es_fopencookie (void *ES__RESTRICT cookie, const char *ES__RESTRICT mode, @@ -2285,6 +2541,7 @@ unsigned int modeflags; estream_t stream; int err; + es_syshd_t syshd; stream = NULL; modeflags = 0; @@ -2293,16 +2550,17 @@ if (err) goto out; - err = es_create (&stream, cookie, -1, functions, modeflags, 0); + memset (&syshd, 0, sizeof syshd); + err = es_create (&stream, cookie, &syshd, functions, modeflags, 0); if (err) goto out; out: - return stream; } + estream_t do_fdopen (int filedes, const char *mode, int no_close, int with_locked_list) { @@ -2311,6 +2569,7 @@ estream_t stream; void *cookie; int err; + es_syshd_t syshd; stream = NULL; cookie = NULL; @@ -2324,12 +2583,13 @@ if (err) goto out; + syshd.type = ES_SYSHD_FD; + syshd.u.fd = filedes; create_called = 1; - err = es_create (&stream, cookie, filedes, estream_functions_fd, + err = es_create (&stream, cookie, &syshd, estream_functions_fd, modeflags, with_locked_list); out: - if (err && create_called) (*estream_functions_fd.func_close) (cookie); @@ -2350,6 +2610,7 @@ } + estream_t do_fpopen (FILE *fp, const char *mode, int no_close, int with_locked_list) { @@ -2358,6 +2619,7 @@ estream_t stream; void *cookie; int err; + es_syshd_t syshd; stream = NULL; cookie = NULL; @@ -2372,9 +2634,11 @@ err = es_func_fp_create (&cookie, fp, modeflags, no_close); if (err) goto out; - + + syshd.type = ES_SYSHD_FD; + syshd.u.fd = fp? fileno (fp): -1; create_called = 1; - err = es_create (&stream, cookie, fp? fileno (fp):-1, estream_functions_fp, + err = es_create (&stream, cookie, &syshd, estream_functions_fp, modeflags, with_locked_list); out: @@ -2409,6 +2673,87 @@ } + +#ifdef HAVE_W32_SYSTEM +estream_t +do_w32open (HANDLE hd, const char *mode, + int no_close, int with_locked_list) +{ + unsigned int modeflags; + int create_called = 0; + estream_t stream = NULL; + void *cookie = NULL; + int err; + es_syshd_t syshd; + + err = es_convert_mode (mode, &modeflags); + if (err) + goto leave; + + err = es_func_w32_create (&cookie, hd, modeflags, no_close); + if (err) + goto leave; + + syshd.type = ES_SYSHD_HANDLE; + syshd.u.handle = hd; + create_called = 1; + err = es_create (&stream, cookie, &syshd, estream_functions_w32, + modeflags, with_locked_list); + + leave: + if (err && create_called) + (*estream_functions_w32.func_close) (cookie); + + return stream; +} +#endif /*HAVE_W32_SYSTEM*/ + +static estream_t +do_sysopen (es_syshd_t *syshd, const char *mode, int no_close) +{ + estream_t stream; + + switch (syshd->type) + { + case ES_SYSHD_FD: + case ES_SYSHD_SOCK: + stream = do_fdopen (syshd->u.fd, mode, no_close, 0); + break; + +#ifdef HAVE_W32_SYSTEM + case ES_SYSHD_HANDLE: + stream = do_w32open (syshd->u.handle, mode, no_close, 0); + break; +#endif + + /* FIXME: Support RVIDs under Wince? */ + + default: + _set_errno (EINVAL); + stream = NULL; + } + return stream; +} + +/* On POSIX systems this function is an alias for es_fdopen. Under + Windows it uses the bare W32 API and thus a HANDLE instead of a + file descriptor. */ +estream_t +es_sysopen (es_syshd_t *syshd, const char *mode) +{ + return do_sysopen (syshd, mode, 0); +} + +/* Same as es_sysopen but the handle/fd will not be closed by + es_fclose. */ +estream_t +es_sysopen_nc (es_syshd_t *syshd, const char *mode) +{ + return do_sysopen (syshd, mode, 1); +} + + + /* Set custom standard descriptors to be used for stdin, stdout and stderr. This function needs to be called before any of the standard streams are accessed. */ @@ -2500,6 +2845,7 @@ int create_called; void *cookie; int fd; + es_syshd_t syshd; cookie = NULL; create_called = 0; @@ -2516,8 +2862,10 @@ if (err) goto leave; + syshd.type = ES_SYSHD_FD; + syshd.u.fd = fd; create_called = 1; - es_initialize (stream, cookie, fd, estream_functions_fd, modeflags); + es_initialize (stream, cookie, &syshd, estream_functions_fd, modeflags); leave: @@ -2526,7 +2874,7 @@ if (create_called) es_func_fd_destroy (cookie); - es_destroy (stream, 0); + do_close (stream, 0); stream = NULL; } else @@ -2541,7 +2889,7 @@ /* FIXME? We don't support re-opening at the moment. */ _set_errno (EINVAL); es_deinitialize (stream); - es_destroy (stream, 0); + do_close (stream, 0); stream = NULL; } @@ -2554,18 +2902,50 @@ { int err; - err = es_destroy (stream, 0); + err = do_close (stream, 0); return err; } + int es_fileno_unlocked (estream_t stream) { - return es_get_fd (stream); + es_syshd_t syshd; + + if (es_syshd (stream, &syshd)) + return -1; + switch (syshd.type) + { + case ES_SYSHD_FD: return syshd.u.fd; + case ES_SYSHD_SOCK: return syshd.u.sock; + default: + _set_errno (EINVAL); + return -1; + } } +/* Return the handle of a stream which has been opened by es_sysopen. + The caller needs to pass a structure which will be filled with the + sys handle. Return 0 on success or true on error and sets errno. + This is the unlocked version. */ +int +es_syshd_unlocked (estream_t stream, es_syshd_t *syshd) +{ + if (!stream || !syshd || stream->intern->syshd.type == ES_SYSHD_NONE) + { + if (syshd) + syshd->type = ES_SYSHD_NONE; + _set_errno (EINVAL); + return -1; + } + + *syshd = stream->intern->syshd; + return 0; +} + + void es_flockfile (estream_t stream) { @@ -2600,7 +2980,24 @@ } +/* Return the handle of a stream which has been opened by es_sysopen. + The caller needs to pass a structure which will be filled with the + sys handle. Return 0 on success or true on error and sets errno. + This is the unlocked version. */ int +es_syshd (estream_t stream, es_syshd_t *syshd) +{ + int ret; + + ESTREAM_LOCK (stream); + ret = es_syshd_unlocked (stream, syshd); + ESTREAM_UNLOCK (stream); + + return ret; +} + + +int es_feof_unlocked (estream_t stream) { return es_get_indicator (stream, 0, 1); @@ -3371,6 +3768,7 @@ void *cookie; int err; int fd; + es_syshd_t syshd; create_called = 0; stream = NULL; @@ -3388,11 +3786,12 @@ if (err) goto out; + syshd.type = ES_SYSHD_FD; + syshd.u.fd = fd; create_called = 1; - err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags, 0); + err = es_create (&stream, cookie, &syshd, estream_functions_fd, modeflags, 0); out: - if (err) { if (create_called) Modified: trunk/common/estream.h =================================================================== --- trunk/common/estream.h 2010-08-19 13:38:37 UTC (rev 5400) +++ trunk/common/estream.h 2010-08-20 12:18:38 UTC (rev 5401) @@ -78,6 +78,8 @@ #define es_fopenmem _ESTREAM_PREFIX(es_fopenmem) #define es_fdopen _ESTREAM_PREFIX(es_fdopen) #define es_fdopen_nc _ESTREAM_PREFIX(es_fdopen_nc) +#define es_sysopen _ESTREAM_PREFIX(es_sysopen) +#define es_sysopen_nc _ESTREAM_PREFIX(es_sysopen_nc) #define es_fpopen _ESTREAM_PREFIX(es_fpopen) #define es_fpopen_nc _ESTREAM_PREFIX(es_fpopen_nc) #define _es_set_std_fd _ESTREAM_PREFIX(_es_set_std_fd) @@ -211,6 +213,29 @@ es_cookie_close_function_t func_close; } es_cookie_io_functions_t; + +enum es_syshd_types + { + ES_SYSHD_NONE, /* No system handle available. */ + ES_SYSHD_FD, /* A file descriptor as returned by open(). */ + ES_SYSHD_SOCK, /* A socket as returned by socket(). */ + ES_SYSHD_RVID, /* A rendevous id (see libassuan's gpgcedev.c). */ + ES_SYSHD_HANDLE /* A HANDLE object (Windows). */ + }; + +typedef struct +{ + enum es_syshd_types type; + union { + int fd; + int sock; + int rvid; + void *handle; + } u; +} es_syshd_t; + + + #ifndef _ESTREAM_GCC_A_PRINTF #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) @@ -245,6 +270,8 @@ estream_t es_fopenmem (size_t memlimit, const char *ES__RESTRICT mode); estream_t es_fdopen (int filedes, const char *mode); estream_t es_fdopen_nc (int filedes, const char *mode); +estream_t es_sysopen (es_syshd_t *syshd, const char *mode); +estream_t es_sysopen_nc (es_syshd_t *syshd, const char *mode); estream_t es_fpopen (FILE *fp, const char *mode); estream_t es_fpopen_nc (FILE *fp, const char *mode); estream_t es_freopen (const char *ES__RESTRICT path, @@ -256,6 +283,8 @@ int es_fclose (estream_t stream); int es_fileno (estream_t stream); int es_fileno_unlocked (estream_t stream); +int es_syshd (estream_t stream, es_syshd_t *syshd); +int es_syshd_unlocked (estream_t stream, es_syshd_t *syshd); void _es_set_std_fd (int no, int fd); estream_t _es_get_std_stream (int fd); Modified: trunk/common/exechelp-posix.c =================================================================== --- trunk/common/exechelp-posix.c 2010-08-19 13:38:37 UTC (rev 5400) +++ trunk/common/exechelp-posix.c 2010-08-20 12:18:38 UTC (rev 5401) @@ -299,45 +299,95 @@ } + +static gpg_error_t +create_pipe_and_estream (int filedes[2], estream_t *r_fp, + gpg_err_source_t errsource) +{ + gpg_error_t err; + + if (pipe (filedes) == -1) + { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); + filedes[0] = filedes[1] = -1; + *r_fp = NULL; + return err; + } + + *r_fp = es_fdopen (filedes[0], "r"); + if (!*r_fp) + { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + log_error (_("error creating a stream for a pipe: %s\n"), + gpg_strerror (err)); + close (filedes[0]); + close (filedes[1]); + filedes[0] = filedes[1] = -1; + return err; + } + return 0; +} + + + /* Fork and exec the PGMNAME, see exechelp.h for details. */ gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[], - estream_t infile, estream_t outfile, + gpg_err_source_t errsource, void (*preexec)(void), unsigned int flags, - estream_t *statusfile, pid_t *pid) + estream_t infp, + estream_t *r_outfp, + estream_t *r_errfp, + pid_t *pid) { gpg_error_t err; - int fd, fdout, rp[2]; + int infd = -1; + int outpipe[2] = {-1, -1}; + int errpipe[2] = {-1, -1}; + estream_t outfp = NULL; + estream_t errfp = NULL; (void)flags; /* Currently not used. */ - *statusfile = NULL; - *pid = (pid_t)(-1); + if (r_outfp) + *r_outfp = NULL; + if (r_errfp) + *r_errfp = NULL; + *pid = (pid_t)(-1); /* Always required. */ - if (infile) + if (infp) { - es_fflush (infile); - es_rewind (infile); - fd = es_fileno (infile); + es_fflush (infp); + es_rewind (infp); + infd = es_fileno (infp); + if (infd == -1) + return gpg_err_make (errsource, GPG_ERR_INV_VALUE); } - else - fd = -1; - if (outfile) - fdout = es_fileno (outfile); - else - fdout = -1; + if (r_outfp) + { + err = create_pipe_and_estream (outpipe, &outfp, errsource); + if (err) + return err; + } - if ((infile && fd == -1) || (outfile && fdout == -1)) - log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n"); - - if (pipe (rp) == -1) + if (r_errfp) { - err = gpg_error_from_syserror (); - log_error (_("error creating a pipe: %s\n"), strerror (errno)); - return err; + err = create_pipe_and_estream (errpipe, &errfp, errsource); + if (err) + { + if (outfp) + es_fclose (outfp); + else if (outpipe[0] != -1) + close (outpipe[0]); + if (outpipe[1] != -1) + close (outpipe[1]); + return err; + } } + #ifdef USE_GNU_PTH *pid = pth_fork? pth_fork () : fork (); #else @@ -345,33 +395,45 @@ #endif if (*pid == (pid_t)(-1)) { - err = gpg_error_from_syserror (); - log_error (_("error forking process: %s\n"), strerror (errno)); - close (rp[0]); - close (rp[1]); + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + log_error (_("error forking process: %s\n"), gpg_strerror (err)); + + if (outfp) + es_fclose (outfp); + else if (outpipe[0] != -1) + close (outpipe[0]); + if (outpipe[1] != -1) + close (outpipe[1]); + + if (errfp) + es_fclose (errfp); + else if (errpipe[0] != -1) + close (errpipe[0]); + if (errpipe[1] != -1) + close (errpipe[1]); return err; } if (!*pid) { + /* This is the child. */ gcry_control (GCRYCTL_TERM_SECMEM); - /* Run child. */ - do_exec (pgmname, argv, fd, fdout, rp[1], preexec); + es_fclose (outfp); + es_fclose (errfp); + do_exec (pgmname, argv, infd, outpipe[1], errpipe[1], preexec); /*NOTREACHED*/ } - /* Parent. */ - close (rp[1]); + /* This is the parent. */ + if (outpipe[1] != -1) + close (outpipe[1]); + if (errpipe[1] != -1) + close (errpipe[1]); - *statusfile = es_fdopen (rp[0], "r"); - if (!*statusfile) - { - err = gpg_error_from_syserror (); - log_error (_("can't fdopen pipe for reading: %s\n"), strerror (errno)); - kill (*pid, SIGTERM); - *pid = (pid_t)(-1); - return err; - } + if (r_outfp) + *r_outfp = outfp; + if (r_errfp) + *r_errfp = errfp; return 0; } Modified: trunk/common/exechelp-w32.c =================================================================== --- trunk/common/exechelp-w32.c 2010-08-19 13:38:37 UTC (rev 5400) +++ trunk/common/exechelp-w32.c 2010-08-20 12:18:38 UTC (rev 5401) @@ -257,7 +257,7 @@ /* Create pipe where one end is inheritable: With an INHERIT_IDX of 0 the read end is inheritable, with 1 the write end is inheritable. */ static int -create_inheritable_pipe (int filedes[2], int inherit_idx) +create_inheritable_pipe (HANDLE filedes[2], int inherit_idx) { HANDLE r, w, h; SECURITY_ATTRIBUTES sec_attr; @@ -290,8 +290,8 @@ r = h; } - filedes[0] = handle_to_fd (r); - filedes[1] = handle_to_fd (w); + filedes[0] = r; + filedes[1] = w; return 0; } @@ -315,27 +315,27 @@ do_create_pipe (int filedes[2], int inherit_idx) { gpg_error_t err = 0; - int fds[2]; + HANDLE fds[2]; filedes[0] = filedes[1] = -1; err = gpg_error (GPG_ERR_GENERAL); if (!create_inheritable_pipe (fds, inherit_idx)) { - filedes[0] = _open_osfhandle (fds[0], 0); + filedes[0] = _open_osfhandle (handle_to_fd (fds[0]), 0); if (filedes[0] == -1) { - log_error ("failed to translate osfhandle %p\n", (void*)fds[0]); - CloseHandle (fd_to_handle (fds[1])); + log_error ("failed to translate osfhandle %p\n", fds[0]); + CloseHandle (fds[1]); } else { - filedes[1] = _open_osfhandle (fds[1], 1); + filedes[1] = _open_osfhandle (handle_to_fd (fds[1]), 1); if (filedes[1] == -1) { - log_error ("failed to translate osfhandle %p\n", (void*)fds[1]); + log_error ("failed to translate osfhandle %p\n", fds[1]); close (filedes[0]); filedes[0] = -1; - CloseHandle (fd_to_handle (fds[1])); + CloseHandle (fds[1]); } else err = 0; @@ -365,9 +365,12 @@ /* Fork and exec the PGMNAME, see exechelp.h for details. */ gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[], - estream_t infile, estream_t outfile, + gpg_err_source_t errsource, void (*preexec)(void), unsigned int flags, - estream_t *statusfile, pid_t *pid) + estream_t infp, + estream_t *r_outfp, + estream_t *r_errfp, + pid_t *pid) { gpg_error_t err; SECURITY_ATTRIBUTES sec_attr; @@ -381,33 +384,104 @@ STARTUPINFO si; int cr_flags; char *cmdline; - int fd, fdout, rp[2]; - HANDLE nullhd[2]; + HANDLE inhandle = INVALID_HANDLE_VALUE; + HANDLE outpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; + HANDLE errpipe[2] = {INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE}; + estream_t outfp = NULL; + estream_t errfp = NULL; + HANDLE nullhd[3] = {INVALID_HANDLE_VALUE, + INVALID_HANDLE_VALUE, + INVALID_HANDLE_VALUE}; int i; + es_syshd_t syshd; - (void)preexec; - - /* Setup return values. */ - *statusfile = NULL; - *pid = (pid_t)(-1); + if (r_outfp) + *r_outfp = NULL; + if (r_errfp) + *r_errfp = NULL; + *pid = (pid_t)(-1); /* Always required. */ - if (infile) + if (infp) { - es_fflush (infile); - es_rewind (infile); - fd = _get_osfhandle (es_fileno (infile)); + es_fflush (infp); + es_rewind (infp); + es_syshd (infp, &syshd); + switch (syshd.type) + { + case ES_SYSHD_FD: + inhandle = (HANDLE)_get_osfhandle (syshd.u.fd); + break; + case ES_SYSHD_SOCK: + inhandle = (HANDLE)_get_osfhandle (syshd.u.sock); + break; + case ES_SYSHD_HANDLE: + inhandle = syshd.u.handle; + break; + default: + inhandle = INVALID_HANDLE_VALUE; + break; + } + if (inhandle == INVALID_HANDLE_VALUE) + return gpg_err_make (errsource, GPG_ERR_INV_VALUE); + /* FIXME: In case we can't get a system handle (e.g. due to + es_fopencookie we should create a piper and a feeder + thread. */ } - else - fd = -1; - if (outfile) - fdout = _get_osfhandle (es_fileno (outfile)); - else - fdout = -1; + if (r_outfp) + { + if (create_inheritable_pipe (outpipe, 1)) + { + err = gpg_err_make (errsource, GPG_ERR_GENERAL); + log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); + return err; + } - if ( (infile && fd == -1) || (outfile && fdout == -1)) - log_fatal ("no file descriptor for file passed to gnupg_spawn_process\n"); + syshd.type = ES_SYSHD_HANDLE; + syshd.u.handle = outpipe[0]; + outfp = es_sysopen (&syshd, "r"); + if (!outfp) + { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + log_error (_("error creating a stream for a pipe: %s\n"), + gpg_strerror (err)); + CloseHandle (outpipe[0]); + CloseHandle (outpipe[1]); + outpipe[0] = outpipe[1] = INVALID_HANDLE_VALUE; + return err; + } + } + if (r_errfp) + { + if (create_inheritable_pipe (errpipe, 1)) + { + err = gpg_err_make (errsource, GPG_ERR_GENERAL); + log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); + return err; + } + + syshd.type = ES_SYSHD_HANDLE; + syshd.u.handle = errpipe[0]; + errfp = es_sysopen (&syshd, "r"); + if (!errfp) + { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + log_error (_("error creating a stream for a pipe: %s\n"), + gpg_strerror (err)); + CloseHandle (errpipe[0]); + CloseHandle (errpipe[1]); + errpipe[0] = errpipe[1] = INVALID_HANDLE_VALUE; + if (outfp) + es_fclose (outfp); + else if (outpipe[0] != INVALID_HANDLE_VALUE) + CloseHandle (outpipe[0]); + if (outpipe[1] != INVALID_HANDLE_VALUE) + CloseHandle (outpipe[1]); + return err; + } + } + /* Prepare security attributes. */ memset (&sec_attr, 0, sizeof sec_attr ); sec_attr.nLength = sizeof sec_attr; @@ -418,27 +492,24 @@ if (err) return err; - /* Create a pipe. */ - if (create_inheritable_pipe (rp, 1)) - { - err = gpg_error (GPG_ERR_GENERAL); - log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); - xfree (cmdline); - return err; - } - - nullhd[0] = fd == -1? w32_open_null (0) : INVALID_HANDLE_VALUE; - nullhd[1] = fdout == -1? w32_open_null (1) : INVALID_HANDLE_VALUE; + if (inhandle != INVALID_HANDLE_VALUE) + nullhd[0] = w32_open_null (0); + if (outpipe[1] != INVALID_HANDLE_VALUE) + nullhd[1] = w32_open_null (0); + if (errpipe[1] != INVALID_HANDLE_VALUE) + nullhd[2] = w32_open_null (0); /* Start the process. Note that we can't run the PREEXEC function - because this would change our own environment. */ + because this might change our own environment. */ + (void)preexec; + memset (&si, 0, sizeof si); si.cb = sizeof (si); si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; - si.hStdInput = fd == -1? nullhd[0] : fd_to_handle (fd); - si.hStdOutput = fdout == -1? nullhd[1] : fd_to_handle (fdout); - si.hStdError = fd_to_handle (rp[1]); + si.hStdInput = inhandle == INVALID_HANDLE_VALUE? nullhd[0] : inhandle; + si.hStdOutput = outpipe[1] == INVALID_HANDLE_VALUE? nullhd[1] : outpipe[1]; + si.hStdError = errpipe[1] == INVALID_HANDLE_VALUE? nullhd[2] : errpipe[1]; cr_flags = (CREATE_DEFAULT_ERROR_MODE | ((flags & 128)? DETACHED_PROCESS : 0) @@ -459,9 +530,19 @@ { log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); xfree (cmdline); - CloseHandle (fd_to_handle (rp[0])); - CloseHandle (fd_to_handle (rp[1])); - return gpg_error (GPG_ERR_GENERAL); + if (outfp) + es_fclose (outfp); + else if (outpipe[0] != INVALID_HANDLE_VALUE) + CloseHandle (outpipe[0]); + if (outpipe[1] != INVALID_HANDLE_VALUE) + CloseHandle (outpipe[1]); + if (errfp) + es_fclose (errfp); + else if (errpipe[0] != INVALID_HANDLE_VALUE) + CloseHandle (errpipe[0]); + if (errpipe[1] != INVALID_HANDLE_VALUE) + CloseHandle (errpipe[1]); + return gpg_err_make (errsource, GPG_ERR_GENERAL); } xfree (cmdline); cmdline = NULL; @@ -471,17 +552,21 @@ if (nullhd[i] != INVALID_HANDLE_VALUE) CloseHandle (nullhd[i]); - /* Close the other end of the pipe. */ - CloseHandle (fd_to_handle (rp[1])); + /* Close the inherited ends of the pipes. */ + if (outpipe[1] != INVALID_HANDLE_VALUE) + CloseHandle (outpipe[1]); + if (errpipe[1] != INVALID_HANDLE_VALUE) + CloseHandle (errpipe[1]); -/* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */ -/* " dwProcessID=%d dwThreadId=%d\n", */ -/* pi.hProcess, pi.hThread, */ -/* (int) pi.dwProcessId, (int) pi.dwThreadId); */ - + /* log_debug ("CreateProcess ready: hProcess=%p hThread=%p" */ + /* " dwProcessID=%d dwThreadId=%d\n", */ + /* pi.hProcess, pi.hThread, */ + /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ + /* log_debug (" outfp=%p errfp=%p\n", outfp, errfp); */ + /* Fixme: For unknown reasons AllowSetForegroundWindow returns an - invalid argument error if we pass the correct processID to - it. As a workaround we use -1 (ASFW_ANY). */ + invalid argument error if we pass it the correct processID. As a + workaround we use -1 (ASFW_ANY). */ if ( (flags & 64) ) gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/); @@ -489,23 +574,11 @@ ResumeThread (pi.hThread); CloseHandle (pi.hThread); - { - int x; + if (r_outfp) + *r_outfp = outfp; + if (r_errfp) + *r_errfp = errfp; - x = _open_osfhandle (rp[0], 0); - if (x == -1) - log_error ("failed to translate osfhandle %p\n", (void*)rp[0] ); - else - *statusfile = es_fdopen (x, "r"); - } - if (!*statusfile) - { - err = gpg_error_from_syserror (); - log_error (_("can't fdopen pipe for reading: %s\n"), gpg_strerror (err)); - CloseHandle (pi.hProcess); - return err; - } - *pid = handle_to_pid (pi.hProcess); return 0; Modified: trunk/common/exechelp-w32ce.c =================================================================== --- trunk/common/exechelp-w32ce.c 2010-08-19 13:38:37 UTC (rev 5400) +++ trunk/common/exechelp-w32ce.c 2010-08-20 12:18:38 UTC (rev 5401) @@ -83,7 +83,7 @@ }; -/* The thread started by start_feeded. */ +/* The thread started by start_feede3. */ static void * feeder_thread (void *arg) { @@ -485,10 +485,14 @@ /* Fork and exec the PGMNAME, see exechelp.h for details. */ gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[], - estream_t infile, estream_t outfile, + gpg_err_source_t errsource, void (*preexec)(void), unsigned int flags, - estream_t *statusfile, pid_t *pid) + estream_t infp, + estream_t *r_outfp, + estream_t *r_errfp, + pid_t *pid) { +#if 0 gpg_error_t err; PROCESS_INFORMATION pi = {NULL }; char *cmdline; @@ -598,7 +602,9 @@ *pid = handle_to_pid (pi.hProcess); return 0; - +#else + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); +#endif } Modified: trunk/common/exechelp.h =================================================================== --- trunk/common/exechelp.h 2010-08-19 13:38:37 UTC (rev 5400) +++ trunk/common/exechelp.h 2010-08-20 12:18:38 UTC (rev 5401) @@ -52,16 +52,25 @@ gpg_error_t gnupg_create_outbound_pipe (int filedes[2]); -/* Fork and exec the PGMNAME, connect the file descriptor of INFILE to - stdin, write the output to OUTFILE. INFILE or PUTFILE may be NULL - to connect thenm to /dev/null. Returns a new stream in STATUSFILE - for stderr and the pid of the process in PID. The arguments for the - process are expected in the NULL terminated array ARGV. The - program name itself should not be included there. If PREEXEC is - not NULL, that function will be called right before the exec. - Calling gnupg_wait_process and gnupg_release_process is required. - Returns 0 on success or an error code. +/* Fork and exec the PGMNAME. If INFP is NULL connect /dev/null to + stdin of the new process; if it is not NULL connect the file + descriptor retrieved from INFP to stdin. If R_OUTFP is NULL + connect stdout of the new process to /dev/null; if it is not NULL + store the address of a pointer to a new estream there. If R_ERRFP + is NULL connect stderr of the new process to /dev/null; if it is + not NULL store the address of a pointer to a new estream there. On + success the pid of the new process is stored at PID. On error -1 + is stored at PID and if R_OUTFP or R_ERRFP are not NULL, NULL is + stored there. + The arguments for the process are expected in the NULL terminated + array ARGV. The program name itself should not be included there. + If PREEXEC is not NULL, the given function will be called right + before the exec. + + Returns 0 on success or an error code. Calling gnupg_wait_process + and gnupg_release_process is required if the function succeeded. + FLAGS is a bit vector: Bit 7: If set the process will be started as a background process. @@ -74,10 +83,14 @@ allows SetForegroundWindow for all childs of this process. */ -gpg_error_t gnupg_spawn_process (const char *pgmname, const char *argv[], - estream_t infile, estream_t outfile, - void (*preexec)(void), unsigned int flags, - estream_t *statusfile, pid_t *pid); +gpg_error_t +gnupg_spawn_process (const char *pgmname, const char *argv[], + gpg_err_source_t errsource, From cvs at cvs.gnupg.org Mon Aug 23 18:27:11 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 23 Aug 2010 18:27:11 +0200 Subject: [svn] GnuPG - r5402 - in branches/STABLE-BRANCH-2-0: . tools Message-ID: Author: wk Date: 2010-08-23 18:27:10 +0200 (Mon, 23 Aug 2010) New Revision: 5402 Modified: branches/STABLE-BRANCH-2-0/NEWS branches/STABLE-BRANCH-2-0/README branches/STABLE-BRANCH-2-0/tools/ChangeLog branches/STABLE-BRANCH-2-0/tools/gpgconf-comp.c Log: Fix Modified: branches/STABLE-BRANCH-2-0/tools/ChangeLog =================================================================== --- branches/STABLE-BRANCH-2-0/tools/ChangeLog 2010-08-20 12:18:38 UTC (rev 5401) +++ branches/STABLE-BRANCH-2-0/tools/ChangeLog 2010-08-23 16:27:10 UTC (rev 5402) @@ -1,3 +1,10 @@ +2010-08-23 Werner Koch + + * gpgconf-comp.c (retrieve_options_from_program) + (retrieve_options_from_file, copy_file): Do not use ferror after a + failed fclose. Note that the stream is in any case invalid after + calling fclose and that fclose does set ERRNO. + 2010-08-19 Werner Koch * gpgconf.c (main): Fix --check-options. Modified: branches/STABLE-BRANCH-2-0/NEWS =================================================================== --- branches/STABLE-BRANCH-2-0/NEWS 2010-08-20 12:18:38 UTC (rev 5401) +++ branches/STABLE-BRANCH-2-0/NEWS 2010-08-23 16:27:10 UTC (rev 5402) @@ -1,7 +1,9 @@ Noteworthy changes in version 2.0.17 (unreleased) ------------------------------------------------- + * Fixed output of "gpgconf --check-options". + Noteworthy changes in version 2.0.16 (2010-07-19) ------------------------------------------------- Modified: branches/STABLE-BRANCH-2-0/README =================================================================== --- branches/STABLE-BRANCH-2-0/README 2010-08-20 12:18:38 UTC (rev 5401) +++ branches/STABLE-BRANCH-2-0/README 2010-08-23 16:27:10 UTC (rev 5402) @@ -12,7 +12,7 @@ GnuPG is GNU's tool for secure communication and data storage. It can be used to encrypt data and to create digital signatures. It includes an advanced key management facility and is compliant with the proposed -OpenPGP Internet standard as described in RFC2440 and the S/MIME +OpenPGP Internet standard as described in RFC4880 and the S/MIME standard as described by several RFCs. GnuPG is distributed under the terms of the GNU General Public Modified: branches/STABLE-BRANCH-2-0/tools/gpgconf-comp.c =================================================================== --- branches/STABLE-BRANCH-2-0/tools/gpgconf-comp.c 2010-08-20 12:18:38 UTC (rev 5401) +++ branches/STABLE-BRANCH-2-0/tools/gpgconf-comp.c 2010-08-23 16:27:10 UTC (rev 5402) @@ -1903,7 +1903,7 @@ } if (length < 0 || ferror (config)) gc_error (1, errno, "error reading from %s",pgmname); - if (fclose (config) && ferror (config)) + if (fclose (config)) gc_error (1, errno, "error closing %s", pgmname); err = gnupg_wait_process (pgmname, pid, &exitcode); @@ -2004,7 +2004,7 @@ if (length < 0 || ferror (config)) gc_error (1, errno, "error reading from %s", config_filename); - if (fclose (config) && ferror (config)) + if (fclose (config)) gc_error (1, errno, "error closing %s", config_filename); } @@ -2084,7 +2084,7 @@ if (config_option->flags & GC_OPT_FLAG_NO_CHANGE) list_option->flags |= GC_OPT_FLAG_NO_CHANGE; - if (list_file && fclose (list_file) && ferror (list_file)) + if (list_file && fclose (list_file)) gc_error (1, errno, "error closing %s", list_filename); xfree (line); } @@ -2305,9 +2305,9 @@ return -1; } - if (fclose (dst) && ferror (dst)) + if (fclose (dst)) gc_error (1, errno, "error closing %s", dst_name); - if (fclose (src) && ferror (src)) + if (fclose (src)) gc_error (1, errno, "error closing %s", src_name); return 0; From cvs at cvs.gnupg.org Mon Aug 23 21:26:06 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 23 Aug 2010 21:26:06 +0200 Subject: [svn] GnuPG - r5403 - in trunk: common tools Message-ID: Author: wk Date: 2010-08-23 21:26:05 +0200 (Mon, 23 Aug 2010) New Revision: 5403 Modified: trunk/common/ChangeLog trunk/common/estream.c trunk/common/estream.h trunk/common/exechelp-w32.c trunk/common/exechelp-w32ce.c trunk/common/init.c trunk/tools/ChangeLog trunk/tools/Makefile.am trunk/tools/gpgconf-comp.c Log: gpgconf does now work for Wince. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2010-08-23 16:27:10 UTC (rev 5402) +++ trunk/common/ChangeLog 2010-08-23 19:26:05 UTC (rev 5403) @@ -1,3 +1,15 @@ +2010-08-23 Werner Koch + + * exechelp-w32ce.c: Rewrite all spawn stuff. + + * exechelp-w32.c (close_all_fds) [W32]: Make it a dummy function. + + * estream.c (es_onclose): New. + (notify_list_t, onclose): New. + (struct estream_internal): Add field ONCLOSE. + (es_initialize, es_deinitialize): Manage new field. + (do_close): Call onclose notify functions. + 2010-08-20 Werner Koch * exechelp-w32.c (create_inheritable_pipe): Change arg to HANDLE. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2010-08-23 16:27:10 UTC (rev 5402) +++ trunk/tools/ChangeLog 2010-08-23 19:26:05 UTC (rev 5403) @@ -1,3 +1,17 @@ +2010-08-23 Werner Koch + + * gpgconf-comp.c (GPGNAME) [W32CE]: s/gpg2/gpg/. + (get_config_filename) [W32CE]: Adjust absolute file name check. + + * gpgconf-comp.c (retrieve_options_from_program) + (retrieve_options_from_file, retrieve_options_from_program) + (copy_file, gc_process_gpgconf_conf): Do not use es_ferror after a + failed es_fclose. Note that the stream is in any case invalid + after calling es_fclose and that es_fclose does set ERRNO. + + * Makefile.am (maybe_commonpth_libs): New. + (gpgconf_LDADD): Use it. + 2010-08-20 Werner Koch * gpgconf-comp.c (collect_error_output): Remove extra CRs. Modified: trunk/common/estream.c =================================================================== --- trunk/common/estream.c 2010-08-23 16:27:10 UTC (rev 5402) +++ trunk/common/estream.c 2010-08-23 19:26:05 UTC (rev 5403) @@ -202,8 +202,16 @@ #define ES_DEFAULT_OPEN_MODE (S_IRUSR | S_IWUSR) +/* A linked list to hold notification functions. */ +struct notify_list_s +{ + struct notify_list_s *next; + void (*fnc) (estream_t, void*); /* The notification function. */ + void *fnc_value; /* The value to be passed to FNC. */ +}; +typedef struct notify_list_s *notify_list_t; + /* An internal stream object. */ - struct estream_internal { unsigned char buffer[BUFFER_BLOCK_SIZE]; @@ -230,6 +238,7 @@ unsigned int stdstream_fd:2; /* 0, 1 or 2 for a standard stream. */ unsigned int printable_fname_inuse: 1; /* es_fname_get has been used. */ size_t print_ntotal; /* Bytes written from in print_writer. */ + notify_list_t onclose; /* On close notify function list. */ }; @@ -1534,6 +1543,7 @@ stream->intern->deallocate_buffer = 0; stream->intern->printable_fname = NULL; stream->intern->printable_fname_inuse = 0; + stream->intern->onclose = NULL; stream->data_len = 0; stream->data_offset = 0; @@ -1568,6 +1578,12 @@ mem_free (stream->intern->printable_fname); stream->intern->printable_fname = NULL; stream->intern->printable_fname_inuse = 0; + while (stream->intern->onclose) + { + notify_list_t tmp = stream->intern->onclose->next; + mem_free (stream->intern->onclose); + stream->intern->onclose = tmp; + } return err; } @@ -1637,6 +1653,16 @@ if (stream) { es_list_remove (stream, with_locked_list); + while (stream->intern->onclose) + { + notify_list_t tmp = stream->intern->onclose->next; + + if (stream->intern->onclose->fnc) + stream->intern->onclose->fnc (stream, + stream->intern->onclose->fnc_value); + mem_free (stream->intern->onclose); + stream->intern->onclose = tmp; + } err = es_deinitialize (stream); mem_free (stream->intern); mem_free (stream); @@ -1647,6 +1673,34 @@ return err; } + +/* This worker function is called with a locked stream. */ +static int +do_onclose (estream_t stream, int mode, + void (*fnc) (estream_t, void*), void *fnc_value) +{ + notify_list_t item; + + if (!mode) + { + for (item = stream->intern->onclose; item; item = item->next) + if (item->fnc && item->fnc == fnc && item->fnc_value == fnc_value) + item->fnc = NULL; /* Disable this notification. */ + } + else + { + item = mem_alloc (sizeof *item); + if (!item) + return -1; + item->fnc = fnc; + item->fnc_value = fnc_value; + item->next = stream->intern->onclose; + stream->intern->onclose = item; + } + return 0; +} + + /* Try to read BYTES_TO_READ bytes FROM STREAM into BUFFER in unbuffered-mode, storing the amount of bytes read in *BYTES_READ. */ @@ -2760,6 +2814,7 @@ void _es_set_std_fd (int no, int fd) { + fprintf (stderr, "es_set_std_fd(%d, %d)\n", no, fd); ESTREAM_LIST_LOCK; if (no >= 0 && no < 3 && !custom_std_fds_valid[no]) { @@ -2908,7 +2963,35 @@ } +/* Register or unregister a close notification function for STREAM. + FNC is the function to call and FNC_VALUE the value passed as + second argument. To register the notification the value for MODE + must be 1. If mode is 0 the function tries to remove or disable an + already registered notification; for this to work the value of FNC + and FNC_VALUE must be the same as with the registration and + FNC_VALUE must be a unique value. No error will be returned if + MODE is 0. Unregistered should only be used in the error case + because it may not remove memory internall allocated for the + onclose handler. + + The notification will be called right before the stream is closed. + It may not call any estream function for STREAM, neither direct nor + indirectly. */ int +es_onclose (estream_t stream, int mode, + void (*fnc) (estream_t, void*), void *fnc_value) +{ + int err; + + ESTREAM_LOCK (stream); + err = do_onclose (stream, mode, fnc, fnc_value); + ESTREAM_UNLOCK (stream); + + return err; +} + + +int es_fileno_unlocked (estream_t stream) { es_syshd_t syshd; Modified: trunk/common/estream.h =================================================================== --- trunk/common/estream.h 2010-08-23 16:27:10 UTC (rev 5402) +++ trunk/common/estream.h 2010-08-23 19:26:05 UTC (rev 5403) @@ -87,6 +87,7 @@ #define es_freopen _ESTREAM_PREFIX(es_freopen) #define es_fopencookie _ESTREAM_PREFIX(es_fopencookie) #define es_fclose _ESTREAM_PREFIX(es_fclose) +#define es_onclose _ESTREAM_PREFIX(es_onclose) #define es_fileno _ESTREAM_PREFIX(es_fileno) #define es_fileno_unlocked _ESTREAM_PREFIX(es_fileno_unlocked) #define es_flockfile _ESTREAM_PREFIX(es_flockfile) @@ -281,6 +282,8 @@ const char *ES__RESTRICT mode, es_cookie_io_functions_t functions); int es_fclose (estream_t stream); +int es_onclose (estream_t stream, int mode, + void (*fnc) (estream_t, void*), void *fnc_value); int es_fileno (estream_t stream); int es_fileno_unlocked (estream_t stream); int es_syshd (estream_t stream, es_syshd_t *syshd); Modified: trunk/common/exechelp-w32.c =================================================================== --- trunk/common/exechelp-w32.c 2010-08-23 16:27:10 UTC (rev 5402) +++ trunk/common/exechelp-w32.c 2010-08-23 19:26:05 UTC (rev 5403) @@ -94,43 +94,12 @@ } -/* Close all file descriptors starting with descriptor FIRST. If - EXCEPT is not NULL, it is expected to be a list of file descriptors - which shall not be closed. This list shall be sorted in ascending - order with the end marked by -1. */ +/* Under Windows this is a dummy function. */ void close_all_fds (int first, int *except) { - int max_fd = get_max_fds (); - int fd, i, except_start; - - if (except) - { - except_start = 0; - for (fd=first; fd < max_fd; fd++) - { - for (i=except_start; except[i] != -1; i++) - { - if (except[i] == fd) - { - /* If we found the descriptor in the exception list - we can start the next compare run at the next - index because the exception list is ordered. */ - except_start = i + 1; - break; - } - } - if (except[i] == -1) - close (fd); - } - } - else - { - for (fd=first; fd < max_fd; fd++) - close (fd); - } - - gpg_err_set_errno (0); + (void)first; + (void)except; } Modified: trunk/common/exechelp-w32ce.c =================================================================== --- trunk/common/exechelp-w32ce.c 2010-08-23 16:27:10 UTC (rev 5402) +++ trunk/common/exechelp-w32ce.c 2010-08-23 19:26:05 UTC (rev 5403) @@ -78,7 +78,8 @@ struct feeder_thread_parms { estream_t stream; - int fd; + volatile int stream_valid; + HANDLE hd; int direction; }; @@ -89,71 +90,106 @@ { struct feeder_thread_parms *parm = arg; char buffer[4096]; + int rc; if (parm->direction) { - size_t nread; + size_t nread = 0; DWORD nwritten; - while (!es_read (parm->stream, buffer, sizeof buffer, &nread)) + log_debug ("feeder_thread estream->pipe: stream=%p pipe=%p\n", + parm->stream, parm->hd); + while (parm->stream_valid + && !es_read (parm->stream, buffer, sizeof buffer, &nread)) { do { - if (!WriteFile (fd_to_handle (parm->fd), - buffer, nread, &nwritten, NULL)) + pth_enter (); + rc = WriteFile (parm->hd, buffer, nread, &nwritten, NULL); + pth_leave (); + if (!rc) { - log_debug ("feeder(%d): WriteFile error: rc=%d\n", - parm->fd, (int)GetLastError ()); + log_debug ("feeder(%p): WriteFile error: rc=%d\n", + parm->hd, (int)GetLastError ()); goto leave; } nread -= nwritten; } while (nread); } - if (nread) - log_debug ("feeder(%d): es_read error: %s\n", - parm->fd, strerror (errno)); + if (!parm->stream_valid) + log_debug ("feeder(%p): closed by other thread\n", parm->hd); + else if (nread) + log_debug ("feeder(%p): es_read error: %s\n", + parm->hd, strerror (errno)); } else { - DWORD nread; + DWORD nread = 0; size_t nwritten; - while (ReadFile (fd_to_handle (parm->fd), - buffer, sizeof buffer, &nread, NULL) && nread) + log_debug ("feeder_thread pipe->estream: stream=%p pipe=%p\n", + parm->stream, parm->hd); + while ( (pth_enter (), + (rc = ReadFile (parm->hd, buffer, sizeof buffer, &nread, NULL)), + pth_leave (), + rc) && nread) { - do + log_debug ("feeder_thread pipe->estream: read %d bytes\n", + (int)nread); + do { - if (es_write (parm->stream, buffer, nread, &nwritten)) + if (parm->stream_valid + && es_write (parm->stream, buffer, nread, &nwritten)) { - log_debug ("feeder(%d): es_write error: %s\n", - parm->fd, strerror (errno)); + log_debug ("feeder(%p): es_write error: %s\n", + parm->hd, strerror (errno)); goto leave; } + log_debug ("feeder_thread pipe->estream: es_wrote %d bytes\n", + (int)nwritten); nread -= nwritten; } - while (nread); + while (nread && parm->stream_valid); } - if (nread) - log_debug ("feeder(%d): ReadFile error: rc=%d\n", - parm->fd, (int)GetLastError ()); + if (!parm->stream_valid) + log_debug ("feeder(%p): closed by other thread\n", parm->hd); + else if (nread) + log_debug ("feeder(%p): ReadFile error: rc=%d\n", + parm->hd, (int)GetLastError ()); else - log_debug ("feeder(%d): eof\n", parm->fd); + log_debug ("feeder(%p): eof\n", parm->hd); } leave: - CloseHandle (fd_to_handle (parm->fd)); + log_debug ("feeder(%p): waiting for es_fclose\n", parm->hd); + while (parm->stream_valid) + pth_yield (NULL); + log_debug ("feeder(%p): about to close the pipe handle\n", parm->hd); + CloseHandle (parm->hd); + log_debug ("feeder(%p): pipe handle closed\n", parm->hd); xfree (parm); return NULL; } #endif /*USE_GNU_PTH*/ +#ifdef USE_GNU_PTH +static void +feeder_onclose_notification (estream_t stream, void *opaque) +{ + struct feeder_thread_parms *parm = opaque; + (void)stream; + log_debug ("feeder(%p): received onclose note\n", parm->hd); + parm->stream_valid = 0; +} +#endif /*USE_GNU_PTH*/ + /* Fire up a thread to copy data between STREAM and a pipe's descriptor FD. With DIRECTION set to true the copy takes place from the stream to the pipe, otherwise from the pipe to the stream. */ static gpg_error_t -start_feeder (estream_t stream, int fd, int direction) +start_feeder (estream_t stream, HANDLE hd, int direction) { #ifdef USE_GNU_PTH gpg_error_t err; @@ -164,19 +200,27 @@ if (!parm) return gpg_error_from_syserror (); parm->stream = stream; - parm->fd = fd; + parm->stream_valid = 1; + parm->hd = hd; parm->direction = direction; + + if (es_onclose (stream, 1, feeder_onclose_notification, parm)) + { + err = gpg_error_from_syserror (); + xfree (parm); + return err; + } tattr = pth_attr_new (); pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 64*1024); pth_attr_set (tattr, PTH_ATTR_NAME, "exec-feeder"); - log_error ("spawning new feeder(%p, %d, %d)\n", stream, fd, direction); + log_debug ("spawning new feeder(%p, %p, %d)\n", stream, hd, direction); if(!pth_spawn (tattr, feeder_thread, parm)) { err = gpg_error_from_syserror (); - log_error ("error spawning feeder: %s\n", gpg_strerror (err)); + es_onclose (stream, 0, feeder_onclose_notification, parm); xfree (parm); } else @@ -186,7 +230,7 @@ return err; #else (void)stream; - (void)fd; + (void)hd; (void)direction; return gpg_error (GPG_ERR_NOT_IMPLEMENTED); /* No Pth. */ #endif @@ -214,50 +258,19 @@ } -/* Close all file descriptors starting with descriptor FIRST. If - EXCEPT is not NULL, it is expected to be a list of file descriptors - which shall not be closed. This list shall be sorted in ascending - order with the end marked by -1. */ +/* Under Windows this is a dummy function. */ void close_all_fds (int first, int *except) { - int max_fd = get_max_fds (); - int fd, i, except_start; - - if (except) - { - except_start = 0; - for (fd=first; fd < max_fd; fd++) - { - for (i=except_start; except[i] != -1; i++) - { - if (except[i] == fd) - { - /* If we found the descriptor in the exception list - we can start the next compare run at the next - index because the exception list is ordered. */ - except_start = i + 1; - break; - } - } - if (except[i] == -1) - close (fd); - } - } - else - { - for (fd=first; fd < max_fd; fd++) - close (fd); - } - - gpg_err_set_errno (0); + (void)first; + (void)except; } /* Returns an array with all currently open file descriptors. The end of the array is marked by -1. The caller needs to release this array using the *standard free* and not with xfree. This allow the - use of this fucntion right at startup even before libgcrypt has + use of this function right at startup even before libgcrypt has been initialized. Returns NULL on error and sets ERRNO accordingly. */ int * @@ -335,9 +348,7 @@ CMDLINE gets the address of a newly allocated string. */ static int build_w32_commandline (const char * const *argv, - int fd0, int fd0_isnull, - int fd1, int fd1_isnull, - int fd2, int fd2_isnull, + int rvid0, int rvid1, int rvid2, char **cmdline) { int i, n; @@ -347,30 +358,24 @@ p = fdbuf; *p = 0; - if (fd0) - { - if (fd0_isnull) - strcpy (p, "-&S0=null "); - else - snprintf (p, 25, "-&S0=%d ", fd0); - p += strlen (p); - } - if (fd1) - { - if (fd1_isnull) - strcpy (p, "-&S1=null "); - else - snprintf (p, 25, "-&S1=%d ", fd1); - p += strlen (p); - } - if (fd2) - { - if (fd2_isnull) - strcpy (p, "-&S2=null "); - else - snprintf (p, 25, "-&S2=%d ", fd2); - p += strlen (p); - } + + if (rvid0) + snprintf (p, 25, "-&S0=%d ", rvid0); + else + strcpy (p, "-&S0=null "); + p += strlen (p); + + if (rvid1) + snprintf (p, 25, "-&S1=%d ", rvid1); + else + strcpy (p, "-&S1=null "); + p += strlen (p); + + if (rvid2) + snprintf (p, 25, "-&S2=%d ", rvid2); + else + strcpy (p, "-&S2=null "); + p += strlen (p); *cmdline = NULL; n = strlen (fdbuf); @@ -492,94 +497,149 @@ estream_t *r_errfp, pid_t *pid) { -#if 0 gpg_error_t err; PROCESS_INFORMATION pi = {NULL }; char *cmdline; - int inpipe[2], outpipe[2], errpipe[2]; + es_syshd_t syshd; + struct { + HANDLE hd; + int rvid; + } inpipe = {INVALID_HANDLE_VALUE, 0}; + struct { + HANDLE hd; + int rvid; + } outpipe = {INVALID_HANDLE_VALUE, 0}; + struct { + HANDLE hd; + int rvid; + } errpipe = {INVALID_HANDLE_VALUE, 0}; + estream_t outfp = NULL; + estream_t errfp = NULL; (void)preexec; (void)flags; /* Setup return values. */ - *statusfile = NULL; - *pid = (pid_t)(-1); + if (r_outfp) + *r_outfp = NULL; + if (r_errfp) + *r_errfp = NULL; + *pid = (pid_t)(-1); /* Always required. */ - /* A NULL INFILE or OUTFILE is only used by gpgtar thus we don't - need to implement this for CE. */ - if (!infile || !outfile) - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + log_debug ("%s: enter\n", __func__); + if (infp) + { + es_fflush (infp); + es_rewind (infp); - es_fflush (infile); - es_rewind (infile); + /* Create a pipe to copy our infile to the stdin of the child + process. On success inpipe.hd is owned by the feeder. */ + inpipe.hd = _assuan_w32ce_prepare_pipe (&inpipe.rvid, 1); + if (inpipe.hd == INVALID_HANDLE_VALUE) + { + log_error ("_assuan_w32ce_prepare_pipe failed: %s\n", + w32_strerror (-1)); + gpg_err_set_errno (EIO); + return gpg_error_from_syserror (); + } + log_debug ("%s: inpipe %p created; hd=%p rvid=%d\n", __func__, + infp, inpipe.hd, inpipe.rvid); + err = start_feeder (infp, inpipe.hd, 1); + if (err) + { + log_error ("error spawning feeder: %s\n", gpg_strerror (err)); + CloseHandle (inpipe.hd); + return err; + } + inpipe.hd = INVALID_HANDLE_VALUE; /* Now owned by the feeder. */ + log_debug ("%s: inpipe %p created; feeder started\n", __func__, + infp); + } - /* Create a pipe to copy our infile to the stdin of the child - process. On success inpipe[1] is owned by the feeder. */ - err = create_inheritable_pipe (inpipe, 0); - if (err) + if (r_outfp) { - log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); - return err; + /* Create a pipe to make the stdout of the child process + available as a stream. */ + outpipe.hd = _assuan_w32ce_prepare_pipe (&outpipe.rvid, 0); + if (outpipe.hd == INVALID_HANDLE_VALUE) + { + log_error ("_assuan_w32ce_prepare_pipe failed: %s\n", + w32_strerror (-1)); + gpg_err_set_errno (EIO); + /* Fixme release other stuff/kill feeder. */ + return gpg_error_from_syserror (); + } + syshd.type = ES_SYSHD_HANDLE; + syshd.u.handle = outpipe.hd; + err = 0; + outfp = es_sysopen (&syshd, "r"); + if (!outfp) + { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + log_error ("error opening pipe stream: %s\n", gpg_strerror (err)); + CloseHandle (outpipe.hd); + return err; + } + log_debug ("%s: outpipe %p created; hd=%p rvid=%d\n", __func__, + outfp, outpipe.hd, outpipe.rvid); + outpipe.hd = INVALID_HANDLE_VALUE; /* Now owned by the OUTFP. */ } - err = start_feeder (infile, inpipe[1], 1); - if (err) - { - log_error (_("error spawning feeder: %s\n"), gpg_strerror (err)); - CloseHandle (fd_to_handle (inpipe[1])); - return err; - } - /* Create a pipe to copy stdout of the child process to our - outfile. On success outpipe[0] is owned by the feeded. */ - err = create_inheritable_pipe (outpipe, 1); - if (err) + if (r_errfp) { - log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); - return err; + /* Create a pipe to make the stderr of the child process + available as a stream. */ + errpipe.hd = _assuan_w32ce_prepare_pipe (&errpipe.rvid, 0); + if (errpipe.hd == INVALID_HANDLE_VALUE) + { + log_error ("_assuan_w32ce_prepare_pipe failed: %s\n", + w32_strerror (-1)); + gpg_err_set_errno (EIO); + /* Fixme release other stuff/kill feeder. */ + return gpg_error_from_syserror (); + } + syshd.type = ES_SYSHD_HANDLE; + syshd.u.handle = errpipe.hd; + err = 0; + errfp = es_sysopen (&syshd, "r"); + if (!errfp) + { + err = gpg_err_make (errsource, gpg_err_code_from_syserror ()); + log_error ("error opening pipe stream: %s\n", gpg_strerror (err)); + CloseHandle (errpipe.hd); + return err; + } + log_debug ("%s: errpipe %p created; hd=%p rvid=%d\n", __func__, + errfp, errpipe.hd, errpipe.rvid); + errpipe.hd = INVALID_HANDLE_VALUE; /* Now owned by the ERRFP. */ } - err = start_feeder (outfile, outpipe[0], 0); - if (err) - { - log_error (_("error spawning feeder: %s\n"), gpg_strerror (err)); - CloseHandle (fd_to_handle (outpipe[0])); - return err; - } - /* Create a pipe for use with stderr of the child process. */ - err = create_inheritable_pipe (errpipe, 1); - if (err) - { - log_error (_("error creating a pipe: %s\n"), gpg_strerror (err)); - return err; - } /* Build the command line. */ - err = build_w32_commandline (argv, - inpipe[0], 0, - outpipe[1], 0, - errpipe[1], 0, + err = build_w32_commandline (argv, inpipe.rvid, outpipe.rvid, errpipe.rvid, &cmdline); if (err) { - CloseHandle (fd_to_handle (errpipe[0])); + /* Fixme release other stuff/kill feeder. */ + CloseHandle (errpipe.hd); return err; } - log_debug ("CreateProcess, path=`%s' cmdline=`%s'\n", pgmname, cmdline); if (!create_process (pgmname, cmdline, &pi)) { log_error ("CreateProcess failed: %s\n", w32_strerror (-1)); xfree (cmdline); - CloseHandle (fd_to_handle (errpipe[0])); + /* Fixme release other stuff/kill feeder. */ + CloseHandle (errpipe.hd); return gpg_error (GPG_ERR_GENERAL); } xfree (cmdline); cmdline = NULL; /* Note: The other end of the pipe is a rendezvous id and thus there - is no need to close. */ + is no need for a close. */ log_debug ("CreateProcess ready: hProcess=%p hThread=%p" " dwProcessID=%d dwThreadId=%d\n", @@ -591,20 +651,12 @@ ResumeThread (pi.hThread); CloseHandle (pi.hThread); - *statusfile = es_fdopen (handle_to_fd (errpipe[0]), "r"); - if (!*statusfile) - { - err = gpg_error_from_syserror (); - log_error (_("can't fdopen pipe for reading: %s\n"), gpg_strerror (err)); - CloseHandle (pi.hProcess); - return err; - } - + if (r_outfp) + *r_outfp = outfp; + if (r_errfp) + *r_errfp = errfp; *pid = handle_to_pid (pi.hProcess); return 0; -#else - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); -#endif } @@ -632,7 +684,7 @@ return gpg_error (GPG_ERR_NOT_SUPPORTED); /* Build the command line. */ - err = build_w32_commandline (argv, -1, 1, -1, 1, -1, 1, &cmdline); + err = build_w32_commandline (argv, 0, 0, 0, &cmdline); if (err) return err; @@ -755,7 +807,7 @@ (void)envp; /* Build the command line. */ - err = build_w32_commandline (argv, -1, 1, -1, 1, -1, 1, &cmdline); + err = build_w32_commandline (argv, 0, 0, 0, &cmdline); if (err) return err; Modified: trunk/common/init.c =================================================================== --- trunk/common/init.c 2010-08-23 16:27:10 UTC (rev 5402) +++ trunk/common/init.c 2010-08-23 19:26:05 UTC (rev 5403) @@ -118,9 +118,18 @@ (void)argvp; #endif + /* Access the standard estreams as early as possible. If we don't + do this the original stdio streams may have been closed when + _es_get_std_stream is first use and in turn it would connect to + the bit bucket. */ + { + int i; + for (i=0; i < 3; i++) + (void)_es_get_std_stream (i); + } + /* --version et al shall use estream as well. */ argparse_register_outfnc (writestring_via_estream); - } @@ -191,6 +200,6 @@ argv[i] = NULL; } - + } #endif /*HAVE_W32CE_SYSTEM*/ Modified: trunk/tools/Makefile.am =================================================================== --- trunk/tools/Makefile.am 2010-08-23 16:27:10 UTC (rev 5402) +++ trunk/tools/Makefile.am 2010-08-23 19:26:05 UTC (rev 5403) @@ -67,7 +67,15 @@ common_libs = $(libcommon) ../gl/libgnu.a commonpth_libs = $(libcommonpth) ../gl/libgnu.a + +# Some modules require PTH under W32CE. if HAVE_W32CE_SYSTEM +maybe_commonpth_libs = $(commonpth_libs) +else +maybe_commonpth_libs = $(common_libs) +endif + +if HAVE_W32CE_SYSTEM pwquery_libs = else pwquery_libs = ../common/libsimple-pwquery.a @@ -85,8 +93,8 @@ # 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) $(opt_libassuan_libs) \ - $(LIBINTL) $(GPG_ERROR_LIBS) $(NETLIBS) \ +gpgconf_LDADD = $(maybe_commonpth_libs) $(opt_libassuan_libs) \ + $(LIBINTL) $(GPG_ERROR_LIBS) $(PTH_LIBS) $(NETLIBS) \ $(LIBICONV) $(W32SOCKLIBS) gpgparsemail_SOURCES = gpgparsemail.c rfc822parse.c rfc822parse.h Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2010-08-23 16:27:10 UTC (rev 5402) +++ trunk/tools/gpgconf-comp.c 2010-08-23 19:26:05 UTC (rev 5403) @@ -54,9 +54,8 @@ /* There is a problem with gpg 1.4 under Windows: --gpgconf-list returns a plain filename without escaping. As long as we have not - fixed that we need to use gpg2 - it might actually be better to use - gpg2 in any case. */ -#ifdef HAVE_W32_SYSTEM + fixed that we need to use gpg2. */ +#if defined(HAVE_W32_SYSTEM) && !defined(HAVE_W32CE_SYSTEM) #define GPGNAME "gpg2" #else #define GPGNAME "gpg" @@ -1799,7 +1798,9 @@ else filename = ""; -#ifdef HAVE_DOSISH_SYSTEM +#if HAVE_W32CE_SYSTEM + if (!(filename[0] == '/' || filename[0] == '\\')) +#elif defined(HAVE_DOSISH_SYSTEM) if (!(filename[0] && filename[1] == ':' && (filename[2] == '/' || filename[2] == '\\'))) @@ -1916,7 +1917,7 @@ } if (length < 0 || es_ferror (outfp)) gc_error (1, errno, "error reading from %s", pgmname); - if (es_fclose (outfp) && es_ferror (outfp)) + if (es_fclose (outfp)) gc_error (1, errno, "error closing %s", pgmname); err = gnupg_wait_process (pgmname, pid, 1, &exitcode); @@ -2018,7 +2019,7 @@ if (length < 0 || es_ferror (config)) gc_error (1, errno, "error reading from %s", config_filename); - if (es_fclose (config) && es_ferror (config)) + if (es_fclose (config)) gc_error (1, errno, "error closing %s", config_filename); } @@ -2098,7 +2099,7 @@ if (config_option->flags & GC_OPT_FLAG_NO_CHANGE) list_option->flags |= GC_OPT_FLAG_NO_CHANGE; - if (list_file && fclose (list_file) && ferror (list_file)) + if (list_file && fclose (list_file)) gc_error (1, errno, "error closing %s", list_filename); xfree (line); } @@ -2328,9 +2329,9 @@ return -1; } - if (fclose (dst) && ferror (dst)) + if (fclose (dst)) gc_error (1, errno, "error closing %s", dst_name); - if (fclose (src) && ferror (src)) + if (fclose (src)) gc_error (1, errno, "error closing %s", src_name); return 0; @@ -3623,7 +3624,7 @@ gc_error (0, errno, "error reading from `%s'", fname); result = -1; } - if (fclose (config) && ferror (config)) + if (fclose (config)) gc_error (0, errno, "error closing `%s'", fname); xfree (line); From cvs at cvs.gnupg.org Wed Aug 25 12:31:48 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 25 Aug 2010 12:31:48 +0200 Subject: [svn] GnuPG - r5404 - trunk/tools Message-ID: Author: wk Date: 2010-08-25 12:31:47 +0200 (Wed, 25 Aug 2010) New Revision: 5404 Modified: trunk/tools/ChangeLog trunk/tools/gpgtar-extract.c trunk/tools/gpgtar-list.c trunk/tools/gpgtar.c Log: Changed option names. Add O_BINARY for stdin and stdout. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2010-08-23 19:26:05 UTC (rev 5403) +++ trunk/tools/ChangeLog 2010-08-25 10:31:47 UTC (rev 5404) @@ -1,3 +1,15 @@ +2010-08-25 Werner Koch + + * gpgtar.c: Add -t as short option for --list-archive. + + * gpgtar-extract.c (gpgtar_extract): Use filename "-" for stdin. + Fix dirprefix setting. + * gpgtar-list.c (gpgtar_list): Ditto. + +2010-08-24 Werner Koch + + * gpgtar.c (opts): Fix --cms and --openpgp names. + 2010-08-23 Werner Koch * gpgconf-comp.c (GPGNAME) [W32CE]: s/gpg2/gpg/. Modified: trunk/tools/gpgtar-extract.c =================================================================== --- trunk/tools/gpgtar-extract.c 2010-08-23 19:26:05 UTC (rev 5403) +++ trunk/tools/gpgtar-extract.c 2010-08-25 10:31:47 UTC (rev 5404) @@ -79,7 +79,7 @@ leave: if (!err && opt.verbose) - log_info ("extracted `%s/'\n", fname); + log_info ("extracted `%s'\n", fname); es_fclose (outfp); if (err && fname && outfp) { @@ -270,7 +270,10 @@ if (filename) { - stream = es_fopen (filename, "rb"); + if (!strcmp (filename, "-")) + stream = es_stdout; + else + stream = es_fopen (filename, "rb"); if (!stream) { err = gpg_error_from_syserror (); @@ -279,20 +282,26 @@ } } else - stream = es_stdin; /* FIXME: How can we enforce binary mode? */ + stream = es_stdin; + if (stream == es_stdin) + es_set_binary (es_stdin); if (filename) { dirprefix = strrchr (filename, '/'); if (dirprefix) dirprefix++; + else + dirprefix = filename; } else if (opt.filename) { dirprefix = strrchr (opt.filename, '/'); if (dirprefix) dirprefix++; + else + dirprefix = opt.filename; } if (!dirprefix || !*dirprefix) Modified: trunk/tools/gpgtar-list.c =================================================================== --- trunk/tools/gpgtar-list.c 2010-08-23 19:26:05 UTC (rev 5403) +++ trunk/tools/gpgtar-list.c 2010-08-25 10:31:47 UTC (rev 5404) @@ -275,7 +275,10 @@ if (filename) { - stream = es_fopen (filename, "rb"); + if (!strcmp (filename, "-")) + stream = es_stdout; + else + stream = es_fopen (filename, "rb"); if (!stream) { err = gpg_error_from_syserror (); @@ -284,8 +287,11 @@ } } else - stream = es_stdin; /* FIXME: How can we enforce binary mode? */ + stream = es_stdin; + if (stream == es_stdin) + es_set_binary (es_stdin); + for (;;) { header = read_header (stream); @@ -303,7 +309,7 @@ leave: xfree (header); - if (filename) + if (stream != es_stdin) es_fclose (stream); return; } Modified: trunk/tools/gpgtar.c =================================================================== --- trunk/tools/gpgtar.c 2010-08-23 19:26:05 UTC (rev 5403) +++ trunk/tools/gpgtar.c 2010-08-25 10:31:47 UTC (rev 5404) @@ -48,6 +48,7 @@ aEncrypt = 'e', aDecrypt = 'd', aSign = 's', + aList = 't', oSymmetric = 'c', oRecipient = 'r', @@ -63,7 +64,6 @@ oOpenPGP, oCMS, oSetFilename, - aList, oNull }; @@ -91,8 +91,8 @@ ARGPARSE_s_s (oFilesFrom, "files-from", N_("|FILE|get names to create from FILE")), ARGPARSE_s_n (oNull, "null", N_("-T reads null-terminated names")), - ARGPARSE_s_n (oOpenPGP, "--openpgp", "@"), - ARGPARSE_s_n (oCMS, "--cms", "@"), + ARGPARSE_s_n (oOpenPGP, "openpgp", "@"), + ARGPARSE_s_n (oCMS, "cms", "@"), ARGPARSE_end () }; From cvs at cvs.gnupg.org Thu Aug 26 10:47:43 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 26 Aug 2010 10:47:43 +0200 Subject: [svn] GnuPG - r5405 - in trunk: agent common tools Message-ID: Author: wk Date: 2010-08-26 10:47:42 +0200 (Thu, 26 Aug 2010) New Revision: 5405 Modified: trunk/agent/ChangeLog trunk/agent/command-ssh.c trunk/agent/findkey.c trunk/agent/gpg-agent.c trunk/agent/trustlist.c trunk/common/ChangeLog trunk/common/estream.c trunk/tools/ChangeLog trunk/tools/gpgtar-extract.c Log: From cvs at cvs.gnupg.org Thu Aug 26 11:28:11 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 26 Aug 2010 11:28:11 +0200 Subject: [svn] GnuPG - r5406 - trunk/common Message-ID: Author: wk Date: 2010-08-26 11:28:11 +0200 (Thu, 26 Aug 2010) New Revision: 5406 Modified: trunk/common/estream.c Log: Fix for W32. Modified: trunk/common/estream.c =================================================================== --- trunk/common/estream.c 2010-08-26 08:47:42 UTC (rev 5405) +++ trunk/common/estream.c 2010-08-26 09:28:11 UTC (rev 5406) @@ -121,6 +121,8 @@ # define S_IROTH S_IRUSR # define S_IWGRP S_IWUSR # define S_IWOTH S_IWUSR +# define S_IXGRP S_IXUSR +# define S_IXOTH S_IXUSR #endif From cvs at cvs.gnupg.org Fri Aug 27 10:52:25 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 27 Aug 2010 10:52:25 +0200 Subject: [svn] gcry - r1445 - in trunk: . src Message-ID: Author: wk Date: 2010-08-27 10:52:24 +0200 (Fri, 27 Aug 2010) New Revision: 1445 Modified: trunk/autogen.sh trunk/src/ChangeLog trunk/src/g10lib.h trunk/src/global.c trunk/src/hwfeatures.c Log: Prepare support of ia32 AES instructions Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2010-08-19 13:57:38 UTC (rev 1444) +++ trunk/src/ChangeLog 2010-08-27 08:52:24 UTC (rev 1445) @@ -1,3 +1,9 @@ +2010-08-27 Werner Koch + + * g10lib.h (HWF_INTEL_AES): New. + * global.c (print_config): Print new flag. + * hwfeatures.c (detect_ia32_gnuc): Detect this flag. + 2010-08-16 Werner Koch * gcrypt.h.in [!WIN32]: Add INSERT_SYS_SELECT_H autoconf substitute. Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2010-08-19 13:57:38 UTC (rev 1444) +++ trunk/autogen.sh 2010-08-27 08:52:24 UTC (rev 1445) @@ -128,7 +128,7 @@ fi fi - ./configure --enable-maintainer-mode --prefix=${w32root} \ + $tsdir/configure --enable-maintainer-mode --prefix=${w32root} \ --host=${host} --build=${build} \ --with-gpg-error-prefix=${w32root} exit $? Modified: trunk/src/g10lib.h =================================================================== --- trunk/src/g10lib.h 2010-08-19 13:57:38 UTC (rev 1444) +++ trunk/src/g10lib.h 2010-08-27 08:52:24 UTC (rev 1445) @@ -148,6 +148,9 @@ #define HWF_PADLOCK_SHA 4 #define HWF_PADLOCK_MMUL 8 +#define HWF_INTEL_AES 256 + + unsigned int _gcry_get_hw_features (void); void _gcry_detect_hw_features (void); Modified: trunk/src/global.c =================================================================== --- trunk/src/global.c 2010-08-19 13:57:38 UTC (rev 1444) +++ trunk/src/global.c 2010-08-27 08:52:24 UTC (rev 1445) @@ -265,6 +265,7 @@ { HWF_PADLOCK_RNG, "padlock-rng" }, { HWF_PADLOCK_AES, "padlock-aes" }, { HWF_PADLOCK_SHA, "padlock-sha" }, + { HWF_INTEL_AES, "intel-aes" }, { 0, NULL} }; int i; Modified: trunk/src/hwfeatures.c =================================================================== --- trunk/src/hwfeatures.c 2010-08-19 13:57:38 UTC (rev 1444) +++ trunk/src/hwfeatures.c 2010-08-27 08:52:24 UTC (rev 1445) @@ -44,7 +44,6 @@ static void detect_ia32_gnuc (void) { -#ifdef ENABLE_PADLOCK_SUPPORT /* The code here is only useful for the PadLock engine thus we don't build it if that support has been disabled. */ int has_cpuid = 0; @@ -89,10 +88,12 @@ ); vendor_id[12] = 0; - /* Check whether this is a VIA CPU and what PadLock features we - have. */ - if (!strcmp (vendor_id, "CentaurHauls")) + if (0) + ; /* Just to make "else if" and ifdef macros look pretty. */ +#ifdef ENABLE_PADLOCK_SUPPORT + else if (!strcmp (vendor_id, "CentaurHauls")) { + /* This is a VIA CPU. Check what PadLock features we have. */ asm volatile ("pushl %%ebx\n\t" /* Save GOT register. */ "movl $0xC0000000, %%eax\n\t" /* Check for extended centaur */ @@ -140,11 +141,33 @@ ); } #endif /*ENABLE_PADLOCK_SUPPORT*/ + else if (!strcmp (vendor_id, "GenuineIntel")) + { + /* This is an Intel CPU. */ + asm volatile + ("pushl %%ebx\n\t" /* Save GOT register. */ + "movl $1, %%eax\n\t" /* Get CPU info and feature flags. */ + "cpuid\n" + "popl %%ebx\n\t" /* Restore GOT register. */ + "cmpl $0x02000000, %%ecx\n\t" /* Test bit 25. */ + "jnz .Lno_aes%=\n\t" /* No AES support. */ + "orl $256, %0\n" /* Set our HWF_INTEL_AES bit. */ + + ".Lno_aes%=:\n" + : "+r" (hw_features) + : + : "%eax", "%ecx", "%edx", "cc" + ); + } + else if (!strcmp (vendor_id, "AuthenticAMD")) + { + /* This is an AMD CPU. */ + + } } #endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */ - /* Detect the available hardware features. This function is called once right at startup and we assume that no other threads are running. */ From cvs at cvs.gnupg.org Tue Aug 31 10:42:40 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 31 Aug 2010 10:42:40 +0200 Subject: [svn] GnuPG - r5407 - in branches/STABLE-BRANCH-1-4: . cipher g10 Message-ID: Author: wk Date: 2010-08-31 10:42:38 +0200 (Tue, 31 Aug 2010) New Revision: 5407 Modified: branches/STABLE-BRANCH-1-4/NEWS branches/STABLE-BRANCH-1-4/README branches/STABLE-BRANCH-1-4/cipher/rndw32.c branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/mainproc.c Log: Minor fixes Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2010-08-26 09:28:11 UTC (rev 5406) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2010-08-31 08:42:38 UTC (rev 5407) @@ -1,3 +1,8 @@ +2010-08-31 Werner Koch + + * mainproc.c (print_pkenc_list): Print a STATUS_ERROR. Fixes + bug#1255. + 2010-07-24 Werner Koch * cardglue.c (agent_scd_pksign): Allow more hash algorithms when Modified: branches/STABLE-BRANCH-1-4/NEWS =================================================================== --- branches/STABLE-BRANCH-1-4/NEWS 2010-08-26 09:28:11 UTC (rev 5406) +++ branches/STABLE-BRANCH-1-4/NEWS 2010-08-31 08:42:38 UTC (rev 5407) @@ -2,6 +2,8 @@ ------------------------------------------------- * Bug fixes. + + * Ignore some GnuPG-2 options. Noteworthy changes in version 1.4.10 (2009-09-02) Modified: branches/STABLE-BRANCH-1-4/README =================================================================== --- branches/STABLE-BRANCH-1-4/README 2010-08-26 09:28:11 UTC (rev 5406) +++ branches/STABLE-BRANCH-1-4/README 2010-08-31 08:42:38 UTC (rev 5407) @@ -23,7 +23,7 @@ GnuPG is GNU's tool for secure communication and data storage. It can be used to encrypt data and to create digital signatures. It includes an advanced key management facility and is compliant - with the proposed OpenPGP Internet standard as described in RFC2440. + with the proposed OpenPGP Internet standard as described in RFC4880. GnuPG works best on GNU/Linux or *BSD systems. Most other Unices are also supported but are not as well tested as the Free Unices. Modified: branches/STABLE-BRANCH-1-4/cipher/rndw32.c =================================================================== --- branches/STABLE-BRANCH-1-4/cipher/rndw32.c 2010-08-26 09:28:11 UTC (rev 5406) +++ branches/STABLE-BRANCH-1-4/cipher/rndw32.c 2010-08-31 08:42:38 UTC (rev 5407) @@ -477,6 +477,10 @@ * worst-case estimate which is usually nowhere near the actual amount * required. For example it may report that 128K of memory is required, * but only return 64K of data */ +#warning How shall we disable get performacne data + if (0) + log_debug ("Warning: get performance data disabled\n"); + else { pPerfData = xmalloc (cbPerfData); for (;;) { dwSize = cbPerfData; Modified: branches/STABLE-BRANCH-1-4/g10/mainproc.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/mainproc.c 2010-08-26 09:28:11 UTC (rev 5406) +++ branches/STABLE-BRANCH-1-4/g10/mainproc.c 2010-08-31 08:42:38 UTC (rev 5407) @@ -501,8 +501,16 @@ } } else if (list->reason) + { log_info(_("public key decryption failed: %s\n"), g10_errstr(list->reason)); + if (is_status_enabled ()) + { + char buf[20+30]; + snprintf (buf, sizeof buf, "pkdecrypt_failed %d", list->reason); + write_status_text (STATUS_ERROR, buf); + } + } } } From cvs at cvs.gnupg.org Tue Aug 31 17:58:42 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 31 Aug 2010 17:58:42 +0200 Subject: [svn] GnuPG - r5408 - in trunk: . agent g10 Message-ID: Author: wk Date: 2010-08-31 17:58:39 +0200 (Tue, 31 Aug 2010) New Revision: 5408 Added: trunk/agent/cvt-openpgp.c trunk/agent/cvt-openpgp.h Modified: trunk/NEWS trunk/agent/ChangeLog trunk/agent/Makefile.am trunk/agent/agent.h trunk/agent/command.c trunk/agent/findkey.c trunk/agent/keyformat.txt trunk/agent/pksign.c trunk/agent/protect.c trunk/g10/ChangeLog trunk/g10/call-agent.c trunk/g10/call-agent.h trunk/g10/gpg.c trunk/g10/import.c trunk/g10/keydb.h trunk/g10/keyid.c trunk/g10/keyserver.c trunk/g10/main.h trunk/g10/misc.c trunk/g10/options.h trunk/g10/pkglue.c Log: Import OpenPGP keys into the agent. [The diff below has been truncated] Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/agent/ChangeLog 2010-08-31 15:58:39 UTC (rev 5408) @@ -1,3 +1,18 @@ +2010-08-31 Werner Koch + + * pksign.c (do_encode_dsa): Fix sign problem. + * findkey.c (agent_is_dsa_key): Adjust to actual usage. + +2010-08-30 Werner Koch + + * protect.c (s2k_hash_passphrase): New public function. + +2010-08-27 Werner Koch + + * command.c (cmd_import_key): Support OpenPGP keys. + * cvt-openpgp.h, cvt-openpgp.c: New. Some of the code is based on + code taken from g10/seckey-cert.c. + 2010-08-26 Werner Koch * command-ssh.c (open_control_file): Use estream to create the file. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/g10/ChangeLog 2010-08-31 15:58:39 UTC (rev 5408) @@ -1,3 +1,32 @@ +2010-08-30 Werner Koch + + * keyid.c (KEYID_STR_SIZE): New + (keystr): Use snprintf and new macro. + (keystr_with_sub): New. + (keystr_from_sk_with_sub): New. + (keystr_from_pk_with_sub): New. + +2010-08-27 Werner Koch + + * gpg.c (main): Change scope of CTRL to the entire function. + + * import.c (import_secret_one, import, import_keys_internal) + (import_keys, import_keys_stream): Add arg CTRL. + * call-agent.c (agent_keywrap_key): New. + (agent_import_key, inq_import_key_parms): New. + +2010-08-26 Werner Koch + + * misc.c (openpgp_pk_algo_name): New. + (openpgp_md_algo_name): New. + +2010-08-24 Werner Koch + + * options.h (IMPORT_SK2PK): Remove. + * import.c (parse_import_options): Turn convert-sk-to-pk into a + dummy option. + (sec_to_pub_keyblock): Use modern functions. + 2010-08-16 Werner Koch * gpg.c (list_config, gpgconf_list): Use es_printf. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/NEWS 2010-08-31 15:58:39 UTC (rev 5408) @@ -37,7 +37,11 @@ * Fixed output of "gpgconf --check-options". + * GPG does not anymore use secring.gpg but delegates all secret key + operations to gpg-agent. The import command moves secret keys to + the agent. + Noteworthy changes in version 2.0.13 (2009-09-04) ------------------------------------------------- Modified: trunk/agent/Makefile.am =================================================================== --- trunk/agent/Makefile.am 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/agent/Makefile.am 2010-08-31 15:58:39 UTC (rev 5408) @@ -46,6 +46,7 @@ protect.c \ trustlist.c \ divert-scd.c \ + cvt-openpgp.c cvt-openpgp.h \ call-scd.c \ learncard.c Modified: trunk/agent/agent.h =================================================================== --- trunk/agent/agent.h 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/agent/agent.h 2010-08-31 15:58:39 UTC (rev 5408) @@ -171,8 +171,8 @@ int with_qualitybar; /* Set if the quality bar should be displayed. */ int (*check_cb)(struct pin_entry_info_s *); /* CB used to check the PIN */ void *check_cb_arg; /* optional argument which might be of use in the CB */ - const char *cb_errtext; /* used by the cb to displaye a specific error */ - size_t max_length; /* allocated length of the buffer */ + const char *cb_errtext; /* used by the cb to display a specific error */ + size_t max_length; /* allocated length of the buffer */ char pin[1]; }; @@ -306,6 +306,11 @@ unsigned char const **shadow_info); gpg_error_t parse_shadow_info (const unsigned char *shadow_info, char **r_hexsn, char **r_idstr); +gpg_error_t s2k_hash_passphrase (const char *passphrase, int hashalgo, + int s2kmode, + const unsigned char *s2ksalt, + unsigned int s2kcount, + unsigned char *key, size_t keylen); /*-- trustlist.c --*/ Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/agent/command.c 2010-08-31 15:58:39 UTC (rev 5408) @@ -37,9 +37,9 @@ #include "agent.h" #include #include "i18n.h" +#include "cvt-openpgp.h" - /* Maximum allowed size of the inquired ciphertext. */ #define MAXLEN_CIPHERTEXT 4096 /* Maximum allowed size of the key parameters. */ @@ -357,6 +357,12 @@ const char *name = assuan_get_command_name (ctx); if (!name) name = "?"; + + /* Most code from common/ does not know the error source, thus + we fix this here. */ + if (gpg_err_source (err) == GPG_ERR_SOURCE_UNKNOWN) + err = gpg_err_make (GPG_ERR_SOURCE_DEFAULT, gpg_err_code (err)); + if (gpg_err_source (err) == GPG_ERR_SOURCE_DEFAULT) log_error ("command '%s' failed: %s\n", name, gpg_strerror (err)); @@ -566,8 +572,8 @@ static const char hlp_setkeydesc[] = "SETKEYDESC plus_percent_escaped_string\n" "\n" - "Set a description to be used for the next PKSIGN, PKDECRYPT or EXPORT_KEY\n" - "operation if this operation requires the entry of a passphrase. If\n" + "Set a description to be used for the next PKSIGN, PKDECRYPT, IMPORT_KEY\n" + "or EXPORT_KEY operation if this operation requires a passphrase. If\n" "this command is not used a default text will be used. Note, that\n" "this description implictly selects the label used for the entry\n" "box; if the string contains the string PIN (which in general will\n" @@ -575,8 +581,8 @@ "\"passphrase\" is used. The description string should not contain\n" "blanks unless they are percent or '+' escaped.\n" "\n" - "The description is only valid for the next PKSIGN, PKDECRYPT or\n" - "EXPORT_KEY operation."; + "The description is only valid for the next PKSIGN, PKDECRYPT,\n" + "IMPORT_KEY or EXPORT_KEY operation."; static gpg_error_t cmd_setkeydesc (assuan_context_t ctx, char *line) { @@ -1478,6 +1484,7 @@ unsigned char *finalkey = NULL; size_t finalkeylen; unsigned char grip[20]; + gcry_sexp_t openpgp_sexp = NULL; (void)line; @@ -1528,21 +1535,59 @@ err = keygrip_from_canon_sexp (key, realkeylen, grip); if (err) - goto leave; + { + /* This might be due to an unsupported S-expression format. + Check whether this is openpgp-private-key and trigger that + import code. */ + if (!gcry_sexp_sscan (&openpgp_sexp, NULL, key, realkeylen)) + { + const char *tag; + size_t taglen; + + tag = gcry_sexp_nth_data (openpgp_sexp, 0, &taglen); + if (tag && taglen == 19 && !memcmp (tag, "openpgp-private-key", 19)) + ; + else + { + gcry_sexp_release (openpgp_sexp); + openpgp_sexp = NULL; + } + } + if (!openpgp_sexp) + goto leave; /* Note that ERR is still set. */ + } - if (!agent_key_available (grip)) + + if (openpgp_sexp) { - err = gpg_error (GPG_ERR_EEXIST); - goto leave; + /* In most cases the key is encrypted and thus the conversion + function from the OpenPGP format to our internal format will + ask for a passphrase. That passphrase will be returned and + used to protect the key using the same code as for regular + key import. */ + + err = convert_openpgp (ctrl, openpgp_sexp, grip, + ctrl->server_local->keydesc, + &key, &passphrase); + if (err) + goto leave; + realkeylen = gcry_sexp_canon_len (key, keylen, NULL, &err); + if (!realkeylen) + goto leave; /* Invalid canonical encoded S-expression. */ } + else + { + if (!agent_key_available (grip)) + err = gpg_error (GPG_ERR_EEXIST); + else + err = agent_ask_new_passphrase + (ctrl, _("Please enter the passphrase to protect the " + "imported object within the GnuPG system."), + &passphrase); + if (err) + goto leave; + } - err = agent_ask_new_passphrase - (ctrl, _("Please enter the passphrase to protect the " - "imported object within the GnuPG system."), - &passphrase); - if (err) - goto leave; - if (passphrase) { err = agent_protect (key, passphrase, &finalkey, &finalkeylen); @@ -1553,11 +1598,14 @@ err = agent_write_private_key (grip, key, realkeylen, 0); leave: + gcry_sexp_release (openpgp_sexp); xfree (finalkey); xfree (passphrase); xfree (key); gcry_cipher_close (cipherhd); xfree (wrappedkey); + xfree (ctrl->server_local->keydesc); + ctrl->server_local->keydesc = NULL; return leave_cmd (ctx, err); } Added: trunk/agent/cvt-openpgp.c =================================================================== --- trunk/agent/cvt-openpgp.c (rev 0) +++ trunk/agent/cvt-openpgp.c 2010-08-31 15:58:39 UTC (rev 5408) @@ -0,0 +1,807 @@ +/* cvt-openpgp.c - Convert an OpenPGP key to our internal format. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2006, 2009, + * 2010 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 3 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, see . + */ + +#include +#include +#include +#include +#include + +#include "agent.h" +#include "i18n.h" +#include "cvt-openpgp.h" + + +/* Helper to pass data via the callback to do_unprotect. */ +struct try_do_unprotect_arg_s +{ + int is_v4; + int is_protected; + int pubkey_algo; + int protect_algo; + char *iv; + int ivlen; + int s2k_mode; + int s2k_algo; + byte *s2k_salt; + u32 s2k_count; + u16 desired_csum; + gcry_mpi_t *skey; + size_t skeysize; + int skeyidx; + gcry_sexp_t *r_key; +}; + + + +/* Compute the keygrip from the public key and store it at GRIP. */ +static gpg_error_t +get_keygrip (int pubkey_algo, gcry_mpi_t *pkey, unsigned char *grip) +{ + gpg_error_t err; + gcry_sexp_t s_pkey = NULL; + + switch (pubkey_algo) + { + case GCRY_PK_DSA: + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))", + pkey[0], pkey[1], pkey[2], pkey[3]); + break; + + case GCRY_PK_ELG: + case GCRY_PK_ELG_E: + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(elg(p%m)(g%m)(y%m)))", + pkey[0], pkey[1], pkey[2]); + break; + + case GCRY_PK_RSA: + case GCRY_PK_RSA_E: + case GCRY_PK_RSA_S: + err = gcry_sexp_build (&s_pkey, NULL, + "(public-key(rsa(n%m)(e%m)))", pkey[0], pkey[1]); + break; + + default: + err = gpg_error (GPG_ERR_PUBKEY_ALGO); + break; + } + + if (!err && !gcry_pk_get_keygrip (s_pkey, grip)) + err = gpg_error (GPG_ERR_INTERNAL); + + gcry_sexp_release (s_pkey); + return err; +} + + +/* Convert a secret key given as algorithm id and an array of key + parameters into our s-expression based format. */ +static gpg_error_t +convert_secret_key (gcry_sexp_t *r_key, int pubkey_algo, gcry_mpi_t *skey) +{ + gpg_error_t err; + gcry_sexp_t s_skey = NULL; + + *r_key = NULL; + + switch (pubkey_algo) + { + case GCRY_PK_DSA: + err = gcry_sexp_build (&s_skey, NULL, + "(private-key(dsa(p%m)(q%m)(g%m)(y%m)(x%m)))", + skey[0], skey[1], skey[2], skey[3], skey[4]); + break; + + case GCRY_PK_ELG: + case GCRY_PK_ELG_E: + err = gcry_sexp_build (&s_skey, NULL, + "(private-key(elg(p%m)(g%m)(y%m)(x%m)))", + skey[0], skey[1], skey[2], skey[3]); + break; + + + case GCRY_PK_RSA: + case GCRY_PK_RSA_E: + case GCRY_PK_RSA_S: + err = gcry_sexp_build (&s_skey, NULL, + "(private-key(rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))", + skey[0], skey[1], skey[2], skey[3], skey[4], + skey[5]); + + default: + err = gpg_error (GPG_ERR_PUBKEY_ALGO); + break; + } + + if (!err) + *r_key = s_skey; + return err; +} + + + +/* Hash the passphrase and set the key. */ +static gpg_error_t +hash_passphrase_and_set_key (const char *passphrase, + gcry_cipher_hd_t hd, int protect_algo, + int s2k_mode, int s2k_algo, + byte *s2k_salt, u32 s2k_count) +{ + gpg_error_t err; + unsigned char *key; + size_t keylen; + + keylen = gcry_cipher_get_algo_keylen (protect_algo); + if (!keylen) + return gpg_error (GPG_ERR_INTERNAL); + + key = xtrymalloc_secure (keylen); + if (!key) + return gpg_error_from_syserror (); + + err = s2k_hash_passphrase (passphrase, + s2k_algo, s2k_mode, s2k_salt, s2k_count, + key, keylen); + if (!err) + err = gcry_cipher_setkey (hd, key, keylen); + + xfree (key); + return err; +} + + +static u16 +checksum (const unsigned char *p, unsigned int n) +{ + u16 a; + + for (a=0; n; n-- ) + a += *p++; + return a; +} + + +/* Note that this function modified SKEY. SKEYSIZE is the allocated + size of the array including the NULL item; this is used for a + bounds check. On success a converted key is stored at R_KEY. */ +static int +do_unprotect (const char *passphrase, + int pkt_version, int pubkey_algo, int is_protected, + gcry_mpi_t *skey, size_t skeysize, + int protect_algo, void *protect_iv, size_t protect_ivlen, + int s2k_mode, int s2k_algo, byte *s2k_salt, u32 s2k_count, + u16 desired_csum, gcry_sexp_t *r_key) +{ + gpg_error_t err; + size_t npkey, nskey, skeylen; + gcry_cipher_hd_t cipher_hd = NULL; + u16 actual_csum; + size_t nbytes; + int i; + gcry_mpi_t tmpmpi; + + *r_key = NULL; + + /* Count the actual number of MPIs is in the array and set the + remainder to NULL for easier processing later on. */ + for (skeylen = 0; skey[skeylen]; skeylen++) + ; + for (i=skeylen; i < skeysize; i++) + skey[i] = NULL; + + /* Check some args. */ + if (s2k_mode == 1001) + { + /* Stub key. */ + log_info (_("secret key parts are not available\n")); + return gpg_error (GPG_ERR_UNUSABLE_SECKEY); + } + + if (gcry_pk_test_algo (pubkey_algo)) + { + /* The algorithm numbers are Libgcrypt numbers but fortunately + the OpenPGP algorithm numbers map one-to-one to the Libgcrypt + numbers. */ + log_info (_("public key algorithm %d (%s) is not supported\n"), + pubkey_algo, gcry_pk_algo_name (pubkey_algo)); + return gpg_error (GPG_ERR_PUBKEY_ALGO); + } + + /* Get properties of the public key algorithm and do some + consistency checks. Note that we need at least NPKEY+1 elements + in the SKEY array. */ + if ( (err = gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, + NULL, &npkey)) + || (err = gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, + NULL, &nskey))) + return err; + if (!npkey || npkey >= nskey) + return gpg_error (GPG_ERR_INTERNAL); + if (skeylen <= npkey) + return gpg_error (GPG_ERR_MISSING_VALUE); + if (nskey+1 >= skeysize) + return gpg_error (GPG_ERR_BUFFER_TOO_SHORT); + + /* Check whether SKEY is at all protected. If it is not protected + merely verify the checksum. */ + if (!is_protected) + { + unsigned char *buffer; + + actual_csum = 0; + for (i=npkey; i < nskey; i++) + { + if (!skey[i] || gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE)) + return gpg_error (GPG_ERR_BAD_SECKEY); + + err = gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, skey[i]); + if (!err) + { + buffer = (gcry_is_secure (skey[i])? + xtrymalloc_secure (nbytes) : xtrymalloc (nbytes)); + if (!buffer) + return gpg_error_from_syserror (); + err = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, + NULL, skey[i]); + if (!err) + actual_csum += checksum (buffer, nbytes); + xfree (buffer); + } + if (err) + return err; + } + + if (actual_csum != desired_csum) + return gpg_error (GPG_ERR_CHECKSUM); + return 0; + } + + + if (gcry_cipher_test_algo (protect_algo)) + { + /* The algorithm numbers are Libgcrypt numbers but fortunately + the OpenPGP algorithm numbers map one-to-one to the Libgcrypt + numbers. */ + log_info (_("protection algorithm %d (%s) is not supported\n"), + protect_algo, gcry_cipher_algo_name (protect_algo)); + return gpg_error (GPG_ERR_CIPHER_ALGO); + } + + if (gcry_md_test_algo (s2k_algo)) + { + log_info (_("protection hash algorithm %d (%s) is not supported\n"), + s2k_algo, gcry_md_algo_name (s2k_algo)); + return gpg_error (GPG_ERR_DIGEST_ALGO); + } + + err = gcry_cipher_open (&cipher_hd, protect_algo, + GCRY_CIPHER_MODE_CFB, + (GCRY_CIPHER_SECURE + | (protect_algo >= 100 ? + 0 : GCRY_CIPHER_ENABLE_SYNC))); + if (err) + { + log_error ("failed to open cipher_algo %d: %s\n", + protect_algo, gpg_strerror (err)); + return err; + } + + err = hash_passphrase_and_set_key (passphrase, cipher_hd, protect_algo, + s2k_mode, s2k_algo, s2k_salt, s2k_count); + if (err) + { + gcry_cipher_close (cipher_hd); + return err; + } + + gcry_cipher_setiv (cipher_hd, protect_iv, protect_ivlen); + + actual_csum = 0; + if (pkt_version >= 4) + { + int ndata; + unsigned int ndatabits; + unsigned char *p, *data; + u16 csum_pgp7 = 0; + + if (!gcry_mpi_get_flag (skey[npkey], GCRYMPI_FLAG_OPAQUE )) + { + gcry_cipher_close (cipher_hd); + return gpg_error (GPG_ERR_BAD_SECKEY); + } + p = gcry_mpi_get_opaque (skey[npkey], &ndatabits); + ndata = (ndatabits+7)/8; + + if (ndata > 1) + csum_pgp7 = p[ndata-2] << 8 | p[ndata-1]; + data = xtrymalloc_secure (ndata); + if (!data) + { + err = gpg_error_from_syserror (); + gcry_cipher_close (cipher_hd); + return err; + } + gcry_cipher_decrypt (cipher_hd, data, ndata, p, ndata); + + p = data; + if (is_protected == 2) + { + /* This is the new SHA1 checksum method to detect tampering + with the key as used by the Klima/Rosa attack. */ + desired_csum = 0; + actual_csum = 1; /* Default to bad checksum. */ + + if (ndata < 20) + log_error ("not enough bytes for SHA-1 checksum\n"); + else + { + gcry_md_hd_t h; + + if (gcry_md_open (&h, GCRY_MD_SHA1, 1)) + BUG(); /* Algo not available. */ + gcry_md_write (h, data, ndata - 20); + gcry_md_final (h); + if (!memcmp (gcry_md_read (h, GCRY_MD_SHA1), data+ndata-20, 20)) + actual_csum = 0; /* Digest does match. */ + gcry_md_close (h); + } + } + else + { + /* Old 16 bit checksum method. */ + if (ndata < 2) + { + log_error ("not enough bytes for checksum\n"); + desired_csum = 0; + actual_csum = 1; /* Mark checksum bad. */ + } + else + { + desired_csum = (data[ndata-2] << 8 | data[ndata-1]); + actual_csum = checksum (data, ndata-2); + if (desired_csum != actual_csum) + { + /* This is a PGP 7.0.0 workaround */ + desired_csum = csum_pgp7; /* Take the encrypted one. */ + } + } + } + + /* Better check it here. Otherwise the gcry_mpi_scan would fail + because the length may have an arbitrary value. */ + if (desired_csum == actual_csum) + { + for (i=npkey; i < nskey; i++ ) + { + if (gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, p, ndata, &nbytes)) + { + /* Checksum was okay, but not correctly decrypted. */ + desired_csum = 0; + actual_csum = 1; /* Mark checksum bad. */ + break; + } + gcry_mpi_release (skey[i]); + skey[i] = tmpmpi; + ndata -= nbytes; + p += nbytes; + } + skey[i] = NULL; + skeylen = i; + assert (skeylen <= skeysize); + + /* Note: at this point NDATA should be 2 for a simple + checksum or 20 for the sha1 digest. */ + } + xfree(data); + } + else /* Packet version <= 3. */ + { + unsigned char *buffer; + + for (i = npkey; i < nskey; i++) + { + unsigned char *p; + size_t ndata; + unsigned int ndatabits; + + if (!skey[i] || !gcry_mpi_get_flag (skey[i], GCRYMPI_FLAG_OPAQUE)) + { + gcry_cipher_close (cipher_hd); + return gpg_error (GPG_ERR_BAD_SECKEY); + } + p = gcry_mpi_get_opaque (skey[i], &ndatabits); + ndata = (ndatabits+7)/8; + + if (!(ndata >= 2) || !(ndata == ((p[0] << 8 | p[1]) + 7)/8 + 2)) + { + gcry_cipher_close (cipher_hd); + return gpg_error (GPG_ERR_BAD_SECKEY); + } + + buffer = xtrymalloc_secure (ndata); + if (!buffer) + { + err = gpg_error_from_syserror (); + gcry_cipher_close (cipher_hd); + return err; + } + + gcry_cipher_sync (cipher_hd); + buffer[0] = p[0]; + buffer[1] = p[1]; + gcry_cipher_decrypt (cipher_hd, buffer+2, ndata-2, p+2, ndata-2); + actual_csum += checksum (buffer, ndata); + err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_PGP, buffer, ndata, &ndata); + xfree (buffer); + if (err) + { + /* Checksum was okay, but not correctly decrypted. */ + desired_csum = 0; + actual_csum = 1; /* Mark checksum bad. */ + break; + } + gcry_mpi_release (skey[i]); + skey[i] = tmpmpi; + } + } + gcry_cipher_close (cipher_hd); + + /* Now let's see whether we have used the correct passphrase. */ + if (actual_csum != desired_csum) + return gpg_error (GPG_ERR_BAD_PASSPHRASE); + + if (nskey != skeylen) + err = gpg_error (GPG_ERR_BAD_SECKEY); + else + err = convert_secret_key (r_key, pubkey_algo, skey); + if (err) + return err; + + /* The checksum may fail, thus we also check the key itself. */ + err = gcry_pk_testkey (*r_key); + if (err) + { + gcry_sexp_release (*r_key); + *r_key = NULL; + return gpg_error (GPG_ERR_BAD_PASSPHRASE); + } + + return 0; +} + + +/* Callback function to try the unprotection from the passpharse query + code. */ +static int +try_do_unprotect_cb (struct pin_entry_info_s *pi) +{ + gpg_error_t err; + struct try_do_unprotect_arg_s *arg = pi->check_cb_arg; + + err = do_unprotect (pi->pin, arg->is_v4? 4:3, + arg->pubkey_algo, arg->is_protected, + arg->skey, arg->skeysize, + arg->protect_algo, arg->iv, arg->ivlen, + arg->s2k_mode, arg->s2k_algo, + arg->s2k_salt, arg->s2k_count, + arg->desired_csum, arg->r_key); + /* SKEY may be modified now, thus we need to re-compute SKEYIDX. */ + for (arg->skeyidx = 0; (arg->skeyidx < arg->skeysize + && arg->skey[arg->skeyidx]); arg->skeyidx++) + ; + return err; +} + + +/* Convert an OpenPGP transfer key into our internal format. Before + asking for a passphrase we check whether the key already exists in + our key storage. S_PGP is the OpenPGP key in transfer format. On + success R_KEY will receive a canonical encoded S-expression with + the unprotected key in our internal format; the caller needs to + release that memory. The passphrase used to decrypt the OpenPGP + key will be returned at R_PASSPHRASE; the caller must release this + passphrase. The keygrip will be stored at the 20 byte buffer + pointed to by GRIP. On error NULL is stored at all return + arguments. */ +gpg_error_t +convert_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp, + unsigned char *grip, const char *prompt, + unsigned char **r_key, char **r_passphrase) +{ + gpg_error_t err; + gcry_sexp_t top_list; + gcry_sexp_t list = NULL; + const char *value; + size_t valuelen; + char *string; + int idx; + int is_v4, is_protected; + int pubkey_algo; + int protect_algo = 0; + char iv[16]; + int ivlen = 0; + int s2k_mode = 0; + int s2k_algo = 0; + byte s2k_salt[8]; + u32 s2k_count = 0; + size_t npkey, nskey; + gcry_mpi_t skey[10]; /* We support up to 9 parameters. */ + u16 desired_csum; + int skeyidx = 0; + gcry_sexp_t s_skey; + struct pin_entry_info_s *pi; + struct try_do_unprotect_arg_s pi_arg; + + *r_key = NULL; + *r_passphrase = NULL; + + top_list = gcry_sexp_find_token (s_pgp, "openpgp-private-key", 0); + if (!top_list) + goto bad_seckey; + + list = gcry_sexp_find_token (top_list, "version", 0); + if (!list) + goto bad_seckey; + value = gcry_sexp_nth_data (list, 1, &valuelen); + if (!value || valuelen != 1 || !(value[0] == '3' || value[0] == '4')) + goto bad_seckey; + is_v4 = (value[0] == '4'); + + gcry_sexp_release (list); + list = gcry_sexp_find_token (top_list, "protection", 0); + if (!list) + goto bad_seckey; + value = gcry_sexp_nth_data (list, 1, &valuelen); + if (!value) + goto bad_seckey; + if (valuelen == 4 && !memcmp (value, "sha1", 4)) + is_protected = 2; + else if (valuelen == 3 && !memcmp (value, "sum", 3)) + is_protected = 1; + else if (valuelen == 4 && !memcmp (value, "none", 4)) + is_protected = 0; + else + goto bad_seckey; + if (is_protected) + { + string = gcry_sexp_nth_string (list, 2); + if (!string) + goto bad_seckey; + protect_algo = gcry_cipher_map_name (string); + if (!protect_algo && !!strcmp (string, "IDEA")) + protect_algo = GCRY_CIPHER_IDEA; + xfree (string); + + value = gcry_sexp_nth_data (list, 3, &valuelen); + if (!value || !valuelen || valuelen > sizeof iv) + goto bad_seckey; + memcpy (iv, value, valuelen); + ivlen = valuelen; + + string = gcry_sexp_nth_string (list, 4); + if (!string) + goto bad_seckey; + s2k_mode = strtol (string, NULL, 10); + xfree (string); + + string = gcry_sexp_nth_string (list, 5); + if (!string) + goto bad_seckey; + s2k_algo = gcry_md_map_name (string); + xfree (string); + + value = gcry_sexp_nth_data (list, 6, &valuelen); + if (!value || !valuelen || valuelen > sizeof s2k_salt) + goto bad_seckey; + memcpy (s2k_salt, value, valuelen); + + string = gcry_sexp_nth_string (list, 7); + if (!string) + goto bad_seckey; + s2k_count = strtoul (string, NULL, 10); + xfree (string); + } + + gcry_sexp_release (list); + list = gcry_sexp_find_token (top_list, "algo", 0); + if (!list) + goto bad_seckey; + string = gcry_sexp_nth_string (list, 1); + if (!string) + goto bad_seckey; + pubkey_algo = gcry_pk_map_name (string); + xfree (string); + + if (gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &npkey) + || gcry_pk_algo_info (pubkey_algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &nskey) + || !npkey || npkey >= nskey) + goto bad_seckey; + + gcry_sexp_release (list); + list = gcry_sexp_find_token (top_list, "skey", 0); + if (!list) + goto bad_seckey; + for (idx=0;;) + { + int is_enc; + + value = gcry_sexp_nth_data (list, ++idx, &valuelen); + if (!value && skeyidx >= npkey) + break; /* Ready. */ + + /* Check for too many parameters. Note that depending on the + protection mode and version number we may see less than NSKEY + (but at least NPKEY+1) parameters. */ + if (idx >= 2*nskey) + goto bad_seckey; + if (skeyidx >= DIM (skey)-1) + goto bad_seckey; + + if (!value || valuelen != 1 || !(value[0] == '_' || value[0] == 'e')) + goto bad_seckey; + is_enc = (value[0] == 'e'); + value = gcry_sexp_nth_data (list, ++idx, &valuelen); + if (!value || !valuelen) + goto bad_seckey; + if (is_enc) + { + void *p = xtrymalloc (valuelen); + if (!p) + goto outofmem; + memcpy (p, value, valuelen); + skey[skeyidx] = gcry_mpi_set_opaque (NULL, p, valuelen*8); + if (!skey[skeyidx]) + goto outofmem; + } + else + { + if (gcry_mpi_scan (skey + skeyidx, GCRYMPI_FMT_STD, + value, valuelen, NULL)) + goto bad_seckey; + } + skeyidx++; + } + skey[skeyidx++] = NULL; + + gcry_sexp_release (list); + list = gcry_sexp_find_token (top_list, "csum", 0); + if (list) + { + string = gcry_sexp_nth_string (list, 1); + if (!string) + goto bad_seckey; + desired_csum = strtoul (string, NULL, 10); + xfree (string); + } + else + desired_csum = 0; + + + gcry_sexp_release (list); list = NULL; + gcry_sexp_release (top_list); top_list = NULL; + + /* log_debug ("XXX is_v4=%d\n", is_v4); */ + /* log_debug ("XXX pubkey_algo=%d\n", pubkey_algo); */ + /* log_debug ("XXX is_protected=%d\n", is_protected); */ + /* log_debug ("XXX protect_algo=%d\n", protect_algo); */ + /* log_printhex ("XXX iv", iv, ivlen); */ + /* log_debug ("XXX ivlen=%d\n", ivlen); */ + /* log_debug ("XXX s2k_mode=%d\n", s2k_mode); */ + /* log_debug ("XXX s2k_algo=%d\n", s2k_algo); */ + /* log_printhex ("XXX s2k_salt", s2k_salt, sizeof s2k_salt); */ + /* log_debug ("XXX s2k_count=%lu\n", (unsigned long)s2k_count); */ + /* for (idx=0; skey[idx]; idx++) */ + /* { */ + /* int is_enc = gcry_mpi_get_flag (skey[idx], GCRYMPI_FLAG_OPAQUE); */ + /* log_info ("XXX skey[%d]%s:", idx, is_enc? " (enc)":""); */ + /* if (is_enc) */ + /* { */ + /* void *p; */ + /* unsigned int nbits; */ + /* p = gcry_mpi_get_opaque (skey[idx], &nbits); */ + /* log_printhex (NULL, p, (nbits+7)/8); */ + /* } */ + /* else */ + /* gcry_mpi_dump (skey[idx]); */ + /* log_printf ("\n"); */ + /* } */ + + err = get_keygrip (pubkey_algo, skey, grip); + if (err) + goto leave; + + if (!agent_key_available (grip)) + { + err = gpg_error (GPG_ERR_EEXIST); + goto leave; + } + + pi = xtrycalloc_secure (1, sizeof (*pi) + 100); + if (!pi) + return gpg_error_from_syserror (); + pi->max_length = 100; + pi->min_digits = 0; /* We want a real passphrase. */ + pi->max_digits = 16; + pi->max_tries = 3; + pi->check_cb = try_do_unprotect_cb; + pi->check_cb_arg = &pi_arg; + pi_arg.is_v4 = is_v4; + pi_arg.is_protected = is_protected; + pi_arg.pubkey_algo = pubkey_algo; + pi_arg.protect_algo = protect_algo; + pi_arg.iv = iv; + pi_arg.ivlen = ivlen; + pi_arg.s2k_mode = s2k_mode; + pi_arg.s2k_algo = s2k_algo; + pi_arg.s2k_salt = s2k_salt; + pi_arg.s2k_count = s2k_count; + pi_arg.desired_csum = desired_csum; + pi_arg.skey = skey; + pi_arg.skeysize = DIM (skey); + pi_arg.skeyidx = skeyidx; + pi_arg.r_key = &s_skey; + err = agent_askpin (ctrl, prompt, NULL, NULL, pi); + skeyidx = pi_arg.skeyidx; + if (!err) + { + *r_passphrase = xtrystrdup (pi->pin); + if (!*r_passphrase) + err = gpg_error_from_syserror (); + } + xfree (pi); + if (err) + goto leave; + + /* Save some memory and get rid of the SKEY array now. */ + for (idx=0; idx < skeyidx; idx++) + gcry_mpi_release (skey[idx]); + skeyidx = 0; + + /* Note that the padding is not required - we use it only because + that function allows us to created the result in secure memory. */ + err = make_canon_sexp_pad (s_skey, 1, r_key, NULL); + gcry_sexp_release (s_skey); + + leave: + gcry_sexp_release (list); + gcry_sexp_release (top_list); + for (idx=0; idx < skeyidx; idx++) + gcry_mpi_release (skey[idx]); + if (err) + { + xfree (*r_passphrase); + *r_passphrase = NULL; + } + return err; + + bad_seckey: + err = gpg_error (GPG_ERR_BAD_SECKEY); + goto leave; + + outofmem: + err = gpg_error (GPG_ERR_ENOMEM); + goto leave; + +} + + + Added: trunk/agent/cvt-openpgp.h =================================================================== --- trunk/agent/cvt-openpgp.h (rev 0) +++ trunk/agent/cvt-openpgp.h 2010-08-31 15:58:39 UTC (rev 5408) @@ -0,0 +1,27 @@ +/* cvt-openpgp.h - Convert an OpenPGP key to our internal format. + * Copyright (C) 2010 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 3 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, see . + */ +#ifndef GNUPG_AGENT_CVT_OPENPGP_H +#define GNUPG_AGENT_CVT_OPENPGP_H + +gpg_error_t convert_openpgp (ctrl_t ctrl, gcry_sexp_t s_pgp, + unsigned char *grip, const char *prompt, + unsigned char **r_key, char **r_passphrase); + + +#endif /*GNUPG_AGENT_CVT_OPENPGP_H*/ Modified: trunk/agent/findkey.c =================================================================== --- trunk/agent/findkey.c 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/agent/findkey.c 2010-08-31 15:58:39 UTC (rev 5408) @@ -702,7 +702,8 @@ } -/* Return true if S_KEY is a DSA style key. */ +/* Return the public key algorithm number if S_KEY is a DSA style key. + If it is not a DSA style key, return 0. */ int agent_is_dsa_key (gcry_sexp_t s_key) { @@ -714,7 +715,12 @@ if (key_parms_from_sexp (s_key, NULL, algoname, sizeof algoname, NULL, 0)) return 0; /* Error - assume it is not an DSA key. */ - return (!strcmp (algoname, "dsa") || !strcmp (algoname, "ecdsa")); + if (!strcmp (algoname, "dsa")) + return GCRY_PK_DSA; + else if (!strcmp (algoname, "ecdsa")) + return GCRY_PK_ECDSA; + else + return 0; } Modified: trunk/agent/keyformat.txt =================================================================== --- trunk/agent/keyformat.txt 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/agent/keyformat.txt 2010-08-31 15:58:39 UTC (rev 5408) @@ -159,10 +159,37 @@ More items may be added to the list. +OpenPGP Private Key Transfer Format +=================================== +This format is used to transfer keys between gpg and gpg-agent. +(openpgp-private-key + (version V) + (protection PROTTYPE PROTALGO IV S2KMODE S2KHASH S2KSALT S2KCOUNT) + (algo PUBKEYALGO) + (skey CSUM c P1 c P2 c P3 ... e PN)) +* V is the packet version number (3 or 4). +* PUBKEYALGO is a Libgcrypt algo name +* CSUM is the 16 bit checksum as defined by OpenPGP. +* P1 .. PN are the parameters; the public parameters are never encrypted + the secrect key parameters are encrypted if the "protection" list is + given. To make this more explicit each parameter is preceded by a + flag "_" for cleartext or "e" for encrypted text. +* If PROTTYPE is "sha1" the new style SHA1 checksum is used if it is "sum" + the old 16 bit checksum is used and if it is "none" no protection at + all is used. +* PROTALGO is a Libgcrypt style cipher algorithm name +* IV is the initialization verctor. +* S2KMODE is the value from RFC-4880. +* S2KHASH is a a libgcrypt style hash algorithm identifier. +* S2KSALT is the 8 byte salt +* S2KCOUNT is the count value from RFC-4880. + + + Notes: ====== [1] I usually use the terms private and secret key exchangeable but prefer the Modified: trunk/agent/pksign.c =================================================================== --- trunk/agent/pksign.c 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/agent/pksign.c 2010-08-31 15:58:39 UTC (rev 5408) @@ -164,10 +164,22 @@ if (mdlen > qbits/8) mdlen = qbits/8; - /* Create the S-expression. */ - err = gcry_sexp_build (&hash, NULL, - "(data (flags raw) (value %b))", - (int)mdlen, md); + /* Create the S-expression. We need to convert to an MPI first + because we want an unsigned integer. Using %b directly is not + possible because libgcrypt assumes an mpi and uses + GCRYMPI_FMT_STD for parsing and thus possible yielding a negative + value. */ + { + gcry_mpi_t mpi; + + err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_USG, md, mdlen, NULL); + if (!err) + { + err = gcry_sexp_build (&hash, NULL, + "(data (flags raw) (value %m))", mpi); + gcry_mpi_release (mpi); + } + } if (!err) *r_hash = hash; return err; @@ -304,8 +316,10 @@ if (DBG_CRYPTO) { - log_debug ("skey: "); + log_debug ("skey:\n"); gcry_sexp_dump (s_skey); + log_debug ("hash:\n"); + gcry_sexp_dump (s_hash); } /* sign */ @@ -319,7 +333,7 @@ if (DBG_CRYPTO) { - log_debug ("result: "); + log_debug ("result:\n"); gcry_sexp_dump (s_sig); } } Modified: trunk/agent/protect.c =================================================================== --- trunk/agent/protect.c 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/agent/protect.c 2010-08-31 15:58:39 UTC (rev 5408) @@ -73,6 +73,8 @@ const unsigned char *s2ksalt, unsigned long s2kcount, unsigned char *key, size_t keylen); + + /* Get the process time and store it in DATA. */ static void calibrate_get_time (struct calibrate_time_s *data) @@ -1076,6 +1078,19 @@ } +gpg_error_t +s2k_hash_passphrase (const char *passphrase, int hashalgo, + int s2kmode, + const unsigned char *s2ksalt, + unsigned int s2kcount, + unsigned char *key, size_t keylen) +{ + return hash_passphrase (passphrase, hashalgo, s2kmode, s2ksalt, + (16ul + (s2kcount & 15)) << ((s2kcount >> 4) + 6), + key, keylen); +} + + /* Create an canonical encoded S-expression with the shadow info from Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/g10/call-agent.c 2010-08-31 15:58:39 UTC (rev 5408) @@ -77,6 +77,13 @@ const char *keyparms; }; +struct import_key_parm_s +{ + ctrl_t ctrl; + assuan_context_t ctx; + const void *key; + size_t keylen; +}; static gpg_error_t learn_status_cb (void *opaque, const char *line); @@ -1706,3 +1713,97 @@ *r_buf = buf; return 0; } + + + +/* Retrieve a key encryption key from the agent. With FOREXPORT true + the key shall be used for export, with false for import. On success + the new key is stored at R_KEY and its length at R_KEKLEN. */ +gpg_error_t +agent_keywrap_key (ctrl_t ctrl, int forexport, void **r_kek, size_t *r_keklen) +{ + gpg_error_t err; + membuf_t data; + size_t len; + unsigned char *buf; + char line[ASSUAN_LINELENGTH]; + + *r_kek = NULL; + err = start_agent (ctrl, 0); + if (err) + return err; + + snprintf (line, DIM(line)-1, "KEYWRAP_KEY %s", + forexport? "--export":"--import"); + + init_membuf_secure (&data, 64); + err = assuan_transact (agent_ctx, line, + membuf_data_cb, &data, + default_inq_cb, ctrl, NULL, NULL); + if (err) + { + xfree (get_membuf (&data, &len)); + return err; + } + buf = get_membuf (&data, &len); + if (!buf) + return gpg_error_from_syserror (); + *r_kek = buf; + *r_keklen = len; + return 0; +} + + + +/* Handle the inquiry for an IMPORT_KEY command. */ +static gpg_error_t +inq_import_key_parms (void *opaque, const char *line) +{ + struct import_key_parm_s *parm = opaque; + gpg_error_t err; + + if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7])) + { + err = assuan_send_data (parm->ctx, parm->key, parm->keylen); + } + else + err = default_inq_cb (parm->ctrl, line); + + return err; +} + + +/* Call the agent to import a key into the agent. */ +gpg_error_t +agent_import_key (ctrl_t ctrl, const char *desc, const void *key, size_t keylen) +{ + gpg_error_t err; + struct import_key_parm_s parm; + + err = start_agent (ctrl, 0); + if (err) + return err; + + if (desc) + { + char line[ASSUAN_LINELENGTH]; + + snprintf (line, DIM(line)-1, "SETKEYDESC %s", desc); + line[DIM(line)-1] = 0; + err = assuan_transact (agent_ctx, line, + NULL, NULL, NULL, NULL, NULL, NULL); + if (err) + return err; + } + + parm.ctrl = ctrl; + parm.ctx = agent_ctx; + parm.key = key; + parm.keylen = keylen; + + err = assuan_transact (agent_ctx, "IMPORT_KEY", + NULL, NULL, inq_import_key_parms, &parm, NULL, NULL); + return err; +} + + Modified: trunk/g10/call-agent.h =================================================================== --- trunk/g10/call-agent.h 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/g10/call-agent.h 2010-08-31 15:58:39 UTC (rev 5408) @@ -163,6 +163,14 @@ gcry_sexp_t s_ciphertext, unsigned char **r_buf, size_t *r_buflen); +/* Retrieve a key encryption key. */ +gpg_error_t agent_keywrap_key (ctrl_t ctrl, int forexport, + void **r_kek, size_t *r_keklen); +/* Send a key to the agent. */ +gpg_error_t agent_import_key (ctrl_t ctrl, const char *desc, + const void *key, size_t keylen); + + #endif /*GNUPG_G10_CALL_AGENT_H*/ Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/g10/gpg.c 2010-08-31 15:58:39 UTC (rev 5408) @@ -1925,6 +1925,7 @@ int any_explicit_recipient = 0; int require_secmem=0,got_secmem=0; struct assuan_malloc_hooks malloc_hooks; + ctrl_t ctrl; #ifdef __riscos__ opt.lock_once = 1; @@ -1984,23 +1985,24 @@ opt.pgp2_workarounds = 1; opt.escape_from = 1; opt.flags.require_cross_cert = 1; - opt.import_options=IMPORT_SK2PK; - opt.export_options=EXPORT_ATTRIBUTES; - opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG; - opt.keyserver_options.export_options=EXPORT_ATTRIBUTES; - opt.keyserver_options.options= - KEYSERVER_HONOR_KEYSERVER_URL|KEYSERVER_HONOR_PKA_RECORD; - opt.verify_options= - VERIFY_SHOW_POLICY_URLS|VERIFY_SHOW_STD_NOTATIONS|VERIFY_SHOW_KEYSERVER_URLS; - opt.trust_model=TM_AUTO; - opt.mangle_dos_filenames=0; - opt.min_cert_level=2; - set_screen_dimensions(); - opt.keyid_format=KF_SHORT; - opt.def_sig_expire="0"; - opt.def_cert_expire="0"; - set_homedir ( default_homedir () ); - opt.passphrase_repeat=1; + opt.import_options = 0; + opt.export_options = EXPORT_ATTRIBUTES; + opt.keyserver_options.import_options = IMPORT_REPAIR_PKS_SUBKEY_BUG; + opt.keyserver_options.export_options = EXPORT_ATTRIBUTES; + opt.keyserver_options.options = (KEYSERVER_HONOR_KEYSERVER_URL + | KEYSERVER_HONOR_PKA_RECORD ); + opt.verify_options = (VERIFY_SHOW_POLICY_URLS + | VERIFY_SHOW_STD_NOTATIONS + | VERIFY_SHOW_KEYSERVER_URLS); + opt.trust_model = TM_AUTO; + opt.mangle_dos_filenames = 0; + opt.min_cert_level = 2; + set_screen_dimensions (); + opt.keyid_format = KF_SHORT; + opt.def_sig_expire = "0"; + opt.def_cert_expire = "0"; + set_homedir (default_homedir ()); + opt.passphrase_repeat = 1; /* Check whether we have a config file on the command line. */ orig_argc = argc; @@ -3403,6 +3405,9 @@ if(fname && utf8_strings) opt.flags.utf8_filename=1; + ctrl = xtrycalloc (1, sizeof *ctrl); + gpg_init_default_ctrl (ctrl); + switch( cmd ) { case aPrimegen: case aPrintMD: @@ -3438,13 +3443,7 @@ switch( cmd ) { case aServer: - { - ctrl_t ctrl = xtrycalloc (1, sizeof *ctrl); - gpg_init_default_ctrl (ctrl); - gpg_server (ctrl); - gpg_deinit_default_ctrl (ctrl); - xfree (ctrl); - } + gpg_server (ctrl); break; case aStore: /* only store the file */ @@ -3704,7 +3703,7 @@ case aFastImport: opt.import_options |= IMPORT_FAST; case aImport: - import_keys( argc? argv:NULL, argc, NULL, opt.import_options ); + import_keys (ctrl, argc? argv:NULL, argc, NULL, opt.import_options); break; /* TODO: There are a number of command that use this same @@ -4055,6 +4054,8 @@ } /* cleanup */ + gpg_deinit_default_ctrl (ctrl); + xfree (ctrl); release_armor_context (afx); FREE_STRLIST(remusr); FREE_STRLIST(locusr); Modified: trunk/g10/import.c =================================================================== --- trunk/g10/import.c 2010-08-31 08:42:38 UTC (rev 5407) +++ trunk/g10/import.c 2010-08-31 15:58:39 UTC (rev 5408) @@ -1,6 +1,6 @@ /* import.c - import a key into our key storage. * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - * 2007 Free Software Foundation, Inc. + * 2007, 2010 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -37,6 +37,8 @@ #include "ttyio.h" #include "status.h" #include "keyserver-internal.h" +#include "call-agent.h" +#include "../common/membuf.h" struct stats_s { ulong count; @@ -58,14 +60,15 @@ }; -static int import( IOBUF inp, const char* fname,struct stats_s *stats, - unsigned char **fpr,size_t *fpr_len,unsigned int options ); +static int import (ctrl_t ctrl, + IOBUF inp, const char* fname, struct stats_s *stats, + unsigned char **fpr, size_t *fpr_len, unsigned int options); static int read_block( IOBUF a, PACKET **pending_pkt, KBNODE *ret_root ); static void revocation_present(KBNODE keyblock); static int import_one(const char *fname, KBNODE keyblock,struct stats_s *stats, unsigned char **fpr,size_t *fpr_len, unsigned int options,int from_sk); -static int import_secret_one( const char *fname, KBNODE keyblock, +static int import_secret_one (ctrl_t ctrl, const char *fname, KBNODE keyblock, struct stats_s *stats, unsigned int options); static int import_revoke_cert( const char *fname, KBNODE node, struct stats_s *stats); @@ -96,8 +99,6 @@ N_("repair damage from the pks keyserver during import")}, {"fast-import",IMPORT_FAST,NULL, N_("do not update the trustdb after import")}, - {"convert-sk-to-pk",IMPORT_SK2PK,NULL, - N_("create a public key when importing a secret key")}, {"merge-only",IMPORT_MERGE_ONLY,NULL, N_("only accept updates to existing keys")}, {"import-clean",IMPORT_CLEAN,NULL, @@ -111,6 +112,7 @@ {"import-unusable-sigs",0,NULL,NULL}, {"import-clean-sigs",0,NULL,NULL}, {"import-clean-uids",0,NULL,NULL}, + {"convert-sk-to-pk",0, NULL,NULL}, {NULL,0,NULL,NULL} }; From cvs at cvs.gnupg.org Tue Aug 31 18:43:45 2010 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 31 Aug 2010 18:43:45 +0200 Subject: [svn] gcry - r1446 - trunk/cipher Message-ID: Author: wk Date: 2010-08-31 18:43:44 +0200 (Tue, 31 Aug 2010) New Revision: 1446 Modified: trunk/cipher/pubkey.c Log: typo fix Modified: trunk/cipher/pubkey.c =================================================================== --- trunk/cipher/pubkey.c 2010-08-27 08:52:24 UTC (rev 1445) +++ trunk/cipher/pubkey.c 2010-08-31 16:43:44 UTC (rev 1446) @@ -2357,7 +2357,7 @@ /* Return the so called KEYGRIP which is the SHA-1 hash of the public - key parameters expressed in a way depended on the algorithm. + key parameters expressed in a way depending on the algorithm. ARRAY must either be 20 bytes long or NULL; in the latter case a newly allocated array of that size is returned, otherwise ARRAY or