From cvs at cvs.gnupg.org Wed Nov 3 07:36:51 2004 From: cvs at cvs.gnupg.org (cvs user twoaday) Date: Wed Nov 3 07:37:01 2004 Subject: gnupg/cipher (ChangeLog idea-stub.c) Message-ID: Date: Wednesday, November 3, 2004 @ 07:36:51 Author: twoaday Path: /cvs/gnupg/gnupg/cipher Modified: ChangeLog idea-stub.c 2004-11-03 Timo Schulz * strgutil.c (w32_strerror): New. * ttyio.c (init_ttyfp, tty_printf, do_get): Use it here. * iobuf.c (fd_cache_open, file_filter): Likewise. (iobuf_seek, translate_file_handle): Likewise. -------------+ ChangeLog | 5 +++++ idea-stub.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) From cvs at cvs.gnupg.org Wed Nov 3 07:36:52 2004 From: cvs at cvs.gnupg.org (cvs user twoaday) Date: Wed Nov 3 07:37:07 2004 Subject: gnupg/g10 (ChangeLog misc.c passphrase.c) Message-ID: Date: Wednesday, November 3, 2004 @ 07:36:52 Author: twoaday Path: /cvs/gnupg/gnupg/g10 Modified: ChangeLog misc.c passphrase.c 2004-11-03 Timo Schulz * strgutil.c (w32_strerror): New. * ttyio.c (init_ttyfp, tty_printf, do_get): Use it here. * iobuf.c (fd_cache_open, file_filter): Likewise. (iobuf_seek, translate_file_handle): Likewise. --------------+ ChangeLog | 6 ++ misc.c | 4 + passphrase.c | 133 ++++++++++++++++++++++++++++++--------------------------- 3 files changed, 81 insertions(+), 62 deletions(-) From cvs at cvs.gnupg.org Wed Nov 3 07:36:52 2004 From: cvs at cvs.gnupg.org (cvs user twoaday) Date: Wed Nov 3 07:37:17 2004 Subject: gnupg/include (ChangeLog errors.h) Message-ID: Date: Wednesday, November 3, 2004 @ 07:36:52 Author: twoaday Path: /cvs/gnupg/gnupg/include Modified: ChangeLog errors.h 2004-11-03 Timo Schulz * strgutil.c (w32_strerror): New. * ttyio.c (init_ttyfp, tty_printf, do_get): Use it here. * iobuf.c (fd_cache_open, file_filter): Likewise. (iobuf_seek, translate_file_handle): Likewise. -----------+ ChangeLog | 4 ++++ errors.h | 4 ++++ 2 files changed, 8 insertions(+) From cvs at cvs.gnupg.org Wed Nov 3 07:36:52 2004 From: cvs at cvs.gnupg.org (cvs user twoaday) Date: Wed Nov 3 07:37:25 2004 Subject: gnupg/scripts (autogen.sh) Message-ID: Date: Wednesday, November 3, 2004 @ 07:36:52 Author: twoaday Path: /cvs/gnupg/gnupg/scripts Modified: autogen.sh 2004-11-03 Timo Schulz * strgutil.c (w32_strerror): New. * ttyio.c (init_ttyfp, tty_printf, do_get): Use it here. * iobuf.c (fd_cache_open, file_filter): Likewise. (iobuf_seek, translate_file_handle): Likewise. ------------+ autogen.sh | 177 +++++++++++++++++++++++++++-------------------------------- 1 files changed, 82 insertions(+), 95 deletions(-) From cvs at cvs.gnupg.org Wed Nov 3 07:36:53 2004 From: cvs at cvs.gnupg.org (cvs user twoaday) Date: Wed Nov 3 07:37:32 2004 Subject: gnupg/util (ChangeLog iobuf.c strgutil.c ttyio.c) Message-ID: Date: Wednesday, November 3, 2004 @ 07:36:53 Author: twoaday Path: /cvs/gnupg/gnupg/util Modified: ChangeLog iobuf.c strgutil.c ttyio.c 2004-11-03 Timo Schulz * strgutil.c (w32_strerror): New. * ttyio.c (init_ttyfp, tty_printf, do_get): Use it here. * iobuf.c (fd_cache_open, file_filter): Likewise. (iobuf_seek, translate_file_handle): Likewise. ------------+ ChangeLog | 7 +++++++ iobuf.c | 30 +++++++++++++++--------------- strgutil.c | 16 ++++++++++++++++ ttyio.c | 24 ++++++++++++------------ 4 files changed, 50 insertions(+), 27 deletions(-) From cvs at cvs.gnupg.org Wed Nov 3 15:13:34 2004 From: cvs at cvs.gnupg.org (cvs user twoaday) Date: Wed Nov 3 15:13:40 2004 Subject: gnupg/include (dynload.h) Message-ID: Date: Wednesday, November 3, 2004 @ 15:13:34 Author: twoaday Path: /cvs/gnupg/gnupg/include Modified: dynload.h * dynload.h (dlerror): Use w32_strerror.c -----------+ dynload.h | 4 +--- 1 files changed, 1 insertion(+), 3 deletions(-) From cvs at cvs.gnupg.org Wed Nov 3 17:35:50 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Wed Nov 3 17:35:56 2004 Subject: gnupg/util (ChangeLog strgutil.c) Message-ID: Date: Wednesday, November 3, 2004 @ 17:40:29 Author: wk Path: /cvs/gnupg/gnupg/util Modified: ChangeLog strgutil.c * strgutil.c (load_libiconv): Use log_info to avoid failures when iconv.dll is not installed. ------------+ ChangeLog | 5 +++++ strgutil.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) Index: gnupg/util/ChangeLog diff -u gnupg/util/ChangeLog:1.165 gnupg/util/ChangeLog:1.166 --- gnupg/util/ChangeLog:1.165 Sun Oct 31 00:49:09 2004 +++ gnupg/util/ChangeLog Wed Nov 3 17:40:29 2004 @@ -1,3 +1,8 @@ +2004-11-02 Werner Koch + + * strgutil.c (load_libiconv): Use log_info to avoid failures when + iconv.dll is not installed. + 2004-10-31 Werner Koch * simple-gettext.c (get_string): Removed debugging hack. Index: gnupg/util/strgutil.c diff -u gnupg/util/strgutil.c:1.43 gnupg/util/strgutil.c:1.44 --- gnupg/util/strgutil.c:1.43 Wed Oct 27 18:32:33 2004 +++ gnupg/util/strgutil.c Wed Nov 3 17:40:29 2004 @@ -142,7 +142,7 @@ } if (!handle || !iconv_close) { - log_error (_("error loading `%s': %s\n"), + log_info (_("error loading `%s': %s\n"), "iconv.dll", dlerror ()); iconv_open = NULL; iconv = NULL; From cvs at cvs.gnupg.org Wed Nov 3 18:43:22 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Wed Nov 3 19:03:38 2004 Subject: dirmngr (TODO po/dirmngr.pot) Message-ID: Date: Wednesday, November 3, 2004 @ 18:48:03 Author: wk Path: /cvs/dirmngr/dirmngr Modified: TODO po/dirmngr.pot Updated the TODO list ----------------+ TODO | 4 +++ po/dirmngr.pot | 66 +++++++++++++++++++++++++++---------------------------- 2 files changed, 37 insertions(+), 33 deletions(-) Index: dirmngr/TODO diff -u dirmngr/TODO:1.12 dirmngr/TODO:1.13 --- dirmngr/TODO:1.12 Tue Sep 28 14:27:26 2004 +++ dirmngr/TODO Wed Nov 3 18:48:03 2004 @@ -18,5 +18,9 @@ * Properly parse LDAP attributes from the URL and remove the bad hack in crl_fetch. +* Add --honor-http-proxy + +* Write a utility to use Dirmngr from a script or by other programs. + Index: dirmngr/po/dirmngr.pot diff -u dirmngr/po/dirmngr.pot:1.4 dirmngr/po/dirmngr.pot:1.5 --- dirmngr/po/dirmngr.pot:1.4 Tue Sep 28 15:14:56 2004 +++ dirmngr/po/dirmngr.pot Wed Nov 3 18:48:03 2004 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: gpa-dev@gnupg.org\n" -"POT-Creation-Date: 2004-09-28 14:33+0200\n" +"POT-Creation-Date: 2004-10-04 13:52+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -109,7 +109,7 @@ msgid "unsupported record type in `%s' line %u skipped\n" msgstr "" -#: src/crlcache.c:550 src/crlcache.c:779 src/dirmngr.c:814 +#: src/crlcache.c:550 src/crlcache.c:779 src/dirmngr.c:810 #, c-format msgid "error reading `%s': %s\n" msgstr "" @@ -549,138 +549,138 @@ msgid "|FILE|read options from FILE" msgstr "" -#: src/dirmngr.c:105 -msgid "|NAME|set debugging level to NAME" +#: src/dirmngr.c:106 +msgid "|LEVEL|set the debugging level to LEVEL" msgstr "" -#: src/dirmngr.c:106 +#: src/dirmngr.c:107 msgid "do not detach from the console" msgstr "" -#: src/dirmngr.c:107 +#: src/dirmngr.c:108 msgid "|FILE|write logs to FILE" msgstr "" -#: src/dirmngr.c:108 +#: src/dirmngr.c:109 msgid "run without asking a user" msgstr "" -#: src/dirmngr.c:109 +#: src/dirmngr.c:110 msgid "force loading of outdated CRLs" msgstr "" -#: src/dirmngr.c:110 +#: src/dirmngr.c:111 msgid "allow sending OCSP requests" msgstr "" -#: src/dirmngr.c:113 +#: src/dirmngr.c:114 msgid "|FILE|read LDAP server list from FILE" msgstr "" -#: src/dirmngr.c:115 +#: src/dirmngr.c:116 msgid "add new servers discovered in CRL distribution points to serverlist" msgstr "" -#: src/dirmngr.c:117 +#: src/dirmngr.c:118 msgid "|N|set LDAP timeout to N seconds" msgstr "" -#: src/dirmngr.c:119 +#: src/dirmngr.c:120 msgid "|URL|use OCSP responder at URL" msgstr "" -#: src/dirmngr.c:120 +#: src/dirmngr.c:121 msgid "|FPR|OCSP response signed by FPR" msgstr "" -#: src/dirmngr.c:123 +#: src/dirmngr.c:124 msgid "|N|do not return more than N items in one query" msgstr "" -#: src/dirmngr.c:152 +#: src/dirmngr.c:153 msgid "Please report bugs to .\n" msgstr "" -#: src/dirmngr.c:156 +#: src/dirmngr.c:157 msgid "Usage: dirmngr [options] (-h for help)" msgstr "" -#: src/dirmngr.c:159 +#: src/dirmngr.c:160 msgid "" "Syntax: dirmngr [options] [command [args]]\n" "LDAP and OCSP access for GnuPG\n" msgstr "" -#: src/dirmngr.c:230 +#: src/dirmngr.c:231 #, c-format msgid "invalid debug-level `%s' given\n" msgstr "" -#: src/dirmngr.c:231 +#: src/dirmngr.c:232 #, c-format msgid "valid debug levels are: %s\n" msgstr "" -#: src/dirmngr.c:273 +#: src/dirmngr.c:269 msgid "usage: dirmngr [options] " msgstr "" -#: src/dirmngr.c:314 src/dirmngr.c:324 +#: src/dirmngr.c:310 src/dirmngr.c:320 #, c-format msgid "%s is too old (need %s, have %s)\n" msgstr "" -#: src/dirmngr.c:403 +#: src/dirmngr.c:399 #, c-format msgid "NOTE: no default option file `%s'\n" msgstr "" -#: src/dirmngr.c:408 +#: src/dirmngr.c:404 #, c-format msgid "option file `%s': %s\n" msgstr "" -#: src/dirmngr.c:416 +#: src/dirmngr.c:412 #, c-format msgid "reading options from `%s'\n" msgstr "" -#: src/dirmngr.c:511 +#: src/dirmngr.c:507 #, c-format msgid "WARNING: running with faked system time %s\n" msgstr "" -#: src/dirmngr.c:590 +#: src/dirmngr.c:586 #, c-format msgid "fetching CRL from `%s' failed: %s\n" msgstr "" -#: src/dirmngr.c:596 +#: src/dirmngr.c:592 #, c-format msgid "processing CRL from `%s' failed: %s\n" msgstr "" -#: src/dirmngr.c:718 +#: src/dirmngr.c:714 #, c-format msgid "error opening `%s': %s\n" msgstr "" -#: src/dirmngr.c:735 +#: src/dirmngr.c:731 #, c-format msgid "%s:%u: line too long - skipped\n" msgstr "" -#: src/dirmngr.c:763 +#: src/dirmngr.c:759 #, c-format msgid "%s:%u: no hostname given\n" msgstr "" -#: src/dirmngr.c:782 +#: src/dirmngr.c:778 #, c-format msgid "%s:%u: password given without user\n" msgstr "" -#: src/dirmngr.c:803 +#: src/dirmngr.c:799 #, c-format msgid "%s:%u: skipping this line\n" msgstr "" From cvs at cvs.gnupg.org Wed Nov 3 20:59:06 2004 From: cvs at cvs.gnupg.org (cvs user twoaday) Date: Wed Nov 3 20:59:10 2004 Subject: gnupg (14 files) Message-ID: Date: Wednesday, November 3, 2004 @ 21:03:46 Author: twoaday Path: /cvs/gnupg/gnupg Modified: THANKS cipher/ChangeLog cipher/idea-stub.c g10/ChangeLog g10/misc.c g10/passphrase.c include/ChangeLog include/dynload.h include/errors.h util/ChangeLog util/iobuf.c util/simple-gettext.c util/strgutil.c util/ttyio.c 2004-11-03 Timo Schulz * strgutil.c (w32_strerror): New. * ttyio.c (init_ttyfp, tty_printf, do_get): Use it here. * iobuf.c (fd_cache_open, file_filter): Likewise. (iobuf_seek, translate_file_handle): Likewise. -----------------------+ THANKS | 2 cipher/ChangeLog | 5 + cipher/idea-stub.c | 15 ++--- g10/ChangeLog | 6 ++ g10/misc.c | 4 + g10/passphrase.c | 135 +++++++++++++++++++++++++----------------------- include/ChangeLog | 5 + include/dynload.h | 4 - include/errors.h | 6 +- util/ChangeLog | 7 ++ util/iobuf.c | 30 +++++----- util/simple-gettext.c | 2 util/strgutil.c | 16 +++++ util/ttyio.c | 24 ++++---- 14 files changed, 156 insertions(+), 105 deletions(-) Index: gnupg/THANKS diff -u gnupg/THANKS:1.75 gnupg/THANKS:1.76 --- gnupg/THANKS:1.75 Wed Oct 13 20:08:39 2004 +++ gnupg/THANKS Wed Nov 3 21:03:46 2004 @@ -196,7 +196,7 @@ Thijmen Klok thijmen@xs4all.nl Thomas Roessler roessler@guug.de Tim Mooney mooney@dogbert.cc.ndsu.nodak.edu -Timo Schulz towaday@freakmail.de +Timo Schulz twoaday@freakmail.de Todd Vierling tv@pobox.com TOGAWA Satoshi Satoshi.Togawa@jp.yokogawa.com Tom Spindler dogcow@home.merit.edu Index: gnupg/cipher/ChangeLog diff -u gnupg/cipher/ChangeLog:1.144 gnupg/cipher/ChangeLog:1.145 --- gnupg/cipher/ChangeLog:1.144 Thu Oct 14 09:21:16 2004 +++ gnupg/cipher/ChangeLog Wed Nov 3 21:03:46 2004 @@ -1,3 +1,8 @@ +2004-11-03 Timo Schulz + + * idea-stub.c (dlopen, dlsym): Use w32_strerror instead of + just showing the error number. + 2004-10-14 Werner Koch * rndunix.c (start_gatherer) [ENABLE_SELINUX_HACKS]: Don't allow Index: gnupg/cipher/idea-stub.c diff -u gnupg/cipher/idea-stub.c:1.7 gnupg/cipher/idea-stub.c:1.8 --- gnupg/cipher/idea-stub.c:1.7 Tue Oct 12 19:35:50 2004 +++ gnupg/cipher/idea-stub.c Wed Nov 3 21:03:46 2004 @@ -63,7 +63,7 @@ void *h = LoadLibrary (pathname); if (!h) { - log_error ("LoadLibrary failed ec=%d\n", (int)GetLastError()); + log_error ("LoadLibrary failed: %s\n", w32_strerror (errno)); last_error = 1; return NULL; } @@ -77,25 +77,22 @@ return FreeLibrary (handle); } -char* + +const char* dlerror (void) { - static char dlerrstr[10]; if (last_error) - { - sprintf(dlerrstr, "%d", (int)GetLastError() ); - return dlerrstr; - } + return w32_strerror (0); return NULL; } void* -dlsym ( void *handle, const char *name ) +dlsym (void *handle, const char *name) { void *h = GetProcAddress (handle, name); if (!h) { - log_error ("GetProcAddress failed ec=%d\n", (int)GetLastError()); + log_error ("GetProcAddress failed: %s\n", w32_strerror (errno)); last_error = 1; } return h; Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.635 gnupg/g10/ChangeLog:1.636 --- gnupg/g10/ChangeLog:1.635 Fri Oct 29 00:09:09 2004 +++ gnupg/g10/ChangeLog Wed Nov 3 21:03:46 2004 @@ -1,3 +1,9 @@ +2004-11-03 Timo Schulz + + * passphrase.c (readn, writen): Use w32_strerror instead + of just showing the error number. + * misc.c [_WIN32]: Fix warning about missing prototypes. + 2004-10-28 David Shaw * skclist.c (build_sk_list): Don't need to warn about Index: gnupg/g10/misc.c diff -u gnupg/g10/misc.c:1.61 gnupg/g10/misc.c:1.62 --- gnupg/g10/misc.c:1.61 Thu Oct 14 09:11:56 2004 +++ gnupg/g10/misc.c Wed Nov 3 21:03:46 2004 @@ -37,6 +37,10 @@ #ifdef ENABLE_SELINUX_HACKS #include #endif +#ifdef _WIN32 +#include +#include +#endif #include "util.h" #include "main.h" #include "photoid.h" Index: gnupg/g10/passphrase.c diff -u gnupg/g10/passphrase.c:1.67 gnupg/g10/passphrase.c:1.68 --- gnupg/g10/passphrase.c:1.67 Fri Oct 29 00:09:09 2004 +++ gnupg/g10/passphrase.c Wed Nov 3 21:03:46 2004 @@ -189,99 +189,108 @@ } static int -writen ( int fd, const void *buf, size_t nbytes ) +writen (int fd, const void *buf, size_t nbytes) { #if defined (_WIN32) - DWORD nwritten, nleft = nbytes; + DWORD nwritten, nleft = nbytes; - while (nleft > 0) { - if ( !WriteFile( (HANDLE)write_fd, buf, nleft, &nwritten, NULL) ) { - log_error("write failed: ec=%d\n", (int)GetLastError()); - return -1; - } - /*log_info("** WriteFile fd=%d nytes=%d nwritten=%d\n", - write_fd, nbytes, (int)nwritten);*/ - Sleep(100); + while (nleft > 0) + { + if (!WriteFile ((HANDLE)write_fd, buf, nleft, &nwritten, NULL)) + { + log_error ("write failed: %s\n", w32_strerror (0)); + return -1; + } + /*log_info ("** WriteFile fd=%d nytes=%d nwritten=%d\n", + write_fd, nbytes, (int)nwritten);*/ + Sleep (100); - nleft -= nwritten; - buf = (const BYTE *)buf + nwritten; + nleft -= nwritten; + buf = (const BYTE *)buf + nwritten; } #elif defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - /* not implemented */ + /* not implemented */ #else - size_t nleft = nbytes; - int nwritten; + size_t nleft = nbytes; + int nwritten; - while( nleft > 0 ) { - nwritten = write( fd, buf, nleft ); - if( nwritten < 0 ) { - if ( errno == EINTR ) - nwritten = 0; - else { - log_error ( "write() failed: %s\n", strerror (errno) ); - return -1; + while (nleft > 0) + { + nwritten = write (fd, buf, nleft); + if (nwritten < 0) + { + if (errno == EINTR) + nwritten = 0; + else + { + log_error ("write() failed: %s\n", strerror (errno)); + return -1; } } - nleft -= nwritten; - buf = (const char*)buf + nwritten; + nleft -= nwritten; + buf = (const char*)buf + nwritten; } #endif - return 0; + return 0; } static int -readn ( int fd, void *buf, size_t buflen, size_t *ret_nread ) +readn (int fd, void *buf, size_t buflen, size_t *ret_nread) { #if defined (_WIN32) - DWORD nread, nleft = buflen; + DWORD nread, nleft = buflen; - while (nleft > 0) { - if ( !ReadFile( (HANDLE)read_fd, buf, nleft, &nread, NULL) ) { - log_error("read() error: ec=%d\n", (int)GetLastError()); - return -1; + while (nleft > 0) + { + if (!ReadFile ((HANDLE)read_fd, buf, nleft, &nread, NULL)) + { + log_error ("read() error: %s\n", w32_strerror (0)); + return -1; } - if (!nread || GetLastError() == ERROR_BROKEN_PIPE) - break; - /*log_info("** ReadFile fd=%d buflen=%d nread=%d\n", - read_fd, buflen, (int)nread);*/ - Sleep(100); + if (!nread || GetLastError() == ERROR_BROKEN_PIPE) + break; + /*log_info ("** ReadFile fd=%d buflen=%d nread=%d\n", + read_fd, buflen, (int)nread);*/ + Sleep (100); - nleft -= nread; - buf = (BYTE *)buf + nread; + nleft -= nread; + buf = (BYTE *)buf + nread; } - if (ret_nread) - *ret_nread = buflen - nleft; + if (ret_nread) + *ret_nread = buflen - nleft; #elif defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) - /* not implemented */ + /* not implemented */ #else - size_t nleft = buflen; - int nread; - char *p; - - p = buf; - while( nleft > 0 ) { - nread = read ( fd, buf, nleft ); - if( nread < 0 ) { - if (nread == EINTR) - nread = 0; - else { - log_error ( "read() error: %s\n", strerror (errno) ); - return -1; - } + size_t nleft = buflen; + int nread; + char *p; + + p = buf; + while (nleft > 0) + { + nread = read (fd, buf, nleft); + if (nread < 0) + { + if (nread == EINTR) + nread = 0; + else { + log_error ("read() error: %s\n", strerror (errno)); + return -1; + } } - else if( !nread ) - break; /* EOF */ - nleft -= nread; - buf = (char*)buf + nread; + else if (!nread) + break; /* EOF */ + nleft -= nread; + buf = (char*)buf + nread; } - if( ret_nread ) - *ret_nread = buflen - nleft; + if (ret_nread) + *ret_nread = buflen - nleft; #endif - return 0; + return 0; } /* read an entire line */ Index: gnupg/include/ChangeLog diff -u gnupg/include/ChangeLog:1.78 gnupg/include/ChangeLog:1.79 --- gnupg/include/ChangeLog:1.78 Wed Oct 27 18:32:51 2004 +++ gnupg/include/ChangeLog Wed Nov 3 21:03:46 2004 @@ -1,3 +1,8 @@ +2004-11-03 Timo Schulz + + * errors.h: Add w32_strerror prototype. + * dynload.h: Use w32_strerror. + 2004-10-27 Werner Koch * dynload.h: Always use it for _WIN32. Index: gnupg/include/dynload.h diff -u gnupg/include/dynload.h:1.4 gnupg/include/dynload.h:1.5 --- gnupg/include/dynload.h:1.4 Wed Oct 27 18:32:51 2004 +++ gnupg/include/dynload.h Wed Nov 3 21:03:46 2004 @@ -52,9 +52,7 @@ static __inline__ const char * dlerror (void) { - static char buf[32]; - sprintf (buf, "ec=%lu\n", GetLastError ()); - return buf; + return w32_strerror (0); } Index: gnupg/include/errors.h diff -u gnupg/include/errors.h:1.27 gnupg/include/errors.h:1.28 --- gnupg/include/errors.h:1.27 Thu Sep 9 20:18:33 2004 +++ gnupg/include/errors.h Wed Nov 3 21:03:46 2004 @@ -79,7 +79,11 @@ #define G10ERR_NO_CARD 57 #ifndef HAVE_STRERROR -char *strerror( int n ); +char *strerror (int n); +#endif + +#ifdef _WIN32 +const char * w32_strerror (int w32_errno); #endif #endif /*G10_ERRORS_H*/ Index: gnupg/util/ChangeLog diff -u gnupg/util/ChangeLog:1.166 gnupg/util/ChangeLog:1.167 --- gnupg/util/ChangeLog:1.166 Wed Nov 3 17:40:29 2004 +++ gnupg/util/ChangeLog Wed Nov 3 21:03:46 2004 @@ -1,3 +1,10 @@ +2004-11-03 Timo Schulz + + * strgutil.c (w32_strerror): New. + * ttyio.c (init_ttyfp, tty_printf, do_get): Use it here. + * iobuf.c (fd_cache_open, file_filter): Likewise. + (iobuf_seek, translate_file_handle): Likewise. + 2004-11-02 Werner Koch * strgutil.c (load_libiconv): Use log_info to avoid failures when Index: gnupg/util/iobuf.c diff -u gnupg/util/iobuf.c:1.69 gnupg/util/iobuf.c:1.70 --- gnupg/util/iobuf.c:1.69 Thu Oct 14 09:20:54 2004 +++ gnupg/util/iobuf.c Wed Nov 3 21:03:46 2004 @@ -287,8 +287,8 @@ log_debug ("fd_cache_open (%s) using cached fp\n", fname); #ifdef HAVE_DOSISH_SYSTEM if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff ) { - log_error ("rewind file failed on handle %p: ec=%d\n", - fp, (int)GetLastError () ); + log_error ("rewind file failed on handle %p: %s\n", + fp, w32_strerror (errno)); fp = INVALID_FP; } #else @@ -404,9 +404,9 @@ nbytes = 0; if ( !ReadFile ( f, buf, size, &nread, NULL ) ) { - int ec = (int)GetLastError (); - if ( ec != ERROR_BROKEN_PIPE ) { - log_error("%s: read error: ec=%d\n", a->fname, ec); + if ((int)GetLastError () != ERROR_BROKEN_PIPE) { + log_error ("%s: read error: %s\n", a->fname, + w32_strerror (0)); rc = G10ERR_READ_FILE; } } @@ -452,9 +452,9 @@ nbytes = size; do { - if ( size && !WriteFile ( f, p, nbytes, &n, NULL) ) { - int ec = (int)GetLastError (); - log_error("%s: write error: ec=%d\n", a->fname, ec); + if (size && !WriteFile (f, p, nbytes, &n, NULL)) { + log_error ("%s: write error: %s\n", a->fname, + w32_strerror (0)); rc = G10ERR_WRITE_FILE; break; } @@ -1835,10 +1835,10 @@ #if defined(HAVE_DOSISH_SYSTEM) && !defined(FILE_FILTER_USES_STDIO) ulong size; - if ( (size=GetFileSize (fp, NULL)) != 0xffffffff ) + if ((size=GetFileSize (fp, NULL)) != 0xffffffff) return size; - log_error ("GetFileSize for handle %p failed: ec=%d\n", - fp, (int)GetLastError () ); + log_error ("GetFileSize for handle %p failed: %s\n", + fp, w32_strerror (0)); #else if( !fstat(my_fileno(fp), &st) ) return st.st_size; @@ -1945,8 +1945,8 @@ #else #ifdef HAVE_DOSISH_SYSTEM if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff ) { - log_error ("SetFilePointer failed on handle %p: ec=%d\n", - b->fp, (int)GetLastError () ); + log_error ("SetFilePointer failed on handle %p: %s\n", + b->fp, w32_strerror (0)); return -1; } #else @@ -2143,8 +2143,8 @@ x = fd; if (x == -1) - log_debug ("GetStdHandle(%d) failed: ec=%d\n", - fd, (int)GetLastError () ); + log_debug ("GetStdHandle(%d) failed: %s\n", + fd, w32_strerror (0)); fd = x; } Index: gnupg/util/simple-gettext.c diff -u gnupg/util/simple-gettext.c:1.11 gnupg/util/simple-gettext.c:1.12 --- gnupg/util/simple-gettext.c:1.11 Sun Oct 31 00:49:09 2004 +++ gnupg/util/simple-gettext.c Wed Nov 3 21:03:46 2004 @@ -427,7 +427,7 @@ log_info("InputCP=%u OutputCP=%u\n", cp1, cp2 ); if( !SetConsoleOutputCP( 1252 ) ) - log_info("SetConsoleOutputCP failed: %d\n", (int)GetLastError() ); + log_info("SetConsoleOutputCP failed: %s\n", w32_strerror (0)); cp1 = GetConsoleCP(); cp2 = GetConsoleOutputCP(); Index: gnupg/util/strgutil.c diff -u gnupg/util/strgutil.c:1.44 gnupg/util/strgutil.c:1.45 --- gnupg/util/strgutil.c:1.44 Wed Nov 3 17:40:29 2004 +++ gnupg/util/strgutil.c Wed Nov 3 21:03:46 2004 @@ -1260,4 +1260,20 @@ return status; } +const char * +w32_strerror (int w32_errno) +{ + static char strerr[256]; + int ec = (int)GetLastError (); + + if (w32_errno == 0) + w32_errno = ec; + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, w32_errno, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + strerr, DIM (strerr)-1, NULL); + return strerr; +} #endif /*_WIN32*/ + + + Index: gnupg/util/ttyio.c diff -u gnupg/util/ttyio.c:1.32 gnupg/util/ttyio.c:1.33 --- gnupg/util/ttyio.c:1.32 Thu Sep 9 19:04:41 2004 +++ gnupg/util/ttyio.c Wed Nov 3 21:03:46 2004 @@ -140,15 +140,15 @@ FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, 0 ); if( con.out == INVALID_HANDLE_VALUE ) - log_fatal("open(CONOUT$) failed: rc=%d", (int)GetLastError() ); + log_fatal ("open(CONOUT$) failed: %s", w32_strerror (0)); memset(&sa, 0, sizeof(sa)); sa.nLength = sizeof(sa); sa.bInheritHandle = TRUE; con.in = CreateFileA( "CONIN$", GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, &sa, OPEN_EXISTING, 0, 0 ); - if( con.in == INVALID_HANDLE_VALUE ) - log_fatal("open(CONIN$) failed: rc=%d", (int)GetLastError() ); + if (con.in == INVALID_HANDLE_VALUE) + log_fatal ("open(CONIN$) failed: %s", w32_strerror (0)); } SetConsoleMode(con.in, DEF_INPMODE ); SetConsoleMode(con.out, DEF_OUTMODE ); @@ -212,10 +212,10 @@ if( !buf ) log_bug("vasprintf() failed\n"); - if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) ) - log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() ); + if (!WriteConsoleA (con.out, buf, n, &nwritten, NULL)) + log_fatal ("WriteConsole failed: %s", w32_strerror (0)); if( n != nwritten ) - log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten ); + log_fatal ("WriteConsole failed: %d != %d\n", n, (int)nwritten ); last_prompt_len += n; m_free (buf); } @@ -259,10 +259,10 @@ if( !buf ) log_bug("vasprintf() failed\n"); - if( !WriteConsoleA( con.out, buf, n, &nwritten, NULL ) ) - log_fatal("WriteConsole failed: rc=%d", (int)GetLastError() ); - if( n != nwritten ) - log_fatal("WriteConsole failed: %d != %d\n", n, (int)nwritten ); + if (!WriteConsoleA (con.out, buf, n, &nwritten, NULL)) + log_fatal ("WriteConsole failed: %s", w32_strerror (0)); + if (n != nwritten) + log_fatal ("WriteConsole failed: %d != %d\n", n, (int)nwritten); last_prompt_len += n; xfree (buf); } @@ -387,8 +387,8 @@ for(;;) { DWORD nread; - if( !ReadConsoleA( con.in, cbuf, 1, &nread, NULL ) ) - log_fatal("ReadConsole failed: rc=%d", (int)GetLastError() ); + if (!ReadConsoleA (con.in, cbuf, 1, &nread, NULL)) + log_fatal ("ReadConsole failed: %s", w32_strerror (0)); if( !nread ) continue; if( *cbuf == '\n' ) From cvs at cvs.gnupg.org Wed Nov 3 21:30:47 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Wed Nov 3 21:30:49 2004 Subject: gnupg/g10 (ChangeLog misc.c) Message-ID: Date: Wednesday, November 3, 2004 @ 21:35:28 Author: dshaw Path: /cvs/gnupg/gnupg/g10 Modified: ChangeLog misc.c * misc.c (print_digest_algo_note): The latest 2440bis drafts deprecates MD5, so give a warning. (print_pubkey_algo_note, print_cipher_algo_note, print_digest_algo_note): Give the algorithm name in the experimental algo warning. -----------+ ChangeLog | 8 +++++++ misc.c | 66 ++++++++++++++++++++++++++++-------------------------------- 2 files changed, 39 insertions(+), 35 deletions(-) Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.636 gnupg/g10/ChangeLog:1.637 --- gnupg/g10/ChangeLog:1.636 Wed Nov 3 21:03:46 2004 +++ gnupg/g10/ChangeLog Wed Nov 3 21:35:28 2004 @@ -1,3 +1,11 @@ +2004-11-03 David Shaw + + * misc.c (print_digest_algo_note): The latest 2440bis drafts + deprecates MD5, so give a warning. + (print_pubkey_algo_note, print_cipher_algo_note, + print_digest_algo_note): Give the algorithm name in the + experimental algo warning. + 2004-11-03 Timo Schulz * passphrase.c (readn, writen): Use w32_strerror instead Index: gnupg/g10/misc.c diff -u gnupg/g10/misc.c:1.62 gnupg/g10/misc.c:1.63 --- gnupg/g10/misc.c:1.62 Wed Nov 3 21:03:46 2004 +++ gnupg/g10/misc.c Wed Nov 3 21:35:28 2004 @@ -287,46 +287,32 @@ return a; } - -static void -no_exp_algo(void) -{ - static int did_note = 0; - - if( !did_note ) { - did_note = 1; - log_info(_("Experimental algorithms should not be used!\n")); - } -} - void print_pubkey_algo_note( int algo ) { - if( algo >= 100 && algo <= 110 ) - no_exp_algo(); + if(algo >= 100 && algo <= 110) + { + static int warn=0; + if(!warn) + { + warn=1; + log_info(_("WARNING: using experimental public key algorithm %s\n"), + pubkey_algo_to_string(algo)); + } + } } void print_cipher_algo_note( int algo ) { - if( algo >= 100 && algo <= 110 ) - no_exp_algo(); - else if( algo == CIPHER_ALGO_3DES - || algo == CIPHER_ALGO_CAST5 - || algo == CIPHER_ALGO_BLOWFISH - || algo == CIPHER_ALGO_TWOFISH - || algo == CIPHER_ALGO_AES - || algo == CIPHER_ALGO_AES192 - || algo == CIPHER_ALGO_AES256 - ) - ; - else { - static int did_note = 0; - - if( !did_note ) { - did_note = 1; - log_info(_("this cipher algorithm is deprecated; " - "please use a more standard one!\n")); + if(algo >= 100 && algo <= 110) + { + static int warn=0; + if(!warn) + { + warn=1; + log_info(_("WARNING: using experimental cipher algorithm %s\n"), + cipher_algo_to_string(algo)); } } } @@ -334,11 +320,21 @@ void print_digest_algo_note( int algo ) { - if( algo >= 100 && algo <= 110 ) - no_exp_algo(); + if(algo >= 100 && algo <= 110) + { + static int warn=0; + if(!warn) + { + warn=1; + log_info(_("WARNING: using experimental digest algorithm %s\n"), + digest_algo_to_string(algo)); + } + } + else if(algo==DIGEST_ALGO_MD5) + log_info(_("WARNING: digest algorithm %s is deprecated\n"), + digest_algo_to_string(algo)); } - /* Return a string which is used as a kind of process ID */ const byte * get_session_marker( size_t *rlen ) From cvs at cvs.gnupg.org Thu Nov 4 14:53:21 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Thu Nov 4 14:53:24 2004 Subject: gpgme (TODO) Message-ID: Date: Thursday, November 4, 2004 @ 14:58:06 Author: wk Path: /cvs/gpgme/gpgme Modified: TODO . ------+ TODO | 1 + 1 files changed, 1 insertion(+) Index: gpgme/TODO diff -u gpgme/TODO:1.94 gpgme/TODO:1.95 --- gpgme/TODO:1.94 Wed Sep 29 01:25:35 2004 +++ gpgme/TODO Thu Nov 4 14:58:06 2004 @@ -1,6 +1,7 @@ Hey Emacs, this is -*- outline -*- mode! * Before release: +** Switch to LGPL? ** Some gpg tests fail with gpg 1.3.4-cvs (gpg/t-keylist-sig) The test is currently disabled there and in gpg/t-import. ** Add notation data to key signatures. From cvs at cvs.gnupg.org Thu Nov 4 23:23:52 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Thu Nov 4 23:23:54 2004 Subject: gnupg/g10 (ChangeLog encode.c plaintext.c progress.c sign.c) Message-ID: Date: Thursday, November 4, 2004 @ 23:28:39 Author: dshaw Path: /cvs/gnupg/gnupg/g10 Modified: ChangeLog encode.c plaintext.c progress.c sign.c * plaintext.c (handle_plaintext): Don't try and create a zero-length filename when using --use-embedded-filename with input that has no filename (clearsigned or message generated from a pipe). * encode.c (encode_simple, encode_crypt), progress.c (handle_progress), sign.c (write_plaintext_packet): Fix a few inconsistent calls (NULL filename means a pipe here, so don't bother to check it twice). -------------+ ChangeLog | 12 ++++++++++++ encode.c | 16 ++++++++-------- plaintext.c | 5 +++-- progress.c | 2 +- sign.c | 14 +++++++------- 5 files changed, 31 insertions(+), 18 deletions(-) Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.637 gnupg/g10/ChangeLog:1.638 --- gnupg/g10/ChangeLog:1.637 Wed Nov 3 21:35:28 2004 +++ gnupg/g10/ChangeLog Thu Nov 4 23:28:39 2004 @@ -1,3 +1,15 @@ +2004-11-04 David Shaw + + * plaintext.c (handle_plaintext): Don't try and create a + zero-length filename when using --use-embedded-filename with input + that has no filename (clearsigned or message generated from a + pipe). + + * encode.c (encode_simple, encode_crypt), progress.c + (handle_progress), sign.c (write_plaintext_packet): Fix a few + inconsistent calls (NULL filename means a pipe here, so don't + bother to check it twice). + 2004-11-03 David Shaw * misc.c (print_digest_algo_note): The latest 2440bis drafts Index: gnupg/g10/encode.c diff -u gnupg/g10/encode.c:1.92 gnupg/g10/encode.c:1.93 --- gnupg/g10/encode.c:1.92 Wed Oct 13 20:10:06 2004 +++ gnupg/g10/encode.c Thu Nov 4 23:28:39 2004 @@ -300,8 +300,8 @@ either partial length or fixed length with the new style messages. */ - if ( !iobuf_is_pipe_filename (filename) && filename && *filename - && !opt.textmode ) { + if ( !iobuf_is_pipe_filename (filename) && *filename && !opt.textmode ) + { off_t tmpsize; if ( !(tmpsize = iobuf_get_filelength(inp)) ) @@ -314,9 +314,9 @@ filesize = tmpsize; else filesize = 0; - } + } else - filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ + filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ if (!opt.no_literal) { pt->timestamp = make_timestamp(); @@ -596,8 +596,8 @@ } } - if (!iobuf_is_pipe_filename (filename) && *filename - && !opt.textmode ) { + if (!iobuf_is_pipe_filename (filename) && *filename && !opt.textmode ) + { off_t tmpsize; if ( !(tmpsize = iobuf_get_filelength(inp)) ) @@ -610,9 +610,9 @@ filesize = tmpsize; else filesize = 0; - } + } else - filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ + filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ if (!opt.no_literal) { pt->timestamp = make_timestamp(); Index: gnupg/g10/plaintext.c diff -u gnupg/g10/plaintext.c:1.58 gnupg/g10/plaintext.c:1.59 --- gnupg/g10/plaintext.c:1.58 Thu Oct 28 05:57:30 2004 +++ gnupg/g10/plaintext.c Thu Nov 4 23:28:39 2004 @@ -105,13 +105,14 @@ if( nooutput ) ; - else if ( iobuf_is_pipe_filename (fname) ) { + else if ( iobuf_is_pipe_filename (fname) || !*fname) + { /* No filename or "-" given; write to stdout. */ fp = stdout; #ifdef HAVE_DOSISH_SYSTEM setmode ( fileno(fp) , O_BINARY ); #endif - } + } else { while( !overwrite_filep (fname) ) { char *tmp = ask_outfile_name (NULL, 0); Index: gnupg/g10/progress.c diff -u gnupg/g10/progress.c:1.5 gnupg/g10/progress.c:1.6 --- gnupg/g10/progress.c:1.5 Wed Oct 13 11:59:44 2004 +++ gnupg/g10/progress.c Thu Nov 4 23:28:39 2004 @@ -105,7 +105,7 @@ if (!is_status_enabled ()) return; - if ( !iobuf_is_pipe_filename (name) && name && *name ) + if ( !iobuf_is_pipe_filename (name) && *name ) filesize = iobuf_get_filelength (inp); else if (opt.set_filesize) filesize = opt.set_filesize; Index: gnupg/g10/sign.c diff -u gnupg/g10/sign.c:1.134 gnupg/g10/sign.c:1.135 --- gnupg/g10/sign.c:1.134 Fri Oct 29 00:09:09 2004 +++ gnupg/g10/sign.c Thu Nov 4 23:28:39 2004 @@ -543,11 +543,12 @@ } /* try to calculate the length of the data */ - if ( !iobuf_is_pipe_filename (fname) && fname && *fname ) { + if ( !iobuf_is_pipe_filename (fname) && *fname ) + { off_t tmpsize; if( !(tmpsize = iobuf_get_filelength(inp)) ) - log_info (_("WARNING: `%s' is an empty file\n"), fname); + log_info (_("WARNING: `%s' is an empty file\n"), fname); /* We can't encode the length of very large files because OpenPGP uses only 32 bit for file sizes. So if the size of @@ -563,11 +564,10 @@ * without a double read of the file - to avoid that * we simple use partial length packets. */ if ( ptmode == 't' ) - filesize = 0; - } - else { - filesize = opt.set_filesize? opt.set_filesize : 0; /* stdin */ - } + filesize = 0; + } + else + filesize = opt.set_filesize? opt.set_filesize : 0; /* stdin */ if (!opt.no_literal) { PACKET pkt; From cvs at cvs.gnupg.org Fri Nov 5 04:40:17 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Fri Nov 5 04:40:20 2004 Subject: gnupg (ChangeLog README configure.ac) Message-ID: Date: Friday, November 5, 2004 @ 04:45:06 Author: dshaw Path: /cvs/gnupg/gnupg Modified: ChangeLog README configure.ac * README, configure.ac: Add --enable-backsigs to enable the experimental backsigs code. --------------+ ChangeLog | 5 +++++ README | 10 +++++++++- configure.ac | 11 ++++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) Index: gnupg/ChangeLog diff -u gnupg/ChangeLog:1.218 gnupg/ChangeLog:1.219 --- gnupg/ChangeLog:1.218 Thu Oct 28 11:06:50 2004 +++ gnupg/ChangeLog Fri Nov 5 04:45:06 2004 @@ -1,3 +1,8 @@ +2004-11-04 David Shaw + + * README, configure.ac: Add --enable-backsigs to enable the + experimental backsigs code. + 2004-10-28 Werner Koch Released 1.3.92. Index: gnupg/README diff -u gnupg/README:1.88 gnupg/README:1.89 --- gnupg/README:1.88 Thu Oct 28 11:06:50 2004 +++ gnupg/README Fri Nov 5 04:45:06 2004 @@ -614,7 +614,15 @@ support. This option allows to explicity disable the use of iconv. Note, that iconv is also disabled if getext has been disabled. - + + --enable-backsigs + Enables "backsigs" support. This is a currently + experimental solution to a subtle OpenPGP protocol + problem involving signing subkeys. It is + specified in the 2440bis drafts that will become + the new OpenPGP standard, but is not finalized yet + and has not had interoperability testing. Use at + your own risk. Installation Problems Index: gnupg/configure.ac diff -u gnupg/configure.ac:1.110 gnupg/configure.ac:1.111 --- gnupg/configure.ac:1.110 Thu Oct 28 11:50:24 2004 +++ gnupg/configure.ac Fri Nov 5 04:45:06 2004 @@ -19,7 +19,7 @@ dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA dnl dnl (Process this file with autoconf to produce a configure script.) -dnlAC_REVISION($Revision: 1.110 $)dnl +dnlAC_REVISION($Revision: 1.111 $)dnl AC_PREREQ(2.59) min_automake_version="1.7.9" @@ -131,6 +131,12 @@ gnupg_use_iconv=$enableval, gnupg_use_iconv=yes) AC_MSG_RESULT($gnupg_use_iconv) +AC_MSG_CHECKING([whether to enable the experimental backsigs code]) +AC_ARG_ENABLE(backsigs, + AC_HELP_STRING([--enable-backsigs], + [enable the experimental backsigs code]), + do_backsigs=$enableval, do_backsigs=no) +AC_MSG_RESULT($do_backsigs) dnl See if we are disabling any algorithms or features for a smaller dnl binary @@ -751,6 +757,9 @@ AC_DEFINE(USE_GNUPG_ICONV,1,[Define to use the new iconv based code]) fi +if test "$do_backsigs" = yes ; then + AC_DEFINE(DO_BACKSIGS,1,[Define to enable the experimental backsigs code]) +fi AM_CONDITIONAL(ENABLE_CARD_SUPPORT, test "$card_support" = yes) From cvs at cvs.gnupg.org Sat Nov 6 14:13:18 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Sat Nov 6 14:13:21 2004 Subject: gnupg (ChangeLog configure.ac) Message-ID: Date: Saturday, November 6, 2004 @ 14:18:13 Author: dshaw Path: /cvs/gnupg/gnupg Modified: ChangeLog configure.ac * configure.ac: Autodetect wldap32 on Windoze. --------------+ ChangeLog | 4 ++++ configure.ac | 14 ++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) Index: gnupg/ChangeLog diff -u gnupg/ChangeLog:1.219 gnupg/ChangeLog:1.220 --- gnupg/ChangeLog:1.219 Fri Nov 5 04:45:06 2004 +++ gnupg/ChangeLog Sat Nov 6 14:18:13 2004 @@ -1,3 +1,7 @@ +2004-11-06 David Shaw + + * configure.ac: Autodetect wldap32 on Windoze. + 2004-11-04 David Shaw * README, configure.ac: Add --enable-backsigs to enable the Index: gnupg/configure.ac diff -u gnupg/configure.ac:1.111 gnupg/configure.ac:1.112 --- gnupg/configure.ac:1.111 Fri Nov 5 04:45:06 2004 +++ gnupg/configure.ac Sat Nov 6 14:18:13 2004 @@ -19,7 +19,7 @@ dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA dnl dnl (Process this file with autoconf to produce a configure script.) -dnlAC_REVISION($Revision: 1.111 $)dnl +dnlAC_REVISION($Revision: 1.112 $)dnl AC_PREREQ(2.59) min_automake_version="1.7.9" @@ -456,7 +456,6 @@ have_dosish_system=yes need_dlopen=no try_gettext="no" - LDAPLIBS="-lwldap32" ;; i?86-emx-os2 | i?86-*-os2*emx ) # OS/2 with the EMX environment @@ -592,12 +591,19 @@ # LDAPLIBS="-Lfoo -lbar" if test "$try_ldap" = yes ; then - for MY_LDAPLIBS in ${LDAPLIBS+"$LDAPLIBS"} "-lldap" "-lldap -llber" "-lldap -llber -lresolv"; do + for MY_LDAPLIBS in ${LDAPLIBS+"$LDAPLIBS"} "-lldap" "-lldap -llber" "-lldap -llber -lresolv" "-lwldap32"; do _ldap_save_libs=$LIBS LIBS="$MY_LDAPLIBS $NETLIBS $LIBS" AC_MSG_CHECKING([whether LDAP via \"$MY_LDAPLIBS\" is present and sane]) - AC_TRY_LINK([#include ],[ldap_open("foobar",1234);], + AC_TRY_LINK([ +#ifdef _WIN32 +#include +#include +#else +#include +#endif +],[ldap_open("foobar",1234);], [gnupg_cv_func_ldap_init=yes],[gnupg_cv_func_ldap_init=no]) AC_MSG_RESULT([$gnupg_cv_func_ldap_init]) From cvs at cvs.gnupg.org Tue Nov 9 18:00:55 2004 From: cvs at cvs.gnupg.org (cvs user werner) Date: Tue Nov 9 18:01:10 2004 Subject: libgcrypt/src (ChangeLog gcrypt.h) Message-ID: Date: Tuesday, November 9, 2004 @ 18:00:55 Author: werner Path: /cvs/gnupg/libgcrypt/src Modified: ChangeLog gcrypt.h Removed 3 trailing commas from enums. Reported by Heiko Stamer. -----------+ ChangeLog | 5 +++++ gcrypt.h | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) From cvs at cvs.gnupg.org Tue Nov 9 18:02:22 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Tue Nov 9 18:02:25 2004 Subject: LIBGCRYPT-1-2-BRANCH libgcrypt/src (ChangeLog gcrypt.h) Message-ID: Date: Tuesday, November 9, 2004 @ 18:07:37 Author: wk Path: /cvs/libgcrypt/libgcrypt/src Tag: LIBGCRYPT-1-2-BRANCH Modified: ChangeLog gcrypt.h Removed 3 trailing commas from enums. Reported by Heiko Stamer. -----------+ ChangeLog | 5 +++++ gcrypt.h | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) Index: libgcrypt/src/ChangeLog diff -u libgcrypt/src/ChangeLog:1.151.2.6 libgcrypt/src/ChangeLog:1.151.2.7 --- libgcrypt/src/ChangeLog:1.151.2.6 Tue Sep 21 12:19:11 2004 +++ libgcrypt/src/ChangeLog Tue Nov 9 18:07:37 2004 @@ -1,3 +1,8 @@ +2004-11-09 Werner Koch + + * gcrypt.h: Removed 3 trailing commas from enums. Reported by + Heiko Stamer. + 2004-09-21 Werner Koch * sexp.c (sexp_sscan): Removed c++ style commets. Noted by Yoann Index: libgcrypt/src/gcrypt.h diff -u libgcrypt/src/gcrypt.h:1.125.2.1 libgcrypt/src/gcrypt.h:1.125.2.2 --- libgcrypt/src/gcrypt.h:1.125.2.1 Tue Aug 10 18:34:49 2004 +++ libgcrypt/src/gcrypt.h Tue Nov 9 18:07:37 2004 @@ -47,7 +47,7 @@ autoconf (using the AM_PATH_GCRYPT macro) check that this header matches the installed library. Note: Do not edit the next line as configure may fix the string here. */ -#define GCRYPT_VERSION "1.2.0" +#define GCRYPT_VERSION "1.2.1-cvs" /* Internal: We can't use the convenience macros for the multi precision integer functions when building this library. */ @@ -726,7 +726,7 @@ GCRY_CIPHER_SERPENT192 = 305, GCRY_CIPHER_SERPENT256 = 306, GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */ - GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */ + GCRY_CIPHER_RFC2268_128 = 308 /* Ron's Cipher 2 (128 bit). */ }; /* The Rijndael algorithm is basically AES, so provide some macros. */ @@ -944,7 +944,7 @@ GCRY_AC_RSA = 1, GCRY_AC_DSA = 17, GCRY_AC_ELG = 20, - GCRY_AC_ELG_E = 16, + GCRY_AC_ELG_E = 16 } gcry_ac_id_t; @@ -952,7 +952,7 @@ typedef enum gcry_ac_key_type { GCRY_AC_KEY_SECRET, - GCRY_AC_KEY_PUBLIC, + GCRY_AC_KEY_PUBLIC } gcry_ac_key_type_t; From cvs at cvs.gnupg.org Tue Nov 9 18:52:21 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Tue Nov 9 18:52:26 2004 Subject: libgcrypt/src (ChangeLog gcrypt.h) Message-ID: Date: Tuesday, November 9, 2004 @ 18:57:38 Author: wk Path: /cvs/libgcrypt/libgcrypt/src Modified: ChangeLog gcrypt.h Removed trailing commas. This time comitting to the right repository. -----------+ ChangeLog | 5 +++++ gcrypt.h | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) Index: libgcrypt/src/ChangeLog diff -u libgcrypt/src/ChangeLog:1.157 libgcrypt/src/ChangeLog:1.158 --- libgcrypt/src/ChangeLog:1.157 Tue Oct 12 10:55:42 2004 +++ libgcrypt/src/ChangeLog Tue Nov 9 18:57:38 2004 @@ -1,3 +1,8 @@ +2004-11-09 Werner Koch + + * gcrypt.h: Removed 3 trailing commas from enums. Noted by Heiko + Stamer. + 2004-09-21 Werner Koch * sexp.c (sexp_sscan): Removed C++ style comments. Noted by Yoann Index: libgcrypt/src/gcrypt.h diff -u libgcrypt/src/gcrypt.h:1.127 libgcrypt/src/gcrypt.h:1.128 --- libgcrypt/src/gcrypt.h:1.127 Tue Aug 10 18:33:47 2004 +++ libgcrypt/src/gcrypt.h Tue Nov 9 18:57:38 2004 @@ -727,7 +727,7 @@ GCRY_CIPHER_SERPENT192 = 305, GCRY_CIPHER_SERPENT256 = 306, GCRY_CIPHER_RFC2268_40 = 307, /* Ron's Cipher 2 (40 bit). */ - GCRY_CIPHER_RFC2268_128 = 308, /* Ron's Cipher 2 (128 bit). */ + GCRY_CIPHER_RFC2268_128 = 308 /* Ron's Cipher 2 (128 bit). */ }; /* The Rijndael algorithm is basically AES, so provide some macros. */ @@ -945,7 +945,7 @@ GCRY_AC_RSA = 1, GCRY_AC_DSA = 17, GCRY_AC_ELG = 20, - GCRY_AC_ELG_E = 16, + GCRY_AC_ELG_E = 16 } gcry_ac_id_t; @@ -953,7 +953,7 @@ typedef enum gcry_ac_key_type { GCRY_AC_KEY_SECRET, - GCRY_AC_KEY_PUBLIC, + GCRY_AC_KEY_PUBLIC } gcry_ac_key_type_t; From cvs at cvs.gnupg.org Tue Nov 16 20:17:03 2004 From: cvs at cvs.gnupg.org (cvs user werner) Date: Tue Nov 16 20:17:10 2004 Subject: libassuan/src (4 files) Message-ID: Date: Tuesday, November 16, 2004 @ 20:17:03 Author: werner Path: /cvs/gnupg/libassuan/src Modified: ChangeLog assuan-domain-connect.c assuan-pipe-connect.c assuan-socket-connect.c * assuan-socket-connect.c (LOG): Fixed macro to print not only the prefix. * assuan-domain-connect.c, assuan-socket-connect.c (LOG): Ditto. -------------------------+ ChangeLog | 6 ++++++ assuan-domain-connect.c | 6 +++--- assuan-pipe-connect.c | 6 +++--- assuan-socket-connect.c | 7 +++---- 4 files changed, 15 insertions(+), 10 deletions(-) From cvs at cvs.gnupg.org Wed Nov 17 05:45:50 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Wed Nov 17 05:45:53 2004 Subject: STABLE-BRANCH-1-2 gnupg (ChangeLog acinclude.m4) Message-ID: Date: Wednesday, November 17, 2004 @ 05:51:49 Author: dshaw Path: /cvs/gnupg/gnupg Tag: STABLE-BRANCH-1-2 Modified: ChangeLog acinclude.m4 * acinclude.m4: aclocal 1.9 wants quoting on AC_DEFUN arguments. --------------+ ChangeLog | 7 ++++++- acinclude.m4 | 19 +++++++++---------- 2 files changed, 15 insertions(+), 11 deletions(-) Index: gnupg/ChangeLog diff -u gnupg/ChangeLog:1.118.2.84 gnupg/ChangeLog:1.118.2.85 --- gnupg/ChangeLog:1.118.2.84 Wed Aug 25 16:43:15 2004 +++ gnupg/ChangeLog Wed Nov 17 05:51:49 2004 @@ -1,3 +1,7 @@ +2004-11-16 David Shaw + + * acinclude.m4: aclocal 1.9 wants quoting on AC_DEFUN arguments. + 2004-08-25 Werner Koch Released 1.2.6. @@ -1439,7 +1443,8 @@ * Makefile.am: Likewise - Copyright 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2002, 2003, + 2004 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Index: gnupg/acinclude.m4 diff -u gnupg/acinclude.m4:1.34.2.6 gnupg/acinclude.m4:1.34.2.7 --- gnupg/acinclude.m4:1.34.2.6 Thu May 20 05:12:32 2004 +++ gnupg/acinclude.m4 Wed Nov 17 05:51:49 2004 @@ -28,7 +28,7 @@ dnl GNUPG_CHECK_TYPEDEF(TYPE, HAVE_NAME) dnl Check whether a typedef exists and create a #define $2 if it exists dnl -AC_DEFUN(GNUPG_CHECK_TYPEDEF, +AC_DEFUN([GNUPG_CHECK_TYPEDEF], [ AC_MSG_CHECKING(for $1 typedef) AC_CACHE_VAL(gnupg_cv_typedef_$1, [AC_TRY_COMPILE([#define _GNU_SOURCE 1 @@ -46,7 +46,7 @@ dnl GNUPG_CHECK_GNUMAKE dnl -AC_DEFUN(GNUPG_CHECK_GNUMAKE, +AC_DEFUN([GNUPG_CHECK_GNUMAKE], [ if ${MAKE-make} --version 2>/dev/null | grep '^GNU ' >/dev/null 2>&1; then : @@ -64,7 +64,7 @@ dnl GNUPG_CHECK_FAQPROG dnl -AC_DEFUN(GNUPG_CHECK_FAQPROG, +AC_DEFUN([GNUPG_CHECK_FAQPROG], [ AC_MSG_CHECKING(for faqprog.pl) if faqprog.pl -V 2>/dev/null | grep '^faqprog.pl ' >/dev/null 2>&1; then working_faqprog=yes @@ -91,7 +91,7 @@ dnl GNUPG_CHECK_DOCBOOK_TO_TEXI dnl -AC_DEFUN(GNUPG_CHECK_DOCBOOK_TO_TEXI, +AC_DEFUN([GNUPG_CHECK_DOCBOOK_TO_TEXI], [ AC_CHECK_PROG(DOCBOOK_TO_TEXI, docbook2texi, yes, no) AC_MSG_CHECKING(for sgml to texi tools) @@ -459,7 +459,7 @@ ################################################################ # GNUPG_PROG_NM - find the path to a BSD-compatible name lister -AC_DEFUN(GNUPG_PROG_NM, +AC_DEFUN([GNUPG_PROG_NM], [AC_MSG_CHECKING([for BSD-compatible nm]) AC_CACHE_VAL(ac_cv_path_NM, [if test -n "$NM"; then @@ -493,7 +493,7 @@ # GNUPG_SYS_NM_PARSE - Check for command ro grab the raw symbol name followed # by C symbol name from nm. -AC_DEFUN(GNUPG_SYS_NM_PARSE, +AC_DEFUN([GNUPG_SYS_NM_PARSE], [AC_REQUIRE([AC_CANONICAL_HOST])dnl AC_REQUIRE([GNUPG_PROG_NM])dnl # Check for command to grab the raw symbol name followed by C symbol from nm. @@ -660,14 +660,14 @@ ]) # GNUPG_SYS_LIBTOOL_CYGWIN32 - find tools needed on cygwin32 -AC_DEFUN(GNUPG_SYS_LIBTOOL_CYGWIN32, +AC_DEFUN([GNUPG_SYS_LIBTOOL_CYGWIN32], [AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(AS, as, false) ]) # GNUPG_SYS_SYMBOL_UNDERSCORE - does the compiler prefix global symbols # with an underscore? -AC_DEFUN(GNUPG_SYS_SYMBOL_UNDERSCORE, +AC_DEFUN([GNUPG_SYS_SYMBOL_UNDERSCORE], [tmp_do_check="no" case "${target}" in i386-emx-os2 | i[3456]86-pc-os2*emx | i386-pc-msdosdjgpp) @@ -728,7 +728,7 @@ dnl Stolen from gcc dnl Define MKDIR_TAKES_ONE_ARG if mkdir accepts only one argument instead dnl of the usual 2. -AC_DEFUN(GNUPG_FUNC_MKDIR_TAKES_ONE_ARG, +AC_DEFUN([GNUPG_FUNC_MKDIR_TAKES_ONE_ARG], [AC_CHECK_HEADERS(sys/stat.h unistd.h direct.h) AC_CACHE_CHECK([if mkdir takes one argument], gnupg_cv_mkdir_takes_one_arg, [AC_TRY_COMPILE([ @@ -748,4 +748,3 @@ [Defined if mkdir() does not take permission flags]) fi ]) - From cvs at cvs.gnupg.org Tue Nov 16 19:18:40 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Wed Nov 17 13:48:24 2004 Subject: dirmngr (36 files) Message-ID: Date: Tuesday, November 16, 2004 @ 19:24:36 Author: wk Path: /cvs/dirmngr/dirmngr Added: compile src/certcache.c src/certcache.h src/dirmngr-client.c src/dirmngr_ldap.c src/i18n.h src/maperror.c src/no-libgcrypt.c src/no-libgcrypt.h src/util.h src/validate.c src/validate.h tests/show-multi.c Modified: ChangeLog NEWS TODO acinclude.m4 configure.ac doc/dirmngr.texi jnlib/ChangeLog jnlib/logging.c po/POTFILES.in src/ChangeLog src/Makefile.am src/crlcache.c src/crlcache.h src/crlfetch.c src/crlfetch.h src/dirmngr.c src/dirmngr.h src/http.c src/ldap.c src/misc.c src/misc.h src/server.c tests/Makefile.am Started a partial rewrite with the goal to optionally run it as a system daemon. Currently builds but is broken in some important parts. ----------------------+ ChangeLog | 13 NEWS | 9 TODO | 9 acinclude.m4 | 41 + compile | 107 +++ configure.ac | 49 + doc/dirmngr.texi | 185 ++++++ jnlib/ChangeLog | 8 jnlib/logging.c | 306 ++++++---- po/POTFILES.in | 2 src/ChangeLog | 122 ++++ src/Makefile.am | 35 - src/certcache.c | 313 ++++++++++ src/certcache.h | 45 + src/crlcache.c | 112 ++- src/crlcache.h | 19 src/crlfetch.c | 192 ++---- src/crlfetch.h | 27 src/dirmngr-client.c | 474 +++++++++++++++ src/dirmngr.c | 510 +++++++++++++++-- src/dirmngr.h | 62 -- src/dirmngr_ldap.c | 497 ++++++++++++++++ src/http.c | 2 src/i18n.h | 48 + src/ldap.c | 1456 ++++++++++++++++++++++++++----------------------- src/maperror.c | 74 ++ src/misc.c | 103 +++ src/misc.h | 19 src/no-libgcrypt.c | 107 +++ src/no-libgcrypt.h | 33 + src/server.c | 496 ++++++++++++---- src/util.h | 57 + src/validate.c | 781 ++++++++++++++++++++++++++ src/validate.h | 37 + tests/Makefile.am | 5 tests/show-multi.c | 170 +++++ 36 files changed, 5313 insertions(+), 1212 deletions(-) Index: dirmngr/ChangeLog diff -u dirmngr/ChangeLog:1.75 dirmngr/ChangeLog:1.76 --- dirmngr/ChangeLog:1.75 Mon Oct 4 13:50:51 2004 +++ dirmngr/ChangeLog Tue Nov 16 19:24:36 2004 @@ -1,3 +1,14 @@ +2004-11-15 Werner Koch + + * tests/show-multi.c: New. + * tests/Makefile.am (noinst_PROGRAMS): Added. + +2004-11-08 Werner Koch + + * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): New. Taken from gnupg. + * configure.ac: Check for GNU Pth. + * doc/dirmngr.texi (Dirmngr Client): Added. + 2004-10-04 Werner Koch * src/dirmngr.c: Changed an help entry description. @@ -564,7 +575,7 @@ * src/ldap.c (url_fetch_ldap()): try other default servers when an url with hostname failed * AUTHORS: added Steffen and Werner - * THANKS: Thanked people in the ChangeLog and the Ägypten-Team + * THANKS: Thanked people in the ChangeLog and the Ägypten-Team 2003-06-16 Steffen Hansen Index: dirmngr/NEWS diff -u dirmngr/NEWS:1.26 dirmngr/NEWS:1.27 --- dirmngr/NEWS:1.26 Tue Sep 28 15:17:24 2004 +++ dirmngr/NEWS Tue Nov 16 19:24:36 2004 @@ -1,6 +1,11 @@ -Noteworthy changes in version 0.5.7 +Noteworthy changes in version 0.9.0 ------------------------------------------------ + WARNING: CURRENTLY UNDER HEAVY RECONSTRUCTION. Many things might + not yet work again. + + * New tool dirmngr-client. + Noteworthy changes in version 0.5.6 (2004-09-28) ------------------------------------------------ @@ -79,7 +84,7 @@ * The default home directory is now .gnupg - Copyright 2003 g10 Code GmbH + Copyright 2003, 2004 g10 Code GmbH This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Index: dirmngr/TODO diff -u dirmngr/TODO:1.13 dirmngr/TODO:1.14 --- dirmngr/TODO:1.13 Wed Nov 3 18:48:03 2004 +++ dirmngr/TODO Tue Nov 16 19:24:36 2004 @@ -15,12 +15,15 @@ This is the server where a baseDN has been given and that baseDN is contained in the search pattern. -* Properly parse LDAP attributes from the URL - and remove the bad hack in crl_fetch. +* Properly parse LDAP attributes from the URL and remove the bad hack in crl_fetch. * Add --honor-http-proxy -* Write a utility to use Dirmngr from a script or by other programs. +* Properly use locks in crlcache.c +* truncated + Need to updated the code in ldap.c + +* In daemon mode we should put the cache files into /var/cache/dirmngr Index: dirmngr/acinclude.m4 diff -u dirmngr/acinclude.m4:1.3 dirmngr/acinclude.m4:1.4 --- dirmngr/acinclude.m4:1.3 Thu Nov 13 17:19:57 2003 +++ dirmngr/acinclude.m4 Tue Nov 16 19:24:36 2004 @@ -35,4 +35,45 @@ fi ]) +# GNUPG_PTH_VERSION_CHECK(REQUIRED) +# +# If the version is sufficient, HAVE_PTH will be set to yes. +# +# Taken form the m4 macros which come with Pth +AC_DEFUN(GNUPG_PTH_VERSION_CHECK, + [ + _pth_version=`$PTH_CONFIG --version | awk 'NR==1 {print [$]3}'` + _req_version="ifelse([$1],,1.2.0,$1)" + for _var in _pth_version _req_version; do + eval "_val=\"\$${_var}\"" + _major=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\1/'` + _minor=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\2/'` + _rtype=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\3/'` + _micro=`echo $_val | sed 's/\([[0-9]]*\)\.\([[0-9]]*\)\([[ab.]]\)\([[0-9]]*\)/\4/'` + case $_rtype in + "a" ) _rtype=0 ;; + "b" ) _rtype=1 ;; + "." ) _rtype=2 ;; + esac + _hex=`echo dummy | awk '{ printf("%d%02d%1d%02d", major, minor, rtype, micro); }' \ + "major=$_major" "minor=$_minor" "rtype=$_rtype" "micro=$_micro"` + eval "${_var}_hex=\"\$_hex\"" + done + have_pth=no + if test ".$_pth_version_hex" != .; then + if test ".$_req_version_hex" != .; then + if test $_pth_version_hex -ge $_req_version_hex; then + have_pth=yes + fi + fi + fi + if test $have_pth = no; then + AC_MSG_WARN([[ +*** +*** Found Pth version $_pth_version, but require at least +*** version $_req_version. Please upgrade Pth first. +***]]) + fi + ]) + Index: dirmngr/compile diff -u /dev/null dirmngr/compile:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/compile Tue Nov 16 19:24:36 2004 @@ -0,0 +1,107 @@ +#! /bin/sh + +# Wrapper for compilers which do not understand `-c -o'. + +# Copyright 1999, 2000 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program 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, or (at your option) +# any later version. +# +# This program 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. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Usage: +# compile PROGRAM [ARGS]... +# `-o FOO.o' is removed from the args passed to the actual compile. + +# Usage statement added by Billy Biggs . +if [ -z $1 ]; then + echo "Wrapper for compilers which do not understand '-c -o'." + echo "usage: compile PROGRAM [ARGS]..." + echo "'-o FOO.o' is removed from the args passed to the actual compile." + exit 1 +fi + +prog=$1 +shift + +ofile= +cfile= +args= +while test $# -gt 0; do + case "$1" in + -o) + # configure might choose to run compile as `compile cc -o foo foo.c'. + # So we do something ugly here. + ofile=$2 + shift + case "$ofile" in + *.o | *.obj) + ;; + *) + args="$args -o $ofile" + ofile= + ;; + esac + ;; + *.c) + cfile=$1 + args="$args $1" + ;; + *) + args="$args $1" + ;; + esac + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no `-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # `.c' file was seen then we are probably linking. That is also + # ok. + exec "$prog" $args +fi + +# Name of file we expect compiler to create. +cofile=`echo $cfile | sed -e 's|^.*/||' -e 's/\.c$/.o/'` + +# Create the lock directory. +# Note: use `[/.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo $cofile | sed -e 's|[/.-]|_|g'`.d +while true; do + if mkdir $lockdir > /dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir $lockdir; exit 1" 1 2 15 + +# Run the compile. +"$prog" $args +status=$? + +if test -f "$cofile"; then + mv "$cofile" "$ofile" +fi + +rmdir $lockdir +exit $status Index: dirmngr/configure.ac diff -u dirmngr/configure.ac:1.60 dirmngr/configure.ac:1.61 --- dirmngr/configure.ac:1.60 Tue Sep 28 15:17:24 2004 +++ dirmngr/configure.ac Tue Nov 16 19:24:36 2004 @@ -1,5 +1,5 @@ # configure.ac - for DirMngr -# Copyright (C) 2002 Klarälvdalens Datakonsult AB +# Copyright (C) 2002 Klarälvdalens Datakonsult AB # Copyright (C) 2003, 2004 g10 Code GmbH # # This file is part of DirMngr. @@ -19,10 +19,10 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # Process this file with autoconf to produce a configure script. -AC_PREREQ(2.57) -min_automake_version="1.7.6" +AC_PREREQ(2.59) +min_automake_version="1.7.9" -AC_INIT(dirmngr, 0.5.7-cvs, gpa-dev@gnupg.org) +AC_INIT(dirmngr, 0.9.0-cvs, gpa-dev@gnupg.org) NEED_GPG_ERROR_VERSION=0.7 @@ -164,12 +164,49 @@ AM_PATH_KSBA("$NEED_KSBA_VERSION",have_ksba=yes,have_ksba=no) +# +# Check whether the GNU Pth library is available +# +AC_ARG_WITH(pth-prefix, + AC_HELP_STRING([--with-pth-prefix=PFX], + [prefix where GNU Pth is installed (optional)]), + pth_config_prefix="$withval", pth_config_prefix="") +if test x$pth_config_prefix != x ; then + PTH_CONFIG="$pth_config_prefix/bin/pth-config" +fi +AC_PATH_PROG(PTH_CONFIG, pth-config, no) +if test "$PTH_CONFIG" = "no"; then + AC_MSG_WARN([[ +*** +*** GNU Portable Threads Library not found. +*** The --daemon mode won't work. +*** Download GNU Pth from ftp://ftp.gnu.org/gnu/pth/ +*** On a Debian GNU/Linux system you might want to try +*** apt-get install libpth-dev +***]]) +else + GNUPG_PTH_VERSION_CHECK(1.3.7) + if test $have_pth = yes; then + PTH_CFLAGS=`$PTH_CONFIG --cflags` + PTH_LIBS=`$PTH_CONFIG --ldflags` + PTH_LIBS="$PTH_LIBS `$PTH_CONFIG --libs`" + AC_DEFINE(USE_GNU_PTH, 1, + [Defined if the GNU Portable Thread Library should be used]) + fi +fi +AC_SUBST(PTH_CFLAGS) +AC_SUBST(PTH_LIBS) - +# +# Do we need the resolver lib +# AC_HAVE_LIBRARY(resolv) -### OpenLDAP libraries/includes + +# +# OpenLDAP libraries/includes +# AC_DEFUN(AC_FIND_FILE, [ $3=NO Index: dirmngr/doc/dirmngr.texi diff -u dirmngr/doc/dirmngr.texi:1.13 dirmngr/doc/dirmngr.texi:1.14 --- dirmngr/doc/dirmngr.texi:1.13 Wed Apr 28 11:00:54 2004 +++ dirmngr/doc/dirmngr.texi Tue Nov 16 19:24:35 2004 @@ -65,7 +65,8 @@ @ifnottex @dircategory GNU Utilities @direntry -* dirmngr: (gnupg). X.509 CRL and OCSP server. +* dirmngr: (gnupg). X.509 CRL and OCSP server. +* dirmngr-client: (gnupg). X.509 CRL and OCSP client. @end direntry This file documents the use of dirmngr. @@ -116,13 +117,14 @@ * Dirmngr Options:: List of all options. * Dirmngr Examples:: Some usage examples. * Dirmngr Protocol:: The protocol dirmngr uses. +* Dirmngr Client:: How to use the Dirmngr client tool. * Copying:: GNU General Public License says how you can copy and share 'Dirmngr'. * Option Index:: Index to command line options. * Index:: Index of concepts and symbol names. -* History:: Change hostory of this document. +* History:: Change history of this document. @end menu @c man begin COMMANDS @@ -149,6 +151,11 @@ Run in server mode and wait for commands on the @code{stdin}. The default mode is to create a socket and listen for commands there. +@item --daemon +@opindex daemon +Run in background daemon mode and listen for commands on a socket. +Note that this also changes the default home directory. + @item --list-crls @opindex list-crls List the contents of the CRL cache on @code{stdout}. This is probably @@ -191,7 +198,25 @@ @item --options @var{file} @opindex options Reads configuration from @var{file} instead of from the default -per-user configuration file. +per-user configuration file. The default configuration file is named +@file{gpgsm.conf} and expected in the home directory. + +@item --homedir @var{dir} +@opindex options +Set the name of the home directory to @var{dir}. This option is only +effective when used on the command line. The default depends on the +running mode: + + @table @asis + @item With @code{--daemon} given on the commandline + the directory named @file{/etc/dirmngr}. + @item Without @code{--daemon} given on the commandline +the directory named @file{.gnupg} directly below the home directory +of the user unless the environment variable @code{GNUPGHOME} has been set +in which case its value will be used. + @end table + + @item -v @item --verbose @@ -201,6 +226,8 @@ You can increase the verbosity by giving several verbose commands to @sc{dirmngr}, such as @samp{-vv}. + + @item --log-file @var{file} @opindex log-file Append all logging output to @var{file}. This is very helpful in @@ -350,7 +377,9 @@ @menu * Dirmngr LOOKUP:: Look up a certificate via LDAP -* Dirmngr ISVALID:: Validate a certificate against a CRL. +* Dirmngr ISVALID:: Validate a certificate using a CRL or OCSP. +* Dirmngr CHECKCRL:: Validate a certificate using a CRL. +* Dirmngr CHECKOCSP:: Validate a certificate using OCSP. @end menu @node Dirmngr LOOKUP @@ -383,7 +412,7 @@ @node Dirmngr ISVALID -@section Validate a certificate against the CRL +@section Validate a certificate using a CRL or OCSP Check whether the certificate described by the certificate_ID (which is a fingerprint) has been revoked. Due to caching, the Dirmngr is @@ -423,6 +452,152 @@ whatever reason. +@node Dirmngr CHECKCRL +@section Validate a certificate using a CRL + +Check whether the certificate with FINGERPRINT (SHA-1 hash of the +entire X.509 certificate blob) is valid or not by consulting the CRL +responsible for this certificate. If the fingerprint has not been +given or the certificate is not know, the function inquires the +certificate using: + +@example + S: INQUIRE TARGETCERT + C: D + C: END +@end example + +Thus the caller is expected to return the certificate for the request +(which should match FINGERPRINT) as a binary blob. Processing then +takes place without further interaction; in particular dirmngr tries +to locate other required certificate by its own mechanism which +includes a local certificate store as well as a list of trusted root +certificates. + +@noindent +The return code is 0 for success; i.e. the certificate has not been +revoked or one of the usual error codes from libgpg-error. + +@node Dirmngr CHECKOCSP +@section Validate a certificate using OCSP + + Check whether the certificate with FINGERPRINT (SHA-1 hash of the + entire X.509 certificate blob) is valid or not by consulting the + appropiateOCSP responder. If the fingerprint has not + been given or the certificate is not know, the function + inquires the certificate using: + +@example + S: INQUIRE TARGETCERT + C: D + C: END +@end example + + Thus the caller is expected to return the certificate for the + request (which should match FINGERPRINT) as a binary blob. + Processing then takes place without further interaction; in + particular dirmngr tries to locate other required certificate by + its own mechanism which includes a local certificate store as well + as a list of trusted root certificates. + +@noindent +The return code is 0 for success; i.e. the certificate has not been +revoked or one of the usual error codes from libgpg-error. + + +@c ------------------------------------------- +@c Dirmngr Client +@c ------------------------------------------ + +@node Dirmngr Client +@chapter The Client Tool + +The @command{dirmngr-client} is a simple tool to contact a running +dirmngr and test whether a certificate has been revoked --- either by +being listed in the corresponding CRL or by running the OCSP protocol. +If no dirmngr is running, a new instances will be started but this is +in general not a good idea due tom the huge performace overhead. + +@noindent +The usual way to run this tool is either: + +@example +dirmngr-client @var{acert} +@end example + +@noindent +or + +@example +dirmngr-client <@var{acert} +@end example + +Where @var{acert} is one DER encoded (binary) X.509 certificates to be +tested. The return value of this command is + +@table @code + +@item 0 +The certificate under question is valid; i.e. there is a valid CRL +available and it is not listed tehre or teh OCSP request returned that +that certificate is valid. + +@item 1 +The certificate has been revoked + +@item 2 (and other values) +There was a problem checking the revocation state of the certificate. +A message to stderr has given more detailed information. Most likely +this is due to a missing or tool old CRL or a network problem. + +@end table + +@noindent +@command{dirmngr-client} may be called with the following options: + + +@table @gnupgtabopt +@item --version +@opindex version +Print the program version and licensing information. Note that you cannot +abbreviate this command. + +@item --help, -h +@opindex help +Print a usage message summarizing the most useful command-line options. +Note that you cannot abbreviate this command. + +@item --quiet, -q +@opindex quiet +Make the output extra brief by suppressing any informational messages. + +@item -v +@item --verbose +@opindex v +@opindex verbose +Outputs additional information while running. +You can increase the verbosity by giving several +verbose commands to @sc{dirmngr}, such as @samp{-vv}. + +@item --ocsp +@opindex ocsp +Do the check using the COSP protocol and ignore any CRLs. + +@item --ping +@opindex ping +Check whether the dirmngr daemon is up and running. + +@item --use-daemon +@opindex use-daemon +Always try to use a running background daemon. The default is to try +to start a dirmngr if a connecting a daemon fails. This option is +also implicitly use with @code{--ping}. + + +@end table + + + @include gpl.texi @c --------------------------------------------------------------------- Index: dirmngr/jnlib/ChangeLog diff -u dirmngr/jnlib/ChangeLog:1.8 dirmngr/jnlib/ChangeLog:1.9 --- dirmngr/jnlib/ChangeLog:1.8 Tue Sep 28 14:27:26 2004 +++ dirmngr/jnlib/ChangeLog Tue Nov 16 19:24:35 2004 @@ -1,3 +1,11 @@ +2004-10-21 Werner Koch + + * logging.c (do_logv): Use set_log_stream to setup a default. + (log_set_file): Factored code out to .. + (set_file_fd): .. New function to allow using a file descriptor. + (log_set_fd): Make use of new fucntion. + (fun_writer): Reworked. + 2004-09-28 Werner Koch * stringhelp.c (print_sanitized_utf8_string): Actually implement Index: dirmngr/jnlib/logging.c diff -u dirmngr/jnlib/logging.c:1.7 dirmngr/jnlib/logging.c:1.8 --- dirmngr/jnlib/logging.c:1.7 Tue Sep 28 14:27:26 2004 +++ dirmngr/jnlib/logging.c Tue Nov 16 19:24:35 2004 @@ -37,14 +37,20 @@ #include #include #include +#include +#include #ifdef __MINGW32__ # include #endif + #define JNLIB_NEED_LOG_LOGV 1 #include "libjnlib-config.h" #include "logging.h" +#if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) +#define USE_FUNWRITER 1 +#endif static FILE *logstream; static int log_socket = -1; @@ -94,10 +100,12 @@ /* The follwing 3 functions are used by funopen to write logs to a socket. */ -#if defined (HAVE_FOPENCOOKIE) || defined (HAVE_FUNOPEN) +#ifdef USE_FUNWRITER struct fun_cookie_s { int fd; int quiet; + int want_socket; + int is_socket; char name[1]; }; @@ -135,64 +143,78 @@ 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). */ - if (cookie->fd == -1) + if (cookie->want_socket && cookie->fd == -1) { /* Not yet open or meanwhile closed due to an error. */ - struct sockaddr_un addr; - size_t addrlen; - + cookie->is_socket = 0; cookie->fd = socket (PF_LOCAL, SOCK_STREAM, 0); if (cookie->fd == -1) { if (!cookie->quiet && !running_detached) fprintf (stderr, "failed to create socket for logging: %s\n", strerror(errno)); - goto failure; } - log_socket = cookie->fd; + 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 = (offsetof (struct sockaddr_un, sun_path) + + strlen (addr.sun_path) + 1); - 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 = (offsetof (struct sockaddr_un, sun_path) - + strlen (addr.sun_path) + 1); + if (connect (cookie->fd, (struct sockaddr *) &addr, addrlen) == -1) + { + if (!cookie->quiet && !running_detached) + fprintf (stderr, "can't connect to `%s': %s\n", + cookie->name, strerror(errno)); + close (cookie->fd); + cookie->fd = -1; + } + } - if (connect (cookie->fd, (struct sockaddr *) &addr, addrlen) == -1) + if (cookie->fd == -1) { - log_socket = -1; - if (!cookie->quiet && !running_detached) - fprintf (stderr, "can't connect to `%s': %s\n", - cookie->name, strerror(errno)); - close (cookie->fd); - cookie->fd = -1; - goto failure; + if (!running_detached) + { + if (!cookie->quiet) + { + fputs ("switching logging to stderr\n", stderr); + cookie->quiet = 1; + } + cookie->fd = fileno (stderr); + } + } + else /* Connection has been established. */ + { + cookie->quiet = 0; + cookie->is_socket = 1; } - /* Connection established. */ - cookie->quiet = 0; } - - if (!writen (cookie->fd, buffer, size)) - return size; /* Okay. */ - log_socket = -1; - if (!running_detached) - fprintf (stderr, "error writing to `%s': %s\n", - cookie->name, strerror(errno)); - close (cookie->fd); - cookie->fd = -1; + log_socket = cookie->fd; + if (cookie->fd != -1 && !writen (cookie->fd, buffer, size)) + return size; /* Okay. */ - failure: - if (!running_detached) + if (!running_detached && cookie->fd != -1) { - if (!cookie->quiet) - { - fputs ("switching logging to stderr\n", stderr); - cookie->quiet = 1; - } - - fwrite (buffer, size, 1, stderr); + if (*cookie->name) + fprintf (stderr, "error writing to `%s': %s\n", + cookie->name, strerror(errno)); + else + fprintf (stderr, "error writing to file descriptor %d: %s\n", + cookie->fd, strerror(errno)); + } + if (cookie->is_socket && cookie->fd != -1) + { + close (cookie->fd); + cookie->fd = -1; + log_socket = -1; } + return size; } @@ -204,113 +226,151 @@ if (cookie->fd != -1) close (cookie->fd); jnlib_free (cookie); + log_socket = -1; return 0; } -#endif /* HAVE_FOPENCOOKIE || HAVE_FUNOPEN */ +#endif /*USE_FUNWRITER*/ - -/* Set the file to write log to. The special names NULL and "-" may - be used to select stderr and names formatted like - "socket:///home/foo/mylogs" may be used to write the logging to the - socket "/home/foo/mylogs". If the connection to the socket fails - or a write error is detected, the function writes to stderr and - tries the next time again to connect the socket. - */ -void -log_set_file (const char *name) +/* Common function to either set the logging to a file or a file + descriptor. */ +static void +set_file_fd (const char *name, int fd) { FILE *fp; + int want_socket; +#ifdef USE_FUNWRITER + struct fun_cookie_s *cookie; +#endif - force_prefixes = 0; - if (name && !strncmp (name, "socket://", 9) && name[9]) + if (name && !strcmp (name, "-")) { -#if defined (HAVE_FOPENCOOKIE)|| defined (HAVE_FUNOPEN) - struct fun_cookie_s *cookie; - - cookie = jnlib_xmalloc (sizeof *cookie + strlen (name+9)); - cookie->fd = -1; - cookie->quiet = 0; - strcpy (cookie->name, name+9); - -#ifdef HAVE_FOPENCOOKIE - { - cookie_io_functions_t io = { NULL }; - io.write = fun_writer; - io.close = fun_closer; + name = NULL; + fd = fileno (stderr); + } - fp = fopencookie (cookie, "w", io); - } -#else /*!HAVE_FOPENCOOKIE*/ - { - fp = funopen (cookie, NULL, fun_writer, NULL, fun_closer); - } -#endif /*!HAVE_FOPENCOOKIE*/ -#else /* Neither fopencookie nor funopen. */ - { - fprintf (stderr, "system does not support logging to a socket - " - "using stderr\n"); - fp = stderr; - } -#endif /* Neither fopencookie nor funopen. */ - - /* We always need to print the prefix and the pid, so that the - server reading the socket can do something meaningful. */ - force_prefixes = 1; - /* On success close the old logstream right now, so that we are - really sure it has been closed. */ - if (fp && logstream) - { - if (logstream != stderr && logstream != stdout) - fclose (logstream); - logstream = NULL; - } + if (name) + { + want_socket = (!strncmp (name, "socket://", 9) && name[9]); + if (want_socket) + name += 9; } else - fp = (name && strcmp(name,"-"))? fopen (name, "a") : stderr; - if (!fp) { - fprintf (stderr, "failed to open log file `%s': %s\n", - name? name:"[stderr]", strerror(errno)); - return; + want_socket = 0; } - setvbuf (fp, NULL, _IOLBF, 0); - - if (logstream && logstream != stderr && logstream != stdout) - fclose (logstream); - logstream = fp; - missing_lf = 0; -} +#ifdef USE_FUNWRITER + cookie = jnlib_xmalloc (sizeof *cookie + (name? strlen (name):0)); + strcpy (cookie->name, name? name:""); + cookie->quiet = 0; + cookie->is_socket = 0; + cookie->want_socket = want_socket; + if (!name) + cookie->fd = fd; + else if (want_socket) + cookie->fd = -1; + else + { + do + cookie->fd = open (name, O_WRONLY|O_APPEND|O_CREAT, + (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH)); + while (cookie->fd == -1 && errno == EINTR); + } + log_socket = cookie->fd; -void -log_set_fd (int fd) -{ - FILE *fp; +#ifdef HAVE_FOPENCOOKIE + { + cookie_io_functions_t io = { NULL }; + io.write = fun_writer; + io.close = fun_closer; + + fp = fopencookie (cookie, "w", io); + } +#else /*!HAVE_FOPENCOOKIE*/ + fp = funopen (cookie, NULL, fun_writer, NULL, fun_closer); +#endif /*!HAVE_FOPENCOOKIE*/ - force_prefixes = 0; - if (fd == 1) +#else /*!USE_FUNWRITER*/ + + /* The system does not feature custom streams. Thus fallback to + plain stdio. */ + if (want_socket) + { + fprintf (stderr, "system does not support logging to a socket - " + "using stderr\n"); + fp = stderr; + } + else if (name) + fp = fopen (name, "a"); + else if (fd == 1) fp = stdout; else if (fd == 2) fp = stderr; else fp = fdopen (fd, "a"); + + log_socket = -1; + +#endif /*!USE_FUNWRITER*/ + + /* On success close the old logstream right now, so that we are + really sure it has been closed. */ + if (fp && logstream) + { + if (logstream != stderr && logstream != stdout) + fclose (logstream); + logstream = NULL; + } + if (!fp) { - fprintf (stderr, "failed to fdopen log fd %d: %s\n", - fd, strerror(errno)); - return; + if (name) + fprintf (stderr, "failed to open log file `%s': %s\n", + name, strerror(errno)); + else + fprintf (stderr, "failed to fdopen file descriptor %d: %s\n", + fd, strerror(errno)); + /* We need to make sure that there is a log stream. We use stderr. */ + fp = stderr; } - setvbuf (fp, NULL, _IOLBF, 0); + else + setvbuf (fp, NULL, _IOLBF, 0); if (logstream && logstream != stderr && logstream != stdout) - fclose( logstream); + fclose (logstream); logstream = fp; + + /* We always need to print the prefix and the pid for socket mode, + so that the server reading the socket can do something + meaningful. */ + force_prefixes = want_socket; + missing_lf = 0; } +/* Set the file to write log to. The special names NULL and "-" may + be used to select stderr and names formatted like + "socket:///home/foo/mylogs" may be used to write the logging to the + socket "/home/foo/mylogs". If the connection to the socket fails + or a write error is detected, the function writes to stderr and + tries the next time again to connect the socket. + */ +void +log_set_file (const char *name) +{ + set_file_fd (name? name: "-", -1); +} + +void +log_set_fd (int fd) +{ + set_file_fd (NULL, fd); +} + + void log_set_prefix (const char *text, unsigned int flags) { @@ -351,9 +411,10 @@ int log_test_fd (int fd) { - if (fileno (logstream?logstream:stderr) == fd) + int tmp = fileno (logstream); + if ( tmp != -1 && tmp == fd) return 1; - if (log_socket == fd) + if (log_socket != -1 && log_socket == fd) return 1; return 0; } @@ -367,15 +428,20 @@ FILE * log_get_stream () { + /* FIXME: We should not return stderr here but initialize the log + stream properly. This might break more things than using stderr, + though */ return logstream?logstream:stderr; } - static void do_logv (int level, const char *fmt, va_list arg_ptr) { if (!logstream) - logstream = stderr; + { + log_set_file (NULL); /* Make sure a log stream has been set. */ + assert (logstream); + } if (missing_lf && level != JNLIB_LOG_CONT) putc('\n', logstream ); Index: dirmngr/po/POTFILES.in diff -u dirmngr/po/POTFILES.in:1.1 dirmngr/po/POTFILES.in:1.2 --- dirmngr/po/POTFILES.in:1.1 Fri Apr 2 20:05:20 2004 +++ dirmngr/po/POTFILES.in Tue Nov 16 19:24:35 2004 @@ -10,4 +10,6 @@ src/misc.c src/ocsp.c src/server.c +src/dirmngr-client.c +src/no-libgcrypt.c Index: dirmngr/src/ChangeLog diff -u /dev/null dirmngr/src/ChangeLog:1.21 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/ChangeLog Tue Nov 16 19:24:35 2004 @@ -0,0 +1,122 @@ +2004-11-16 Werner Koch + + * Makefile.am (AM_CPPFLAGS): Define DIRMNGR_SYSCONFDIR and + DIRMNGR_LIBEXECDIR. + + * misc.c (dump_isotime, dump_string, dump_cert): New. Taken from + gnupg 1.9. + (dump_serial): New. + +2004-11-15 Werner Koch + + * validate.c: New. Based on gnupg's certchain.c + + * ldap.c (get_cert_ldap): Removed. + (read_buffer): New. + (start_cert_fetch_ldap, fetch_next_cert_ldap) + (end_cert_fetch_ldap): Rewritten to make use of the ldap wrapper. + +2004-11-12 Werner Koch + + * http.c (insert_escapes): Print the percent sign too. + + * dirmngr-client.c (inq_cert): Ignore "SENDCERT" and + "SENDISSUERCERT". + + * server.c (do_get_cert_local): Limit the length of a retruned + certificate. Return NULL without an error if an empry value has + been received. + + * crlfetch.c (ca_cert_fetch): Use the ksba_reader_object. + (setup_funopen, fun_reader, fun_closer): Removed. + + * crlcache.c (get_issuer_cert): Adjust accordingly. + + * ldap.c (attr_fetch_ldap_internal, attr_fetch_fun_closer) + (attr_fetch_fun_reader, url_fetch_ldap_internal) + (get_attr_from_result_ldap): Removed. + (destroy_wrapper, print_log_line, ldap_wrapper_thread) + (ldap_wrapper_release_context, reader_callback, ldap_wrapper) + (run_ldap_wrapper): New. + (url_fetch_ldap): Make use of the new ldap wrapper and return a + ksba reader object instead of a stdio stream. + (attr_fetch_ldap): Ditto. + (make_url, escape4url): New. + +2004-11-11 Werner Koch + + * dirmngr.c (launch_ripper_thread): New. + (main): Start it wheere appropriate. Always ignore SIGPIPE. + (start_connection_thread): Maintain a connection count. + (handle_signal, handle_connections): Use it here instead of the + thread count. + + * crlcache.c (crl_cache_insert): Changed to use ksba reader + object. Changed all callers to pass this argument. + +2004-11-08 Werner Koch + + * dirmngr_ldap.c: New. + + * crlcache.c (crl_cache_init): Don't return a cache object but + keep it module local. We only need one. + (crl_cache_deinit): Don't take cache object but work on existing + one. + (get_current_cache): New. + (crl_cache_insert, crl_cache_list, crl_cache_load): Use the global + cache object and removed the cache arg. Changed all callers. + + * dirmngr-client.c: New option --ping. + + * dirmngr.c (main): New option --daemon. Initialize PTH. + (handle_connections, start_connection_thread): New. + (handle_signal): New. + (parse_rereadable_options): New. Changed main to make use of it. + (set_debug): Don't bail out on invalid debug levels. + (main): Init the crl_chache for server and daemon mode. + + * server.c (start_command_handler): New arg FD. Changed callers. + +2004-11-06 Werner Koch + + * server.c (map_assuan_err): Factored out to .. + * maperror.c: .. new file. + * util.h: Add prototype + +2004-11-05 Werner Koch + + * no-libgcrypt.c: New, used as helper for dirmngr-client which + does not need libgcrypt proper but jnlib references the memory + functions. Taken from gnupg 1.9.12. + + * dirmngr.h: Factored i18n and xmalloc code out to .. + * i18n.h, util.h: .. New. + + * dirmngr-client.c: New. Some code taken from gnupg 1.9.12. + * Makefile.am (bin_PROGRAMS) Add dirmngr-client. + +2004-11-04 Werner Koch + + * src/server.c (get_fingerprint_from_line, cmd_checkcrl) + (cmd_checkocsp): New. + (register_commands): Register new commands. + (inquire_cert_and_load_crl): Factored most code out to .. + (reload_crl): .. new function. + * src/certcache.h, src/certcache.c: New. + * src/Makefile.am (dirmngr_SOURCES): Add new files. + +2004-11-04 Werner Koch + + Please note that earlier entries are found in the top level + ChangeLog. + + + Copyright 2004 g10 Code GmbH + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Index: dirmngr/src/Makefile.am diff -u dirmngr/src/Makefile.am:1.17 dirmngr/src/Makefile.am:1.18 --- dirmngr/src/Makefile.am:1.17 Fri Apr 2 20:05:19 2004 +++ dirmngr/src/Makefile.am Tue Nov 16 19:24:35 2004 @@ -1,4 +1,6 @@ -# Copyright (C) 2002 Klarälvdalens Datakonsult AB +# Makefile.am - dirmngr +# Copyright (C) 2002 Klarälvdalens Datakonsult AB +# Copyright (C) 2004 g10 Code GmbH # # This file is part of DirMngr. # @@ -22,21 +24,38 @@ EXTRA_DIST = Manifest -bin_PROGRAMS = dirmngr +bin_PROGRAMS = dirmngr dirmngr-client +libexec_PROGRAMS = dirmngr_ldap AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" -AM_CFLAGS = -I$(top_srcdir)/jnlib @LIBGCRYPT_CFLAGS@ @LIBASSUAN_CFLAGS@ \ - @KSBA_CFLAGS@ @LDAP_INCS@ +AM_CPPFLAGS += -DDIRMNGR_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\"" +AM_CPPFLAGS += -DDIRMNGR_LIBEXECDIR="\"$(libexecdir)\"" -AM_LDFLAGS = @LDFLAGS@ +AM_CFLAGS = -I$(top_srcdir)/jnlib @LIBGCRYPT_CFLAGS@ @LIBASSUAN_CFLAGS@ \ + @KSBA_CFLAGS@ @GPG_ERROR_CFLAGS@ $(PTH_CFLAGS) noinst_HEADERS = dirmngr.h crlcache.h crlfetch.h error.h misc.h dirmngr_SOURCES = \ dirmngr.c dirmngr.h server.c crlcache.c crlfetch.c \ - cdb.h cdblib.c ldap.c http.c http.h misc.c ocsp.c ocsp.h + certcache.c certcache.h i18n.h util.h maperror.c \ + cdb.h cdblib.c ldap.c http.c http.h misc.c ocsp.c ocsp.h \ + validate.c validate.h -dirmngr_LDFLAGS = @LDAP_RPATH@ dirmngr_LDADD = ../jnlib/libjnlib.a @LIBOBJS@ @LIBASSUAN_LIBS@ \ - @LIBGCRYPT_LIBS@ @KSBA_LIBS@ @LDAP_LIBS@ + @LIBGCRYPT_LIBS@ @KSBA_LIBS@ @LDAP_LIBS@ $(PTH_LIBS) + +dirmngr_ldap_SOURCES = dirmngr_ldap.c i18n.h util.h \ + no-libgcrypt.c no-libgcrypt.h +dirmngr_ldap_CFLAGS = $(LDAP_INCS) +dirmngr_ldap_LDFLAGS = $(LDAP_RPATH) +dirmngr_ldap_LDADD = ../jnlib/libjnlib.a $(LIBOBJS) $(GPG_ERROR_LIBS) \ + $(LDAP_LIBS) + + +dirmngr_client_SOURCES = dirmngr-client.c i18n.h util.h maperror.c \ + no-libgcrypt.c no-libgcrypt.h +dirmngr_client_LDADD = ../jnlib/libjnlib.a $(LIBOBJS) $(LIBASSUAN_LIBS) \ + $(GPG_ERROR_LIBS) + Index: dirmngr/src/certcache.c diff -u /dev/null dirmngr/src/certcache.c:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/certcache.c Tue Nov 16 19:24:35 2004 @@ -0,0 +1,313 @@ +/* certcache.c - Certificate caching + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of DirMngr. + * + * DirMngr is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DirMngr 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 + */ + +#include + +#include +#include +#include +#include + +#include + +#include "dirmngr.h" +#include "misc.h" +#include "certcache.h" + + +/* A certificate cache item. This consists of a the ksba cert object + and some meta data for easier lookup. We use a hash table to keep + track of all items and use sue the randomly distributed first byte + of the fingerprint directly as the hash which makes it pretty easy. */ +struct cert_item_s +{ + struct cert_item_s *next; /* Next item with the same hash value. */ + ksba_cert_t cert; /* The KSBA cert object or NULL is this is + not a valid item. */ + unsigned char fpr[20]; /* The fingerprint of this object. */ + char *issuer_dn; /* The malloced issuer DN. */ + ksba_sexp_t sn; /* The malloced serial number */ + struct + { + int trusted; /* This is a trusted root certificate. */ + + + + + } flags; +}; +typedef struct cert_item_s *cert_item_t; + +/* The actual cert cache consisting of 256 slots for items idnex by + the first byte of the fingerprint. */ +static cert_item_t cert_cache[256]; + + + +/* Return false if both serial numbers match. Can't be used for + sorting. */ +static int +compare_serialno (ksba_sexp_t serial1, ksba_sexp_t serial2 ) +{ + unsigned char *a = serial1; + unsigned char *b = serial2; + char *endp; + unsigned long n_a, n_b; + + if (!a || !b) + return (!a && !b); + + n_a = strtoul (a+1, (char**)&endp, 10); + a = endp; + n_b = strtoul (b+1, (char**)&endp, 10); + b = endp; + if (*a != ':' || *b != ':') + { + log_debug ("invalid S-exp in compare_serialno\n"); + return 0; + } + if (n_a != n_b) + return 0; + + for (; n_a && *a == *b; n_a--, a++, b++) + ; + return !!n_a; +} + + +/* Computer the fingerprint of the certificate CERT and put it into + the 20 bytes large buffer DIGEST. Return address of this buffer. */ +static unsigned char * +compute_fpr (ksba_cert_t cert, unsigned char *digest) +{ + gpg_error_t err; + gcry_md_hd_t md; + + err = gcry_md_open (&md, GCRY_MD_SHA1, 0); + if (err) + log_fatal ("gcry_md_open failed: %s\n", gpg_strerror (err)); + + err = ksba_cert_hash (cert, 0, HASH_FNC, md); + if (err) + { + log_error ("oops: ksba_cert_hash failed: %s\n", gpg_strerror (err)); + memset (digest, 0xff, 20); /* Use a dummy value. */ + } + else + { + gcry_md_final (md); + memcpy (digest, gcry_md_read (md, GCRY_MD_SHA1), 20); + } + gcry_md_close (md); + return digest; +} + + + +/* Return a certificate object for the given fingerprint. FPR is + expected to be a 20 byte binary SHA-1 fingerprint. If no matching + certificate is available in the cache NULL is returned. The caller + must release a returned certificate. Note that although we are + using reference counting the caller should not just compare the + pointers to check for identical certificates. */ +ksba_cert_t +get_cert_byfpr (const unsigned char *fpr) +{ + cert_item_t ci; + + for (ci=cert_cache[*fpr]; ci; ci = ci->next) + if (ci->cert && !memcmp (ci->fpr, fpr, 20)) + { + ksba_cert_ref (ci->cert); + return ci->cert; + } + + return NULL; +} + + +/* Return the certificate matching ISSUER_DN and SERIALNO. */ +ksba_cert_t +get_cert_bysn (const char *issuer_dn, ksba_sexp_t serialno) +{ + /* Simple and inefficient implementation. fixme! */ + cert_item_t ci; + int i; + + for (i=0; i < 256; i++) + { + for (ci=cert_cache[i]; ci; ci = ci->next) + if (ci->cert && !strcmp (ci->issuer_dn, issuer_dn) + && !compare_serialno (ci->sn, serialno)) + { + ksba_cert_ref (ci->cert); + return ci->cert; + } + } + + return NULL; +} + + +/* Return the certificate matching ISSUER_DN. SEQ should initially be + set to 0 and bumped up to get the next issuer with that DN. */ +ksba_cert_t +get_cert_byissuer (const char *issuer_dn, unsigned int seq) +{ + /* Simple and very inefficient implementation and API. fixme! */ + cert_item_t ci; + int i; + + for (i=0; i < 256; i++) + { + for (ci=cert_cache[i]; ci; ci = ci->next) + if (ci->cert && !strcmp (ci->issuer_dn, issuer_dn)) + if (!seq--) + { + ksba_cert_ref (ci->cert); + return ci->cert; + } + } + + return NULL; +} + + + + +/* Return the certificate matching ISSUER_DN and SERIALNO; if it is + not already in the cache, try to find it from other resources. */ +ksba_cert_t +find_cert_bysn (const char *issuer_dn, ksba_sexp_t serialno) +{ + ksba_cert_t cert; + + cert = get_cert_bysn (issuer_dn, serialno); + if (cert) + return cert; + + return NULL; +} + + + +/* Return 0 if the certificate is a trusted certificate. Returns + GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in + case of systems errors. */ +gpg_error_t +is_trusted_cert (ksba_cert_t cert) +{ + unsigned char fpr[20]; + cert_item_t ci; + + compute_fpr (cert, fpr); + + for (ci=cert_cache[*fpr]; ci; ci = ci->next) + if (ci->cert && !memcmp (ci->fpr, fpr, 20)) + { + if (ci->flags.trusted) + return 0; /* Yes it is trusted. */ + break; + } + + return gpg_error (GPG_ERR_NOT_TRUSTED); +} + + +/* Given the certificate CERT locate the issuer for this certificate + and return it at R_CERT. Returns 0 on success or + GPG_ERR_NOT_FOUND. */ +gpg_error_t +find_issuing_cert (ksba_cert_t cert, ksba_cert_t *r_cert) +{ + gpg_error_t err; + char *issuer_dn; + ksba_cert_t issuer_cert = NULL; + ksba_name_t authid; + ksba_sexp_t authidno; + + *r_cert = NULL; + + issuer_dn = ksba_cert_get_issuer (cert, 0); + if (!issuer_dn) + { + log_error (_("no issuer found in certificate")); + err = gpg_error (GPG_ERR_BAD_CERT); + goto leave; + } + + /* First we need to check whether we can return that certificate + using the authorithyKeyIdentifier. */ + err = ksba_cert_get_auth_key_id (cert, NULL, &authid, &authidno); + if (err) + { + log_info (_("error getting authorityKeyIdentifier: %s\n"), + gpg_strerror (err)); + } + else + { + const char *s = ksba_name_enum (authid, 0); + if (s && *authidno) + { + issuer_cert = find_cert_bysn (s, authidno); + } + /* Print a note so that the user does not feel too helpless when + an issuer certificate was found and gpgsm prints BAD + signature because it is not the correct one. */ + if (!issuer_cert) + { + log_info ("issuer certificate (#"); + dump_serial (authidno); + log_printf ("/"); + dump_string (s); + log_printf (") not found\n"); + } + ksba_name_release (authid); + xfree (authidno); + } + + /* If this did not work, try just with the issuer's name. */ + if (err || !issuer_cert) + { + /* FIXME: we need to save a sequence number here for later + tries. */ + issuer_cert = get_cert_byissuer (issuer_dn, 0); + } + + leave: + if (!err && !issuer_cert) + err = gpg_error (GPG_ERR_NOT_FOUND); + + xfree (issuer_dn); + + if (err) + ksba_cert_release (issuer_cert); + else + *r_cert = issuer_cert; + + return err; +} + + + + + + + Index: dirmngr/src/certcache.h diff -u /dev/null dirmngr/src/certcache.h:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/certcache.h Tue Nov 16 19:24:35 2004 @@ -0,0 +1,45 @@ +/* certcache.h - Certificate caching + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of DirMngr. + * + * DirMngr is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DirMngr 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 + */ + +#ifndef CERTCACHE_H +#define CERTCACHE_H + + +/* Return 0 if the certificate is a trusted certificate. Returns + GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in + case of systems errors. */ +gpg_error_t is_trusted_cert (ksba_cert_t cert); + + +/* Return a certificate object for the given fingerprint. FPR is + expected to be a 20 byte binary SHA-1 fingerprint. If no matching + certificate is available in the cache NULL is returned. The caller + must release a returned certificate. */ +ksba_cert_t get_cert_byfpr (const unsigned char *fpr); + + +/* Given the certificate CERT locate the issuer for this certificate + and return it at R_CERT. Returns 0 on success or + GPG_ERR_NOT_FOUND. */ +gpg_error_t find_issuing_cert (ksba_cert_t cert, ksba_cert_t *r_cert); + + + +#endif /*CERTCACHE_H*/ Index: dirmngr/src/crlcache.c diff -u dirmngr/src/crlcache.c:1.45 dirmngr/src/crlcache.c:1.46 --- dirmngr/src/crlcache.c:1.45 Wed Aug 18 18:41:42 2004 +++ dirmngr/src/crlcache.c Tue Nov 16 19:24:35 2004 @@ -1,5 +1,5 @@ /* crlcache.c - LDAP access - * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * Copyright (C) 2002 Klarälvdalens Datakonsult AB * Copyright (C) 2003, 2004 g10 Code GmbH * * This file is part of DirMngr. @@ -110,7 +110,7 @@ /* The number of DB files we may have open at one time. We need to limit this because there is no guarantee that the number of issuers has a upper limit. We are currently using mmap, so it is a good - idea anyway to limit the number of opend cache files. */ + idea anyway to limit the number of opened cache files. */ #define MAX_OPEN_DB_FILES 5 @@ -154,12 +154,34 @@ unsigned int cdb_open_count; /* Currently open cache files. */ }; +typedef struct crl_cache_s *crl_cache_t; + +/* Prototypes. */ static crl_cache_entry_t find_entry (crl_cache_entry_t first, const char *issuer_hash); +/* The currently loaded cache object. This isi usually initialized + right at startup. */ +static crl_cache_t current_cache; + + + + + +/* Return the current cache object or bail out if it is has not yet + been initialized. */ +static crl_cache_t +get_current_cache (void) +{ + if (!current_cache) + log_fatal ("CRL cache has not yet been initialized\n"); + return current_cache; +} + + /* Create ae directory if it does not yet exists. Returns on success, or -1 on error. @@ -449,7 +471,7 @@ /* Open the dir file and read in all available information. Store - that in a newly allocated cahce object and return that if + that in a newly allocated cache object and return that if everything worked out fine. Create the cache directory and the dir if it does not yet exist. Remove all files in that directory if the version does not match. */ @@ -1057,31 +1079,38 @@ -/* Create a new CRL cache. Returns the handle to this cache. Will +/* Create a new CRL cache. This fucntion is usually called only once. never fail. */ -crl_cache_t +void crl_cache_init(void) { crl_cache_t cache; gpg_error_t err; + if (current_cache) + { + log_error ("crl cache has already been initialized - not doing twice\n"); + return; + } + err = open_dir (&cache); - if (err) + if (err) log_fatal (_("failed to create a new cache object: %s\n"), gpg_strerror (err)); - return cache; + current_cache = cache; } /* Remove the cache information and all its resources. Note that we still keep the cache on disk. */ void -crl_cache_deinit (crl_cache_t cache) +crl_cache_deinit (void) { - if (!cache) - return; - - release_cache (cache); + if (current_cache) + { + release_cache (current_cache); + current_cache = NULL; + } } @@ -1089,25 +1118,25 @@ int crl_cache_flush (void) { - int problem = 0; + int rc; - if (cleanup_cache_dir (0)) - problem = -1; - return problem; + rc = cleanup_cache_dir (0)? -1 : 0; + + return rc; } /* Check whether the certificate identified by ISSUER_HASH and SERIALNO is valid; i.e. not listed in our cache. With - FORCE_REFRESH set to true, a new CRL will be retrieved eben if the - cached has not yet expired. We use a 30 minutes threshold here so + FORCE_REFRESH set to true, a new CRL will be retrieved even if the + cache has not yet expired. We use a 30 minutes threshold here so that invoking this function several times won't load the CRL over and over. */ crl_cache_result_t -crl_cache_isvalid (crl_cache_t cache, - const char *issuer_hash, const char *serialno, +crl_cache_isvalid (const char *issuer_hash, const char *serialno, int force_refresh) { + crl_cache_t cache = get_current_cache (); crl_cache_result_t retval; struct cdb *cdb; int rc; @@ -1232,7 +1261,7 @@ { gpg_error_t err; ksba_cert_t issuer_cert = NULL; - FILE *fp; + ksba_reader_t reader; /* Ask back to the service requester to return the certificate. This is because we can assume that he already used the @@ -1246,7 +1275,7 @@ log_debug ("certificate for CRL issuer not returned by caller" " - doing lookup\n"); - err = ca_cert_fetch (issuer, &fp); + err = ca_cert_fetch (issuer, &reader); if (err) { log_error (_("error fetching certificate for issuer: %s\n"), @@ -1257,23 +1286,16 @@ err = ksba_cert_new (&issuer_cert); if (!err) { - ksba_reader_t r; - - err = ksba_reader_new (&r); - if (!err) - err = ksba_reader_set_file (r, fp); - if (!err) - err = ksba_cert_read_der (issuer_cert, r); + err = ksba_cert_read_der (issuer_cert, reader); if (err) { ksba_cert_release (issuer_cert); issuer_cert = NULL; } - ksba_reader_release (r); } if (err) log_error (_("invalid issuer certificate: %s\n"), gpg_strerror (err) ); - fclose (fp); + ksba_reader_release (reader); return issuer_cert; } @@ -1560,7 +1582,7 @@ /* Return the authorityKeyIdentifier or NULL if it is not available. - The issuer name may consists of several parts - the are delimted by + The issuer name may consists of several parts - they are delimted by 0x01. */ static char * get_auth_key_id (ksba_crl_t crl, char **serialno) @@ -1610,11 +1632,11 @@ CACHE. The CRL itself will be read from the stream FP and is expected in binary format. */ gpg_error_t -crl_cache_insert (ctrl_t ctrl, crl_cache_t cache, const char *url, FILE *fp) +crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader) { + crl_cache_t cache = get_current_cache (); gpg_error_t err, err2; ksba_crl_t crl; - ksba_reader_t reader; char *fname = NULL; char *newfname = NULL; struct cdb_make cdb; @@ -1630,6 +1652,11 @@ int idx; const char *oid; int critical; + + + /* FIXME: We should acquire a mutex for the URL, so that we don't + simultaneously enter the same CRL twice. However this needs t be + interweaved with the checking function.*/ err2 = 0; @@ -1640,14 +1667,6 @@ goto leave; } - err = ksba_reader_new (&reader); - if (!err) - err = ksba_reader_set_file (reader, fp); - if (err) - { - log_error (_("ksba_reader_set_file failed: %s\n"), gpg_strerror (err)); - goto leave; - } err = ksba_crl_set_reader (crl, reader); if ( err ) { @@ -1836,7 +1855,6 @@ xfree (fname); } xfree (newfname); - ksba_reader_release (reader); ksba_crl_release (crl); xfree (issuer); xfree (issuer_hash); @@ -1967,8 +1985,9 @@ /* Print the contents of the CRL CACHE in a human readable format to stream FP. */ gpg_error_t -crl_cache_list (crl_cache_t cache, FILE *fp) +crl_cache_list (FILE *fp) { + crl_cache_t cache = get_current_cache (); crl_cache_entry_t entry; gpg_error_t err = 0; @@ -1984,7 +2003,7 @@ /* Load the CRL contain the the file named FILENAME into our cache CACHE */ gpg_error_t -crl_cache_load (ctrl_t ctrl, crl_cache_t cache, const char *filename) +crl_cache_load (ctrl_t ctrl, const char *filename) { gpg_error_t err; FILE* fp; @@ -1997,7 +2016,8 @@ return err; } - err = crl_cache_insert (ctrl, cache, filename, fp); + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + /*crl_cache_insert (ctrl, filename, fo);*/ fclose (fp); return err; } Index: dirmngr/src/crlcache.h diff -u dirmngr/src/crlcache.h:1.21 dirmngr/src/crlcache.h:1.22 --- dirmngr/src/crlcache.h:1.21 Thu Apr 29 10:26:32 2004 +++ dirmngr/src/crlcache.h Tue Nov 16 19:24:35 2004 @@ -51,26 +51,21 @@ struct crl_cache_entry_s; typedef struct crl_cache_entry_s *crl_cache_entry_t; -struct crl_cache_s; -typedef struct crl_cache_s *crl_cache_t; - -crl_cache_t crl_cache_init (void); -void crl_cache_deinit (crl_cache_t c); +void crl_cache_init (void); +void crl_cache_deinit (void); int crl_cache_flush(void); -crl_cache_result_t crl_cache_isvalid (crl_cache_t cache, - const char *issuer_hash, +crl_cache_result_t crl_cache_isvalid (const char *issuer_hash, const char *cert_id, int force_refresh); -gpg_error_t crl_cache_insert (ctrl_t ctrl, crl_cache_t cache, - const char *url, FILE *fp); +gpg_error_t crl_cache_insert (ctrl_t ctrl, const char *url, + ksba_reader_t reader); -gpg_error_t crl_cache_list (crl_cache_t cache, FILE* fp); +gpg_error_t crl_cache_list (FILE* fp); -gpg_error_t crl_cache_load (ctrl_t ctrl, crl_cache_t cache, - const char *filename); +gpg_error_t crl_cache_load (ctrl_t ctrl, const char *filename); #endif /* CRLCACHE_H */ Index: dirmngr/src/crlfetch.c diff -u dirmngr/src/crlfetch.c:1.18 dirmngr/src/crlfetch.c:1.19 --- dirmngr/src/crlfetch.c:1.18 Mon Jun 21 10:13:40 2004 +++ dirmngr/src/crlfetch.c Tue Nov 16 19:24:35 2004 @@ -1,5 +1,5 @@ /* crlfetch.c - LDAP access - * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * Copyright (C) 2002 Klarälvdalens Datakonsult AB * Copyright (C) 2003, 2004 g10 Code GmbH * * This file is part of DirMngr. @@ -29,87 +29,18 @@ #include "misc.h" #include "http.h" -struct fun_cookie_s { - unsigned char *value; /* Malloced buffer with the data to deliver. */ - size_t valuelen; /* Size of this buffer. */ - size_t nread; /* Bytes already read from value. */ -}; - -static int -fun_reader (void *cookie, char *buffer, int size) -{ - struct fun_cookie_s *h = cookie; - - if (h->nread >= h->valuelen) - return 0; /* EOF */ - if (h->nread + size > h->valuelen) - size = h->valuelen - h->nread; - memcpy (buffer, h->value + h->nread, size); - h->nread += size; - return size; -} - -static int -fun_closer (void *cookie) -{ - struct fun_cookie_s *h = cookie; - - xfree (h->value); - xfree (h); - return 0; -} - -/* Helper to prepare a stream from VALUE and VALUELEN and return that - stream in R_FP. In the error case VALUE will be freed. */ -static gpg_error_t -setup_funopen (unsigned char *value, size_t valuelen, FILE **r_fp) -{ - gpg_error_t err = 0; - struct fun_cookie_s *h; - FILE *fp; - - h = xtrymalloc (sizeof *h); - if (!h) - { - err = gpg_error_from_errno (errno); - xfree (value); - } - else - { - h->value = value; - value = NULL; - h->valuelen = valuelen; - h->nread = 0; - fp = funopen (h, fun_reader, NULL, NULL, fun_closer); - if (!fp) - { - err = gpg_error_from_errno (errno); - xfree (h->value); - xfree (h); - } - else - *r_fp = fp; - } - return err; -} - -/* Fetch CRL from URL and return the entire CRL as a newly opened - stream returned in R_FP. - - FIXME: we should look for a way to return the stream direct from - the ldap core and not use a temporary buffer. - */ +/* Fetch CRL from URL and return the entire CRL using new ksba reader + object in READER. Note that this reader object should be closed + only using ldap_close_reader. */ gpg_error_t -crl_fetch (const char *url, FILE **r_fp) +crl_fetch (const char *url, ksba_reader_t *reader) { gpg_error_t err; - unsigned char *value = NULL; - size_t valuelen; parsed_uri_t uri; char *free_this = NULL; - *r_fp = NULL; + *reader = NULL; err = http_parse_uri (&uri, url); http_release_parsed_uri (uri); @@ -148,37 +79,59 @@ } else { - *r_fp = hd.fp_read; - http_close (&hd, 1); + err = ksba_reader_new (reader); + if (!err) + err = ksba_reader_set_file (*reader, hd.fp_read); + if (err) + { + log_error (_("error initializing reader object: %s\n"), + gpg_strerror (err)); + ksba_reader_release (*reader); + *reader = NULL; + http_close (&hd, 0); + } + else + { + /* FIXME: Register the fp somewhere so that we are able + to release the ksba_reader and close the underlying + stream. See also below crl_close_reader(). */ + http_close (&hd, 1); + } } } else /* Let the LDAP code try other schemes. */ { const char *s; - const char *attr; - /* FIXME: This is a bad hack. I don't know why we at all - pass the attribute separately to the LDAP serach code. - The attributes are included in the URL and OpenLDAP - provides a parse functionality for it. It has never been - used though. We need to find out why this strange way - was used!!!!. */ - s = strchr (url, '?'); - if (s && !strcmp (s+1, "certificateRevocationList")) - attr = "certificateRevocationList;binary"; - else if (s && !strcmp (s+1, "authorityRevocationList")) - attr = "authorityRevocationList;binary"; - else - { - log_info ("WARNING: unsupported LDAP attribute - using CRL\n"); - attr = "certificateRevocationList;binary"; - } + err = url_fetch_ldap (url, NULL, 0, reader); +/* if (err) */ +/* { */ +/* /\* If the function failed we try again using our default */ +/* host. *\/ */ +/* ldap_server_t server; */ +/* char *savehost; */ +/* int saveport; */ + +/* if (DBG_LOOKUP) */ +/* log_debug ("no hostname in URL or query failed; " */ +/* "trying all default hostnames\n"); */ +/* savehost = ludp->lud_host; */ +/* saveport = ludp->lud_port; */ +/* for (server = opt.ldapservers; server; server = server->next) */ +/* { */ +/* ludp->lud_host = server->host; */ +/* ludp->lud_port = server->port; */ +/* err = url_fetch_ldap_internal (ludp, attr, value, valuelen); */ +/* if (!err) */ +/* break; */ +/* } */ +/* ludp->lud_host = savehost; */ +/* ludp->lud_port = saveport; */ +/* if (opt.add_new_ldapservers) */ +/* add_server_to_servers (ludp->lud_host, ludp->lud_port); */ + +/* } */ - err = url_fetch_ldap (url, attr, &value, &valuelen); - if (!err) - err = setup_funopen (value, valuelen, r_fp); - else if (err && value) - xfree (value); } if (free_this) xfree (free_this); @@ -189,28 +142,18 @@ /* Fetch CRL for ISSUER using a default server. Return the entire CRL as a newly opened stream returned in R_FP. */ gpg_error_t -crl_fetch_default (const char *issuer, FILE **r_fp) +crl_fetch_default (const char *issuer, ksba_reader_t *reader) { - gpg_error_t err; -/* unsigned char *value = NULL; */ -/* size_t valuelen; */ - -/* *r_fp = NULL; */ - err = attr_fetch_ldap (issuer, "certificateRevocationList;binary", - r_fp); -/* if (!err) */ -/* err = setup_funopen (value, valuelen, r_fp); */ -/* else if (err && value) */ -/* xfree (value); */ - return err; + return attr_fetch_ldap (issuer, "certificateRevocationList;binary", + reader); } /* Fetch a CA certificate for DN using the default server. */ int -ca_cert_fetch (const char *dn, FILE **r_fp) +ca_cert_fetch (const char *dn, ksba_reader_t *reader) { - return attr_fetch_ldap (dn, "cACertificate;binary", r_fp); + return attr_fetch_ldap (dn, "cACertificate;binary", reader); } @@ -233,3 +176,24 @@ { return end_cert_fetch_ldap (context); } + + +/* This function is to be used to close the reader object. In + addition to running ksba_reader_release it also releases the LDAP + or HTTP contexts associated with that reader. */ +void +crl_close_reader (ksba_reader_t reader) +{ + if (!reader) + return; + + /* Check whether this is a HTTP one. */ + + /* FIXME: TODO */ + + /* If not a ldap wrapper context might be assocaited. */ + ldap_wrapper_release_context (reader); + + /* Now get rid of the reader object. */ + ksba_reader_release (reader); +} Index: dirmngr/src/crlfetch.h diff -u dirmngr/src/crlfetch.h:1.10 dirmngr/src/crlfetch.h:1.11 --- dirmngr/src/crlfetch.h:1.10 Fri Apr 2 20:05:19 2004 +++ dirmngr/src/crlfetch.h Tue Nov 16 19:24:35 2004 @@ -1,5 +1,5 @@ /* crlfetch.h - LDAP access - * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * Copyright (C) 2002 Klarälvdalens Datakonsult AB * * This file is part of DirMngr. * @@ -31,14 +31,14 @@ /* Fetch CRL from URL. */ -gpg_error_t crl_fetch (const char* url, FILE **r_fp); +gpg_error_t crl_fetch (const char* url, ksba_reader_t *reader); /* Fetch CRL for ISSUER using default server. */ -gpg_error_t crl_fetch_default (const char* issuer, FILE **r_fp); +gpg_error_t crl_fetch_default (const char* issuer, ksba_reader_t *reader); /* Fetch cert for DN. */ -int ca_cert_fetch( const char *dn, FILE **r_fp); +int ca_cert_fetch (const char *dn, ksba_reader_t *reader); /* Query the server for certs matching patterns. */ @@ -49,11 +49,20 @@ unsigned char **value, size_t *valuelen); void end_cert_fetch (cert_fetch_context_t context); +/* Close a reader object. */ +void crl_close_reader (ksba_reader_t reader); + + /*-- ldap.c --*/ -gpg_error_t attr_fetch_ldap( const char* dn, const char *attr, FILE **r_fp); -gpg_error_t url_fetch_ldap(const char* url, const char* attr, - unsigned char **value, size_t *valuelen ); +void *ldap_wrapper_thread (void*); +void ldap_wrapper_release_context (ksba_reader_t reader); + +gpg_error_t url_fetch_ldap (const char *url, const char *host, int port, + ksba_reader_t *reader); +gpg_error_t attr_fetch_ldap (const char *dn, const char *attr, + ksba_reader_t *reader); + gpg_error_t start_cert_fetch_ldap(cert_fetch_context_t *context, strlist_t patterns, @@ -63,4 +72,8 @@ void end_cert_fetch_ldap (cert_fetch_context_t context); + + + + #endif /* CRLFETCH_H */ Index: dirmngr/src/dirmngr-client.c diff -u /dev/null dirmngr/src/dirmngr-client.c:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/dirmngr-client.c Tue Nov 16 19:24:35 2004 @@ -0,0 +1,474 @@ +/* dirmngr-client.c - A client for the dirmngr daemon + * Copyright (C) 2004 g10 Code GmbH + * Copyright (C) 2002, 2003 Free Software Foundation, Inc. + * + * This file is part of DirMngr. + * + * DirMngr is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DirMngr 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 + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#define JNLIB_NEED_LOG_LOGV +#include "../jnlib/logging.h" +#include "../jnlib/argparse.h" +#include "../jnlib/stringhelp.h" +#include "../jnlib/mischelp.h" +#include "../jnlib/strlist.h" + +#include "i18n.h" +#include "util.h" +#include "no-libgcrypt.h" + + +/* Constants for the options. */ +enum + { + oQuiet = 'q', + oVerbose = 'v', + + oOCSP = 500, + oPing, + oUseDaemon, + oDummy + }; + + +/* The list of options as used by the argparse.c code. */ +static ARGPARSE_OPTS opts[] = { + { oVerbose, "verbose", 0, N_("verbose") }, + { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, + { oOCSP, "ocsp", 0, N_("use OCSP instead of CRLs") }, + { oPing, "ping", 0, N_("check whether a dirmngr is running")}, + { oUseDaemon,"use-daemon",0, N_("force use of the daemon")}, + {0} +}; + +#define DEFAULT_SOCKET_NAME "/var/run/dirmngr/socket" + +/* The usual structure for the program flags. */ +static struct +{ + int quiet; + int verbose; + const char *dirmngr_program; + int force_pipe_server; + + int use_ocsp; + +} opt; + + +/* Communication structure for the certificate inquire callback. */ +struct inq_cert_parm_s +{ + assuan_context_t ctx; + const unsigned char *cert; + size_t certlen; +}; + + +/* Prototypes. */ +static assuan_context_t start_dirmngr (int only_daemon); +static gpg_error_t read_certificate (const char *fname, + unsigned char **rbuf, size_t *rbuflen); +static gpg_error_t do_check (assuan_context_t ctx, + const unsigned char *cert, size_t certlen); + + + +/* Function called by argparse.c to display information. */ +static const char * +my_strusage (int level) +{ + const char *p; + + switch(level) + { + case 11: p = "dirmngr-client"; + break; + case 13: p = VERSION; break; + case 14: p = "Copyright (C) 2004 g10 Code GmbH"; break; + case 17: p = PRINTABLE_OS_NAME; break; + case 19: p = + _("Please report bugs to .\n"); + break; + case 1: + case 40: p = + _("Usage: dirmngr-client [options] [certfile] (-h for help)\n"); + break; + case 41: p = + _("Syntax: dirmngr-client [options] [certfile]\n" + "Test an X.509 certificate against a CRL or do an OCSP check\n" + "The process returns 0 if the certificate is valid, 1 if it is\n" + "not valid and other error codes for general failures\n"); + break; + + default: p = NULL; + } + return p; +} + + +static void +i18n_init (void) +{ +#ifdef USE_SIMPLE_GETTEXT + set_gettext_file (PACKAGE); +#else +# ifdef ENABLE_NLS + setlocale (LC_ALL, "" ); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); +# endif +#endif +} + + +int +main (int argc, char **argv ) +{ + ARGPARSE_ARGS pargs; + assuan_context_t ctx; + gpg_error_t err; + unsigned char *certbuf; + size_t certbuflen; + int do_ping = 0; + int use_daemon = 0; + + set_strusage (my_strusage); + log_set_prefix ("dirmngr-client", + JNLIB_LOG_WITH_PREFIX); + + /* Init Assuan. */ + assuan_set_assuan_log_stream (log_get_stream ()); + assuan_set_assuan_log_prefix (log_get_prefix (NULL)); + + /* Setup I18N. */ + i18n_init(); + + /* Parse the command line. */ + pargs.argc = &argc; + pargs.argv = &argv; + pargs.flags= 1; /* Do not remove the args. */ + while (arg_parse (&pargs, opts) ) + { + switch (pargs.r_opt) + { + case oVerbose: opt.verbose++; break; + case oQuiet: opt.quiet++; break; + case oOCSP: opt.use_ocsp++; break; + case oPing: do_ping = 1; break; + case oUseDaemon: use_daemon = 1; break; + + default : pargs.err = 2; break; + } + } + if (log_get_errorcount (0)) + exit (2); + + if (do_ping) + err = 0; + else if (!argc) + { + err = read_certificate (NULL, &certbuf, &certbuflen); + if (err) + log_error (_("error reading certificate from stdin: %s\n"), + gpg_strerror (err)); + } + else if (argc == 1) + { + err = read_certificate (*argv, &certbuf, &certbuflen); + if (err) + log_error (_("error reading certificate from `%s': %s\n"), + *argv, gpg_strerror (err)); + } + else + { + err = 0; + usage (1); + } + + if (log_get_errorcount (0)) + exit (2); + + if (certbuflen > 20000) + { + log_error (_("certificate too large to make any sense\n")); + exit (2); + } + + ctx = start_dirmngr (do_ping || use_daemon); + if (!ctx) + exit (2); + + if (!do_ping) + { + err = do_check (ctx, certbuf, certbuflen); + xfree (certbuf); + } + + assuan_disconnect (ctx); + + if (do_ping) + { + if (!opt.quiet) + log_info (_("a dirmngr daemon is up and running\n")); + return 0; + } + else if (!err) + { + if (!opt.quiet) + log_info (_("certificate is valid\n")); + return 0; + } + else if (gpg_err_code (err) == GPG_ERR_CERT_REVOKED ) + { + if (!opt.quiet) + log_info (_("certificate has been revoked\n")); + return 1; + } + else + { + log_error (_("certificate check failed: %s\n"), gpg_strerror (err)); + return 2; + } +} + + +/* Try to connect to the dirmngr via socket or fork it off and work by + pipes. Handle the server's initial greeting */ +static assuan_context_t +start_dirmngr (int only_daemon) +{ + int rc; + char *infostr, *p; + assuan_context_t ctx; + int try_default = 0; + + infostr = opt.force_pipe_server? NULL : getenv ("DIRMNGR_INFO"); + if (only_daemon && (!infostr || !*infostr)) + { + infostr = DEFAULT_SOCKET_NAME; + try_default = 1; + } + if (!infostr || !*infostr) + { + const char *pgmname; + const char *argv[3]; + int no_close_list[3]; + int i; + + if (only_daemon) + { + log_error (_("apparently no running dirmngr\n")); + return NULL; + } + + if (opt.verbose) + log_info (_("no running dirmngr - starting one\n")); + + if (!opt.dirmngr_program || !*opt.dirmngr_program) + opt.dirmngr_program = "./dirmngr"; + if ( !(pgmname = strrchr (opt.dirmngr_program, '/'))) + pgmname = opt.dirmngr_program; + else + pgmname++; + + argv[0] = pgmname; + argv[1] = "--server"; + argv[2] = NULL; + + i=0; + if (log_get_fd () != -1) + no_close_list[i++] = log_get_fd (); + no_close_list[i++] = fileno (stderr); + no_close_list[i] = -1; + + /* Connect to the agent and perform initial handshaking. */ + rc = assuan_pipe_connect (&ctx, opt.dirmngr_program, (char**)argv, + no_close_list); + } + else /* Connect to a daemon. */ + { + int prot; + int pid; + + infostr = xstrdup (infostr); + if (!try_default && *infostr) + { + if ( !(p = strchr (infostr, ':')) || p == infostr) + { + log_error (_("malformed DIRMNGR_INFO environment variable\n")); + xfree (infostr); + if (only_daemon) + return NULL; + /* Try again by starting a new instance. */ + opt.force_pipe_server = 1; + return start_dirmngr (0); + } + *p++ = 0; + pid = atoi (p); + while (*p && *p != ':') + p++; + prot = *p? atoi (p+1) : 0; + if (prot != 1) + { + log_error (_("dirmngr protocol version %d is not supported\n"), + prot); + xfree (infostr); + if (only_daemon) + return NULL; + opt.force_pipe_server = 1; + return start_dirmngr (0); + } + } + else + pid = -1; + + rc = assuan_socket_connect (&ctx, infostr, pid); + xfree (infostr); + if (rc == ASSUAN_Connect_Failed && !only_daemon) + { + log_error (_("can't connect to the dirmngr - trying fall back\n")); + opt.force_pipe_server = 1; + return start_dirmngr (0); + } + } + + if (rc) + { + log_error (_("can't connect to the dirmngr: %s\n"), + assuan_strerror (rc)); + return NULL; + } + + return ctx; +} + + +/* Red a binary certificate from the file FNAME. If fname is NULL the + file is read from stdin. The certificate is returned in an alloced + buffer whos address will be returned in RBUF and its length in + RBUFLEN. */ +static gpg_error_t +read_certificate (const char *fname, unsigned char **rbuf, size_t *rbuflen) +{ + gpg_error_t err; + FILE *fp; + unsigned char *buf; + size_t nread, bufsize, buflen; + + fp = fname? fopen (fname, "rb") : stdin; + if (!fp) + return gpg_error_from_errno (errno); + + buf = NULL; + bufsize = buflen = 0; +#define NCHUNK 8192 + do + { + bufsize += NCHUNK; + if (!buf) + buf = xmalloc (bufsize); + else + buf = xrealloc (buf, bufsize); + + nread = fread (buf+buflen, 1, NCHUNK, fp); + if (nread < NCHUNK && ferror (fp)) + { + err = gpg_error_from_errno (errno); + xfree (buf); + if (fname) + fclose (fp); + return err; + } + buflen += nread; + } + while (nread == NCHUNK); +#undef NCHUNK + if (fname) + fclose (fp); + *rbuf = buf; + *rbuflen = buflen; + return 0; +} + + +/* Callback for the inquire fiunction to send back the certificate. */ +static assuan_error_t +inq_cert (void *opaque, const char *line) +{ + struct inq_cert_parm_s *parm = opaque; + assuan_error_t ae; + + if (!strncmp (line, "TARGETCERT", 10) && (line[10] == ' ' || !line[10])) + { + ae = assuan_send_data (parm->ctx, parm->cert, parm->certlen); + } + else if (!strncmp (line, "SENDCERT", 8) && (line[8] == ' ' || !line[8])) + { + /* We don't support this but dirmngr might ask for it. So + simply ignore it by sending back and empty value. */ + ae = assuan_send_data (parm->ctx, NULL, 0); + } + else if (!strncmp (line, "SENDISSUERCERT", 14) + && (line[14] == ' ' || !line[14])) + { + /* We don't support this but dirmngr might ask for it. So + simply ignore it by sending back and empty value. */ + ae = assuan_send_data (parm->ctx, NULL, 0); + } + else + { + log_info (_("unsupported inquiry `%s'\n"), line); + ae = ASSUAN_Inquire_Unknown; + } + + return ae; +} + + +/* Check the certificate CERT,CERTLEN for validity using a CRL or OCSP. + Return a proper error code. */ +static gpg_error_t +do_check (assuan_context_t ctx, const unsigned char *cert, size_t certlen) +{ + assuan_error_t ae; + struct inq_cert_parm_s parm; + + memset (&parm, 0, sizeof parm); + parm.ctx = ctx; + parm.cert = cert; + parm.certlen = certlen; + + ae = assuan_transact (ctx, opt.use_ocsp? "CHECKOCSP":"CHECKCRL", NULL, NULL, + inq_cert, &parm, + NULL, NULL); + if (opt.verbose > 1) + log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay"); + return map_assuan_err (ae); +} Index: dirmngr/src/dirmngr.c diff -u dirmngr/src/dirmngr.c:1.40 dirmngr/src/dirmngr.c:1.41 --- dirmngr/src/dirmngr.c:1.40 Mon Oct 4 13:50:50 2004 +++ dirmngr/src/dirmngr.c Tue Nov 16 19:24:35 2004 @@ -1,5 +1,5 @@ /* dirmngr.c - LDAP access - * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * Copyright (C) 2002 Klarälvdalens Datakonsult AB * Copyright (C) 2003, 2004 g10 Code GmbH * * This file is part of DirMngr. @@ -30,12 +30,16 @@ #include #include #include +#include +#include +#include #include #include +#include #include #include -#include /* needed for the malloc hooks */ +#include /* Needed for the malloc hooks */ #define JNLIB_NEED_LOG_LOGV #include "dirmngr.h" @@ -52,6 +56,7 @@ oNoVerbose = 500, aServer, + aDaemon, aListCRLs, aLoadCRL, aFetchCRL, @@ -79,6 +84,7 @@ oFakedSystemTime, oForce, oAllowOCSP, + oSocketName, aTest }; @@ -87,7 +93,8 @@ { 300, NULL, 0, N_("@Commands:\n ") }, - { aServer, "server", 256, N_("run in server mode") }, + { aServer, "server", 256, N_("run in server mode (foreground)") }, + { aDaemon, "daemon", 256, N_("run in daemon mode (background)") }, { aListCRLs, "list-crls", 256, N_("list the contents of the CRL cache")}, { aLoadCRL, "load-crl", 256, N_("|FILE|load CRL from FILE into cache")}, { aFetchCRL, "fetch-crl", 256, N_("|URL|fetch a CRL from URL")}, @@ -123,6 +130,8 @@ { oMaxReplies, "max-replies", 1, N_("|N|do not return more than N items in one query")}, + { oSocketName, "socket-name", 2, N_("|FILE|listen on socket FILE") }, + { oFakedSystemTime, "faked-system-time", 4, "@" }, /* (epoch time) */ { oDebug, "debug" ,4|16, "@"}, { oDebugAll, "debug-all" ,0, "@"}, @@ -133,10 +142,30 @@ #define DEFAULT_MAX_REPLIES 10 #define DEFAULT_LDAP_TIMEOUT 100 /* arbitrary large timeout */ +#define DEFAULT_SOCKET_NAME "/var/run/dirmngr/socket" + +/* For the cleanup handler we need to keep track of the socket's name. */ +static const char *socket_name; +/* Only if this flag has been set we will remove the socket file. */ +static int cleanup_socket; +/* Keep track of the current log file so that we can avoid updating + the log file after a SIGHUP if it didn't changed. Malloced. */ +static char *current_logfile; +/* Helper to implement --debug-level. */ +static const char *debug_level; +/* Flag indicating that a shutdown has been requested. */ +static int shutdown_pending; +/* Counter for the active connections. */ +static int active_connections; +/* Prototypes. */ static void cleanup (void); static ldap_server_t parse_ldapserver_file (const char* filename); static void free_ldapservers_list (ldap_server_t servers); +static void handle_connections (int listen_fd); + +/* Pth wrapper function definitions. */ +GCRY_THREAD_OPTION_PTH_IMPL; static const char * @@ -211,27 +240,28 @@ set of debug flags is set; thus overriding all flags already set. */ static void -set_debug (const char *level) +set_debug (void) { - if (!level) + if (!debug_level) ; - else if (!strcmp (level, "none")) + else if (!strcmp (debug_level, "none")) opt.debug = 0; - else if (!strcmp (level, "basic")) + else if (!strcmp (debug_level, "basic")) opt.debug = DBG_ASSUAN_VALUE; - else if (!strcmp (level, "advanced")) + else if (!strcmp (debug_level, "advanced")) opt.debug = DBG_ASSUAN_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE; - else if (!strcmp (level, "expert")) + else if (!strcmp (debug_level, "expert")) opt.debug = (DBG_ASSUAN_VALUE|DBG_X509_VALUE|DBG_LOOKUP_VALUE |DBG_CACHE_VALUE|DBG_CRYPTO_VALUE); - else if (!strcmp (level, "guru")) + else if (!strcmp (debug_level, "guru")) opt.debug = ~0; else { - log_error (_("invalid debug-level `%s' given\n"), level); + log_error (_("invalid debug-level `%s' given\n"), debug_level); log_info (_("valid debug levels are: %s\n"), "none, basic, advanced, expert, guru"); - dirmngr_exit (2); + opt.debug = 0; /* Reset debugging, so that prior debug + statements won't have an undesired effect. */ } @@ -273,6 +303,74 @@ } +/* Helper to start the ripper thread for the ldap wrapper. */ +static void +launch_ripper_thread (void) +{ + static int done; + pth_attr_t tattr; + + 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-ripper"); + + if (!pth_spawn (tattr, ldap_wrapper_thread, NULL)) + { + log_error (_("error spawning ldap wrapper ripper thread: %s\n"), + strerror (errno) ); + dirmngr_exit (1); + } +} + + + +/* Handle options which are allowed to be reset after program start. + Return true if the current option in PARGS could be handled and + false if not. As a special feature, passing a value of NULL for + PARGS, resets the options to the default. REREAD should be set + true if it is not the initial option parsing. */ +static int +parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread) +{ + if (!pargs) + { /* Reset mode. */ + opt.quiet = 0; + opt.verbose = 0; + opt.debug = 0; + return 1; + } + + switch (pargs->r_opt) + { + case oQuiet: opt.quiet = 1; break; + case oVerbose: opt.verbose++; break; + case oDebug: opt.debug |= pargs->r.ret_ulong; break; + case oDebugAll: opt.debug = ~0; break; + case oDebugLevel: debug_level = pargs->r.ret_str; break; + + case oLogFile: + if (!reread) + return 0; /* Not handled. */ + if (!current_logfile || !pargs->r.ret_str + || strcmp (current_logfile, pargs->r.ret_str)) + { + log_set_file (pargs->r.ret_str); + xfree (current_logfile); + current_logfile = xtrystrdup (pargs->r.ret_str); + } + break; + + default: + return 0; /* Not handled. */ + } + set_debug (); + return 1; /* Handled. */ +} int main (int argc, char **argv ) @@ -289,13 +387,14 @@ int default_config =1; int greeting = 0; int nogreeting = 0; - const char *debug_level = NULL; int nodetach = 0; int csh_style = 0; char *logfile = NULL; char *ldapfile = NULL; int debug_wait = 0; int rc; + int homedir_seen = 0; + int daemon_seen = 0; set_strusage (my_strusage); log_set_prefix ("dirmngr", 1|4); @@ -303,7 +402,16 @@ /* Check that the libraries are suitable. Do it here because the option parsing may need services of the libraries. */ + /* Libgcrypt requires us to register the threading model first. + Note that this will also do the pth_init. */ + /* Init Libgcrypt. */ + rc = gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth); + if (rc) + { + log_fatal ("can't register GNU Pth with Libgcrypt: %s\n", + gpg_strerror (rc)); + } gcry_control (GCRYCTL_DISABLE_SECMEM, 0); if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) { @@ -356,6 +464,10 @@ /* Default max replies */ opt.max_replies = DEFAULT_MAX_REPLIES; + /* Other defaults. */ + socket_name = DEFAULT_SOCKET_NAME; + + /* Check whether we have a config file given on the commandline */ orig_argc = argc; orig_argv = argv; @@ -372,12 +484,23 @@ commandline */ default_config = 0; } - else if (pargs.r_opt == oNoOptions) - default_config = 0; /* --no-options */ - else if (pargs.r_opt == oHomedir) + else if (pargs.r_opt == oNoOptions) + default_config = 0; /* --no-options */ + else if (pargs.r_opt == oHomedir) + { opt.homedir = pargs.r.ret_str; + homedir_seen = 1; + } + else if (pargs.r_opt == aDaemon) + daemon_seen = 1; } + /* If --daemon has been given on the command line but not --homedir, + we switch to /etc/dirmngr as default home directory. Note, that + this also overrides the GNUPGHOME environment variable. */ + if (daemon_seen && !homedir_seen) + opt.homedir = DIRMNGR_SYSCONFDIR; + if (default_config) configname = make_filename (opt.homedir, "dirmngr.conf", NULL ); @@ -415,9 +538,12 @@ while (optfile_parse( configfp, configname, &configlineno, &pargs, opts) ) { + if (parse_rereadable_options (&pargs, 0)) + continue; /* Already handled */ switch (pargs.r_opt) { case aServer: + case aDaemon: case aShutdown: case aFlush: case aListCRLs: @@ -471,6 +597,8 @@ case oForce: opt.force = 1; break; + case oSocketName: socket_name = pargs.r.ret_str; break; + default : pargs.err = configfp? 1:2; break; } } @@ -507,7 +635,7 @@ log_info (_("WARNING: running with faked system time %s\n"), tbuf); } - set_debug (debug_level); + set_debug (); /* Get LDAP server list from file. */ if (!ldapfile) @@ -519,20 +647,23 @@ else opt.ldapservers = parse_ldapserver_file (ldapfile); + /* We need to ignore the PIPE signal because the we might log to a + socket and that code handles EPIPE properly. The ldap wrapper + also requires us to ignore this silly signal. Assuan would set + this signal to ignore anyway.*/ + signal (SIGPIPE, SIG_IGN); + + /* Ready. Now to our duties. */ if (!cmd) cmd = aServer; rc = 0; + if (cmd == aServer) { if (argc) wrong_args ("--server"); - /* We need to ignore the PIPE signal because the we might log to - a socket and that code handles EPIPE properly. Assuan would - set this signal to ignore anyway.*/ - signal (SIGPIPE, SIG_IGN); - if (logfile) { log_set_file (logfile); @@ -546,52 +677,204 @@ sleep (debug_wait); log_debug ("... okay\n"); } + + launch_ripper_thread (); + crl_cache_init (); + start_command_handler (-1); + } + else if (cmd == aDaemon) + { + int fd; + pid_t pid; + int len; + struct sockaddr_un serv_addr; + + if (argc) + wrong_args ("--daemon"); - start_command_handler(); + /* Now start with logging to a file if this is desired. */ + if (logfile) + { + log_set_file (logfile); + log_set_prefix (NULL, (JNLIB_LOG_WITH_PREFIX + |JNLIB_LOG_WITH_TIME + |JNLIB_LOG_WITH_PID)); + current_logfile = xstrdup (logfile); + } + + if (strchr (socket_name, ':') ) + { + log_error (_("colons are not allowed in the socket name\n")); + dirmngr_exit (1); + } + if (strlen (socket_name)+1 >= sizeof serv_addr.sun_path ) + { + log_error (_("name of socket too long\n")); + dirmngr_exit (1); + } + + fd = socket (AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) + { + log_error (_("can't create socket: %s\n"), strerror(errno) ); + cleanup (); + dirmngr_exit (1); + } + + 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); + + rc = bind (fd, (struct sockaddr*)&serv_addr, len); + if (rc == -1 && errno == EADDRINUSE) + { + remove (socket_name); + rc = bind (fd, (struct sockaddr*)&serv_addr, len); + } + if (rc == -1) + { + log_error (_("error binding socket to `%s': %s\n"), + serv_addr.sun_path, strerror (errno) ); + close (fd); + dirmngr_exit (1); + } + cleanup_socket = 1; + + if (listen (fd, 5 ) == -1) + { + log_error (_("listen() failed: %s\n"), strerror (errno)); + close (fd); + dirmngr_exit (1); + } + + if (opt.verbose) + log_info (_("listening on socket `%s'\n"), socket_name ); + + fflush (NULL); + pid = pth_fork (); + if (pid == (pid_t)-1) + { + log_fatal (_("fork failed: %s\n"), strerror (errno) ); + dirmngr_exit (1); + } + + if (pid) + { /* We are the parent */ + char *infostr; + + /* Don't let cleanup() remove the socket - the child is + responsible for doing that. */ + cleanup_socket = 0; + + close (fd); + + /* Create the info string: :: */ + if (asprintf (&infostr, "DIRMNGR_INFO=%s:%lu:1", + socket_name, (ulong)pid ) < 0) + { + log_error (_("out of core\n")); + kill (pid, SIGTERM); + dirmngr_exit (1); + } + /* Print the environment string, so that the caller can use + shell's eval to set it */ + if (csh_style) + { + *strchr (infostr, '=') = ' '; + printf ( "setenv %s\n", infostr); + } + else + { + printf ( "%s; export DIRMNGR_INFO;\n", infostr); + } + free (infostr); + exit (0); + /*NEVER REACHED*/ + } /* end parent */ + + + /* + This is the child + */ + + /* Detach from tty and put process into a new session */ + if (!nodetach ) + { + int i; + unsigned int oldflags; + + /* Close stdin, stdout and stderr unless it is the log stream */ + for (i=0; i <= 2; i++) + { + if (!log_test_fd (i) && i != fd ) + close (i); + } + if (setsid() == -1) + { + log_error (_("setsid() failed: %s\n"), strerror(errno) ); + dirmngr_exit (1); + } + + log_get_prefix (&oldflags); + log_set_prefix (NULL, oldflags | JNLIB_LOG_RUN_DETACHED); + opt.running_detached = 1; + } + + if (chdir("/")) + { + log_error (_("chdir to / failed: %s\n"), strerror (errno)); + dirmngr_exit (1); + } + + + launch_ripper_thread (); + crl_cache_init (); + handle_connections (fd); + close (fd); } else if (cmd == aListCRLs) { /* Just list the CRL cache and exit. */ - crl_cache_t cache; - if (argc) wrong_args ("--list-crls"); - cache = crl_cache_init (); - crl_cache_list (cache, stdout); + launch_ripper_thread (); + crl_cache_init (); + crl_cache_list (stdout); } else if (cmd == aLoadCRL) { - crl_cache_t c; - - c = crl_cache_init (); + launch_ripper_thread (); + crl_cache_init (); if (!argc) - rc = crl_cache_load (NULL, c, NULL); + rc = crl_cache_load (NULL, NULL); else { for (; !rc && argc; argc--, argv++) - rc = crl_cache_load (NULL, c, *argv); + rc = crl_cache_load (NULL, *argv); } } else if (cmd == aFetchCRL) { - crl_cache_t c; - FILE *fp; + ksba_reader_t reader; if (argc != 1) wrong_args ("--fetch-crl URL"); - c = crl_cache_init (); - rc = crl_fetch (argv[0], &fp); + launch_ripper_thread (); + crl_cache_init (); + rc = crl_fetch (argv[0], &reader); if (rc) log_error (_("fetching CRL from `%s' failed: %s\n"), argv[0], gpg_strerror (rc)); else { - rc = crl_cache_insert (NULL, c, argv[0], fp); + rc = crl_cache_insert (NULL, argv[0], reader); if (rc) log_error (_("processing CRL from `%s' failed: %s\n"), argv[0], gpg_strerror (rc)); - fclose (fp); + crl_close_reader (reader); } } else if (cmd == aFlush) @@ -663,8 +946,17 @@ static void cleanup (void) { + crl_cache_deinit (); + free_ldapservers_list (opt.ldapservers); opt.ldapservers = NULL; + + if (cleanup_socket) + { + cleanup_socket = 0; + if (socket_name && *socket_name) + remove (socket_name); + } } @@ -832,3 +1124,145 @@ servers = tmp; } } + + + +/* + Stuff used in daemon mode. + */ +/* The signal handler. */ +static void +handle_signal (int signo) +{ + switch (signo) + { + case SIGHUP: + log_info (_("SIGHUP received - " + "re-reading configuration and flushing caches\n")); +/* reread_configuration (); */ + break; + + case SIGUSR1: + log_info (_("SIGUSR1 received - no action defined\n")); + break; + + case SIGUSR2: + log_info (_("SIGUSR2 received - no action defined\n")); + break; + + case SIGTERM: + if (!shutdown_pending) + log_info (_("SIGTERM received - shutting down ...\n")); + else + log_info (_("SIGTERM received - still %d active connections\n"), + active_connections); + shutdown_pending++; + if (shutdown_pending > 2) + { + log_info (_("shutdown forced\n")); + log_info ("%s %s stopped\n", strusage(11), strusage(13) ); + cleanup (); + dirmngr_exit (0); + } + break; + + case SIGINT: + log_info (_("SIGINT received - immediate shutdown\n")); + log_info( "%s %s stopped\n", strusage(11), strusage(13)); + cleanup (); + dirmngr_exit (0); + break; + + default: + log_info (_("signal %d received - no action defined\n"), signo); + } +} + + + +/* Helper to call a connection's main fucntion. */ +static void * +start_connection_thread (void *arg) +{ + int fd = (int)arg; + + active_connections++; + if (opt.verbose) + log_info (_("handler for fd %d started\n"), fd); + + start_command_handler (fd); + + if (opt.verbose) + log_info (_("handler for fd %d terminated\n"), fd); + active_connections--; + + return NULL; +} + + +/* Main loop in daemon mode. */ +static void +handle_connections (int listen_fd) +{ + pth_attr_t tattr; + pth_event_t ev; + sigset_t sigs; + int signo; + struct sockaddr_un paddr; + socklen_t plen = sizeof( paddr ); + int fd; + + 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, "dirmngr"); + + sigemptyset (&sigs ); + sigaddset (&sigs, SIGHUP); + sigaddset (&sigs, SIGUSR1); + sigaddset (&sigs, SIGUSR2); + sigaddset (&sigs, SIGINT); + sigaddset (&sigs, SIGTERM); + ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); + + for (;;) + { + if (shutdown_pending) + { + if (!active_connections) + break; /* ready */ + + /* Do not accept anymore connections but wait for existing + connections to terminate. */ + signo = 0; + pth_wait (ev); + if (pth_event_occurred (ev) && signo) + handle_signal (signo); + continue; + } + + fd = pth_accept_ev (listen_fd, (struct sockaddr *)&paddr, &plen, ev); + if (fd == -1) + { + if (pth_event_occurred (ev)) + { + handle_signal (signo); + continue; + } + log_error (_("accept failed: %s - waiting 1s\n"), strerror (errno)); + pth_sleep (1); + continue; + } + + if (!pth_spawn (tattr, start_connection_thread, (void*)fd)) + { + log_error (_("error spawning connection handler: %s\n"), + strerror (errno) ); + close (fd); + } + } + + pth_event_free (ev, PTH_FREE_ALL); + cleanup (); + log_info ("%s %s stopped\n", strusage(11), strusage(13)); +} Index: dirmngr/src/dirmngr.h diff -u dirmngr/src/dirmngr.h:1.18 dirmngr/src/dirmngr.h:1.19 --- dirmngr/src/dirmngr.h:1.18 Wed Apr 28 11:00:53 2004 +++ dirmngr/src/dirmngr.h Tue Nov 16 19:24:35 2004 @@ -1,5 +1,6 @@ -/* dirmngr.c - LDAP access - * Copyright (C) 2002 Klarälvdalens Datakonsult AB +/* dirmngr.c - Common definitions for the dirmngr + * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * Copyright (C) 2004 g10 Code GmbH * * This file is part of DirMngr. * @@ -38,59 +39,11 @@ #include "../jnlib/strlist.h" #include "../jnlib/dotlock.h" - -#ifdef USE_SIMPLE_GETTEXT - int set_gettext_file( const char *filename ); - const char *gettext( const char *msgid ); -# define _(a) gettext (a) -# define N_(a) (a) -#else -# ifdef HAVE_LOCALE_H -# include -# endif -# ifdef ENABLE_NLS -# include -# define _(a) gettext (a) -# ifdef gettext_noop -# define N_(a) gettext_noop (a) -# else -# define N_(a) (a) -# endif -# else -# define _(a) (a) -# define N_(a) (a) -# endif -#endif /*!USE_SIMPLE_GETTEXT*/ - - -/* Handy malloc macros - use only them */ -#define xtrymalloc(a) gcry_malloc ((a)) -#define xtrycalloc(a,b) gcry_calloc ((a),(b)) -#define xtryrealloc(a,b) gcry_realloc ((a),(b)) -#define xtrystrdup(a) gcry_strdup ((a)) -#define xfree(a) gcry_free ((a)) - -#define xmalloc(a) gcry_xmalloc ((a)) -#define xcalloc(a,b) gcry_xcalloc ((a),(b)) -#define xrealloc(a,b) gcry_xrealloc ((a),(b)) -#define xstrdup(a) gcry_xstrdup ((a)) +#include "i18n.h" +#include "util.h" #define seterr(a) (GNUPG_ ## a) -/* some macros to replace ctype ones and avoid locale problems */ -#define spacep(p) (*(p) == ' ' || *(p) == '\t') -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -/* the atoi macros assume that the buffer has only valid digits */ -#define atoi_1(p) (*(p) - '0' ) -#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) -#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) - /* This objects keeps information about a particular LDAP server and is used as item of a single linked list of servers. */ @@ -116,6 +69,8 @@ int batch; /* batch mode */ const char *homedir;/* configuration directory name */ + int running_detached; /* We are running in detached mode. */ + int force; /* Force loading outdated CRLs. */ int allow_ocsp; /* Allow using OCSP. */ @@ -171,10 +126,11 @@ /*-- server.c --*/ ksba_cert_t get_cert_local (ctrl_t ctrl, const char *issuer); ksba_cert_t get_issuing_cert_local (ctrl_t ctrl, const char *issuer); -void start_command_handler (void); +void start_command_handler (int fd); void dirmngr_status (ctrl_t ctrl, const char *keyword, ...); void dirmngr_tick (ctrl_t ctrl); + #endif /*DIRMNGR_H*/ Index: dirmngr/src/dirmngr_ldap.c diff -u /dev/null dirmngr/src/dirmngr_ldap.c:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/dirmngr_ldap.c Tue Nov 16 19:24:35 2004 @@ -0,0 +1,497 @@ +/* dirmngr-ldap.c - The LDAP helper for dirmngr. + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of DirMngr. + * + * DirMngr is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DirMngr 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 + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +#define JNLIB_NEED_LOG_LOGV +#include "../jnlib/logging.h" +#include "../jnlib/argparse.h" +#include "../jnlib/stringhelp.h" +#include "../jnlib/mischelp.h" +#include "../jnlib/strlist.h" + +#include "i18n.h" +#include "util.h" +#include "no-libgcrypt.h" + +#define DEFAULT_LDAP_TIMEOUT 100 /* Arbitrary long timeout. */ + + +/* Constants for the options. */ +enum + { + oQuiet = 'q', + oVerbose = 'v', + + oTimeout = 500, + oMulti, + oHost, + oPort, + oUser, + oPass, + oEnvPass, + oDN, + oFilter, + oAttr, + + oDummy + }; + + +/* The list of options as used by the argparse.c code. */ +static ARGPARSE_OPTS opts[] = { + { oVerbose, "verbose", 0, N_("verbose") }, + { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, + { oTimeout, "timeout", 1, N_("|N|set LDAP timeout to N seconds")}, + { oMulti, "multi", 0, N_("return all values in" + " a record oriented format")}, + { oHost, "host", 2, N_("|NAME|connect to host NAME")}, + { oPort, "port", 1, N_("|N|connect to port N")}, + { oUser, "user", 2, N_("|NAME|use user NAME for authentication")}, + { oPass, "pass", 2, N_("|PASS|use password PASS" + " for authentication")}, + { oEnvPass, "env-pass", 0, N_("take password from $DIRMNGR_LDAP_PASS")}, + { oDN, "dn", 2, N_("|STRING|query DN STRING")}, + { oFilter, "filter", 2, N_("|STRING|use STRING as filter expression")}, + { oAttr, "attr", 2, N_("|STRING|return the attribute STRING")}, + {0} +}; + + +/* The usual structure for the program flags. */ +static struct +{ + int quiet; + int verbose; + struct timeval timeout; + int multi; + + /* Note that we can't use const for the strings because ldap_* are + not defined that way. */ + char *user; /* Authentication user. */ + char *pass; /* Authentication password. */ + char *host; /* Override host. */ + int port; /* Override port. */ + char *dn; /* Override DN. */ + char *filter;/* Override filter. */ + char *attr; /* Override attribute. */ +} opt; + + + +/* Prototypes. */ +static int process_url (const char *url); + + + +/* Function called by argparse.c to display information. */ +static const char * +my_strusage (int level) +{ + const char *p; + + switch(level) + { + case 11: p = "dirmngr_ldap"; + break; + case 13: p = VERSION; break; + case 14: p = "Copyright (C) 2004 g10 Code GmbH"; break; + case 17: p = PRINTABLE_OS_NAME; break; + case 19: p = + _("Please report bugs to " PACKAGE_BUGREPORT ".\n"); + break; + case 1: + case 40: p = + _("Usage: dirmngr_ldap [options] [URL] (-h for help)\n"); + break; + case 41: p = + _("Syntax: dirmngr_ldap [options] [URL]\n" + "Internal LDAP helper for Dirmngr.\n" + "Interface and options may change without notice.\n"); + break; + + default: p = NULL; + } + return p; +} + + +static void +i18n_init (void) +{ +#ifdef USE_SIMPLE_GETTEXT + set_gettext_file (PACKAGE); +#else +# ifdef ENABLE_NLS + setlocale (LC_ALL, "" ); + bindtextdomain (PACKAGE, LOCALEDIR); + textdomain (PACKAGE); +# endif +#endif +} + + +int +main (int argc, char **argv ) +{ + ARGPARSE_ARGS pargs; + int any_err = 0; + + set_strusage (my_strusage); + log_set_prefix ("dirmngr_ldap", JNLIB_LOG_WITH_PREFIX); + + /* Setup I18N. */ + i18n_init(); + + /* LDAP defaults */ + opt.timeout.tv_sec = DEFAULT_LDAP_TIMEOUT; + opt.timeout.tv_usec = 0; + + + /* Parse the command line. */ + pargs.argc = &argc; + pargs.argv = &argv; + pargs.flags= 1; /* Do not remove the args. */ + while (arg_parse (&pargs, opts) ) + { + switch (pargs.r_opt) + { + case oVerbose: opt.verbose++; break; + case oQuiet: opt.quiet++; break; + case oTimeout: + opt.timeout.tv_sec = pargs.r.ret_int; + opt.timeout.tv_usec = 0; + break; + case oMulti: opt.multi = 1; break; + case oUser: opt.user = pargs.r.ret_str; break; + case oPass: opt.pass = pargs.r.ret_str; break; + case oEnvPass: + opt.pass = getenv ("DIRMNGR_LDAP_PASS"); + break; + case oHost: opt.host = pargs.r.ret_str; break; + case oPort: opt.port = pargs.r.ret_int; break; + case oDN: opt.dn = pargs.r.ret_str; break; + case oFilter: opt.filter = pargs.r.ret_str; break; + case oAttr: opt.attr = pargs.r.ret_str; break; + + default : pargs.err = 2; break; + } + } + if (opt.port < 0 || opt.port > 65535) + log_error (_("invalid port number %d\n"), opt.port); + + sleep (5); + + if (log_get_errorcount (0)) + exit (2); + + if (argc < 1) + usage (1); + + for (; argc; argc--, argv++) + if (process_url (*argv)) + any_err = 1; + + return any_err; +} + + +/* Helper for fetch_ldap(). */ +static int +print_ldap_entries (LDAP *ld, LDAPMessage *msg, char *want_attr) +{ + LDAPMessage *item; + int any = 0; + + for (item = ldap_first_entry (ld, msg); item; + item = ldap_next_entry (ld, item)) + { + BerElement *berctx; + char *attr; + + if (opt.verbose > 1) + log_info (_("scanning result for attribute `%s'\n"), + want_attr? want_attr : "[all]"); + + if (opt.multi) + { /* Write item marker. */ + if (fwrite ("I\0\0\0\0", 5, 1, stdout) != 1) + { + log_error (_("error writing to stdout: %s\n"), + strerror (errno)); + return -1; + } + } + + + for (attr = ldap_first_attribute (ld, item, &berctx); attr; + attr = ldap_next_attribute (ld, item, berctx)) + { + struct berval **values; + int idx; + + if (opt.verbose > 1) + log_info (_(" available attribute `%s'\n"), attr); + + /* I case we want only one attribute we do a case + insensitive compare without the optional extension + (i.e. ";binary"). case insensive is not really correct + but the best we can do. */ + if (want_attr) + { + char *cp = strchr (attr, ';'); + if (cp) + *cp = 0; + if ( ascii_strcasecmp (want_attr, attr) ) + { + ldap_memfree (attr); + continue; /* Not found: Try next attribute. */ + } + if (cp) + *cp = ';'; + } + + values = ldap_get_values_len (ld, item, attr); + + if (!values) + { + if (opt.verbose) + log_info (_("attribute `%s' not found\n"), attr); + ldap_memfree (attr); + continue; + } + + if (opt.verbose) + log_info (_("found attribute `%s'\n"), attr); + + if (opt.multi) + { /* Write attribute marker. */ + unsigned char tmp[5]; + size_t n = strlen (attr); + + tmp[0] = 'A'; + tmp[1] = (n >> 24); + tmp[2] = (n >> 16); + tmp[3] = (n >> 8); + tmp[4] = (n); + if (fwrite (tmp, 5, 1, stdout) != 1 + || fwrite (attr, n, 1, stdout) != 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; + } + } + + for (idx=0; values[idx]; idx++) + { + if (opt.multi) + { /* Write value marker. */ + unsigned char tmp[5]; + size_t n = values[0]->bv_len; + + tmp[0] = 'V'; + tmp[1] = (n >> 24); + tmp[2] = (n >> 16); + tmp[3] = (n >> 8); + tmp[4] = (n); + + if (fwrite (tmp, 5, 1, stdout) != 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; + } + } + if (fwrite (values[0]->bv_val, values[0]->bv_len, + 1, stdout) != 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; + } + any = 1; + if (!opt.multi) + break; /* Print only the first value. */ + } + ldap_value_free_len (values); + ldap_memfree (attr); + if (want_attr || !opt.multi) + break; /* We only want to return the first attribute. */ + } + ber_free (berctx, 0); + } + + return any?0:-1; +} + + + +/* Helper for the URL based LDAP query. */ +static int +fetch_ldap (const char *url, const LDAPURLDesc *ludp) +{ + LDAP *ld; + LDAPMessage *msg; + int rc = 0; + char *host, *dn, *filter, *attrs[2], *attr; + int port; + + host = opt.host? opt.host : ludp->lud_host; + port = opt.port? opt.port : ludp->lud_port; + dn = opt.dn? opt.dn : ludp->lud_dn; + filter = opt.filter? opt.filter : ludp->lud_filter; + attrs[0] = opt.attr? opt.attr : ludp->lud_attrs? ludp->lud_attrs[0]:NULL; + attrs[1] = NULL; + attr = attrs[0]; + + if (!port) + port = (ludp->lud_scheme && !strcmp (ludp->lud_scheme, "ldaps"))? 636:389; + + if (opt.verbose) + { + log_info (_("processing url `%s'\n"), url); + if (opt.user) + log_info (_(" user `%s'\n"), opt.user); + if (opt.pass) + log_info (_(" pass `%s'\n"), *opt.pass?"*****":""); + if (host) + log_info (_(" host `%s'\n"), host); + log_info (_(" port %d\n"), port); + if (dn) + log_info (_(" DN `%s'\n"), dn); + if (filter) + log_info (_(" filter `%s'\n"), filter); + if (opt.multi && !opt.attr && ludp->lud_attrs) + { + int i; + for (i=0; ludp->lud_attrs[i]; i++) + log_info (_(" attr `%s'\n"), ludp->lud_attrs[i]); + } + else if (attr) + log_info (_(" attr `%s'\n"), attr); + } + + + if (!host || !*host) + { + log_error (_("no host name in `%s'\n"), url); + return -1; + } + if (!opt.multi && !attr) + { + log_error (_("no attribute given for query `%s'\n"), url); + return -1; + } + + if (!opt.multi && !opt.attr + && ludp->lud_attrs && ludp->lud_attrs[0] && ludp->lud_attrs[1]) + log_info (_("WARNING: using first attribute only\n")); + + + ld = ldap_init (host, port); + if (!ld) + { + log_error (_("LDAP init to `%s:%d' failed: %s\n"), + host, port, strerror (errno)); + return -1; + } + if (ldap_simple_bind_s (ld, opt.user, opt.pass)) + { + log_error (_("binding to `%s:%d' failed: %s\n"), + host, port, strerror (errno)); + /* FIXME: Need deinit (ld)? */ + return -1; + } + + rc = ldap_search_st (ld, dn, ludp->lud_scope, filter, + opt.multi && !opt.attr && ludp->lud_attrs? + ludp->lud_attrs:attrs, + 0, + &opt.timeout, &msg); + if (rc) + { + log_error (_("searching `%s' failed: %s\n"), + url, ldap_err2string (rc)); + /* FIXME: Need deinit (ld)? */ + /* Hmmm: Do we need to released MSG in case of an error? */ + return -1; + } + + + rc = print_ldap_entries (ld, msg, opt.multi? NULL:attr); + + ldap_msgfree (msg); + /* FIXME: Need deinit (ld)? */ + return rc; +} + + + + +/* Main processing. Take the URL and run the DLAP query. The result + is printed to stdout, errors are logged to the log stream. */ +static int +process_url (const char *url) +{ + int rc; + LDAPURLDesc *ludp = NULL; + + + if (!ldap_is_ldap_url (url)) + { + log_error (_("`%s' is not an LDAP URL\n"), url); + return -1; + } + + if (ldap_url_parse (url, &ludp)) + { + log_error (_("`%s' is an invalid LDAP URL\n"), url); + return -1; + } + + + rc = fetch_ldap (url, ludp); + + ldap_free_urldesc (ludp); + return rc; +} + Index: dirmngr/src/http.c diff -u dirmngr/src/http.c:1.5 dirmngr/src/http.c:1.6 --- dirmngr/src/http.c:1.5 Fri Apr 2 20:05:19 2004 +++ dirmngr/src/http.c Tue Nov 16 19:24:35 2004 @@ -392,7 +392,7 @@ { if (buffer) { - sprintf (buffer, "%02X", *string); + sprintf (buffer, "%%%02X", *string); buffer += 3; } n += 3; Index: dirmngr/src/i18n.h diff -u /dev/null dirmngr/src/i18n.h:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/i18n.h Tue Nov 16 19:24:35 2004 @@ -0,0 +1,48 @@ +/* i18n.h + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of DirMngr. + * + * DirMngr is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DirMngr 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 + */ + +#ifndef I18N_H +#define I18N_H + + +#ifdef USE_SIMPLE_GETTEXT + int set_gettext_file( const char *filename ); + const char *gettext( const char *msgid ); +# define _(a) gettext (a) +# define N_(a) (a) +#else +# ifdef HAVE_LOCALE_H +# include +# endif +# ifdef ENABLE_NLS +# include +# define _(a) gettext (a) +# ifdef gettext_noop +# define N_(a) gettext_noop (a) +# else +# define N_(a) (a) +# endif +# else +# define _(a) (a) +# define N_(a) (a) +# endif +#endif /*!USE_SIMPLE_GETTEXT*/ + +#endif /*I18N_H*/ Index: dirmngr/src/ldap.c diff -u dirmngr/src/ldap.c:1.32 dirmngr/src/ldap.c:1.33 --- dirmngr/src/ldap.c:1.32 Thu May 13 08:55:44 2004 +++ dirmngr/src/ldap.c Tue Nov 16 19:24:35 2004 @@ -1,5 +1,5 @@ /* ldap.c - LDAP access - * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * Copyright (C) 2002 Klarälvdalens Datakonsult AB * Copyright (C) 2003 g10 Code GmbH * * This file is part of DirMngr. @@ -24,578 +24,686 @@ #include #include #include -#include #include +#include +#include +#include +#include /* fixme: remove it */ +#include +#include #include "crlfetch.h" #include "dirmngr.h" #include "misc.h" +/* In case sysconf does not return a value we need to have a limit. */ +#ifdef _POSIX_OPEN_MAX +#define MAX_OPEN_FDS _POSIX_OPEN_MAX +#else +#define MAX_OPEN_FDS 20 +#endif + + +#define UNENCODED_URL_CHARS "abcdefghijklmnopqrstuvwxyz" \ + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ + "01234567890" \ + "$-_.+!*'()," +#define USERCERTIFICATE "userCertificate" +#define CACERTIFICATE "caCertificate" -#define CERTATTR "userCertificate" -#define CERTATTRBIN CERTATTR ";binary" -#define CACERTATTR "caCertificate" -#define CACERTATTRBIN CACERTATTR ";binary" - -struct cert_fetch_context_s { - LDAP *ld; - strlist_t query_list; /* List of all prepared queries. */ - strlist_t query; /* Pointer into this list. */ - LDAPMessage *result; - int bercount; - struct berval **bervalues; - char *base; -}; +/* Definition for the context of the cert fetch functions. */ +struct cert_fetch_context_s +{ + ksba_reader_t reader; /* The reader used (shallow copy). */ + unsigned char *tmpbuf; /* Helper buffer. */ + size_t tmpbufsize; /* Allocated size of tmpbuf. */ +}; -/* Fetch the value attr, put result in value, length in valuelen. - Returns 0 on success or an gpg error code. - */ -static gpg_error_t -get_attr_from_result_ldap (LDAP * ld, LDAPMessage * msg, const char *attr, - unsigned char **value, size_t * valuelen) +/* To keep track of the LDAp wrapper state we use this structure. */ +struct wrapper_context_s { - LDAPMessage *item; - struct berval **values; + struct wrapper_context_s *next; - item = ldap_first_entry (ld, msg); - if (!item) - return gpg_error (GPG_ERR_NO_CRL_KNOWN); + pid_t pid; /* The pid of the wrapper process. */ + int fd; /* Connected with stdout of the ldap wrapper. */ + int fd_error; /* Set to the errno of the last read error if any. */ + int log_fd; /* Connected with stdoerr of the ldap wrapper. */ + 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. */ +}; - if (DBG_LOOKUP) - log_info ("get_attr_from_result_ldap `%s'\n", attr); - values = ldap_get_values_len (ld, item, attr); - if (values && opt.verbose) - log_info (_("found attribute `%s'\n"), attr); - if (!values) - { - /* Try again without or with ";binary" .. which worked with some - strange LDAP servers. */ - const char *s; - char *newattr; - s = memistr (attr, strlen (attr), ";binary"); - if (s) - { - newattr = xstrdup (attr); - newattr[s - attr] = 0; - } - else - { - newattr = xmalloc (strlen (attr) + 7 + 1); - strcpy (stpcpy (newattr, attr), ";binary"); - } +/* 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; - values = ldap_get_values_len (ld, item, newattr); - if (values && opt.verbose) - log_info (_("found attributes `%s' at second try\n"), newattr); - xfree (newattr); - } - if (values) +#if 0 +/* Add HOST and PORT to our list of LDAP servers. Fixme: We should + better use an extra list of servers. */ +static void +add_server_to_servers (const char *host, int port) +{ + ldap_server_t server; + ldap_server_t last = NULL; + const char *s; + + for (server=opt.ldapservers; server; server = server->next) { - *valuelen = values[0]->bv_len; - *value = xmalloc (*valuelen * sizeof (char)); - memcpy (*value, values[0]->bv_val, *valuelen); - ldap_value_free_len (values); - return 0; + if (!strcmp (server->host, host) && server->port == port) + return; /* already in list... */ + last = server; } + + /* We assume that the host names are all supplied by our + configuration files and thus are sane. To keep this assumption + we must reject all invalid host names. */ + for (s=host; *s; s++) + if (!strchr ("abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "01234567890.-", *s)) + { + log_error (_("invalid char 0x%02x in host name" + " - not added\n"), *s); + return; + } + + log_info (_("adding `%s:%d' to the ldap server list\n"), host, port); + server = xcalloc (1, sizeof *s); + server->host = xstrdup (host); + server->port = port; + if (last) + last->next = server; else - return gpg_error (GPG_ERR_NO_CRL_KNOWN); + opt.ldapservers = server; } +#endif -/* The cookie structure used for returning the results from a - attr_fetch_ldap query. */ -struct attr_fetch_fun_cookie_s { - int eof_reached; /* True if we already encountered EOF. */ - gpg_error_t err; /* The error code from the last operation. */ - int sys_err; /* The system error number. */ - char *attr; /* The attribute used for the search. */ - LDAP *ld; - int msgid; - LDAPMessage *result; - LDAPMessage *item; - struct berval **values; - int nread; -}; +/* Release the wrapper context and kill a running wrapper process. */ +static void +destroy_wrapper (struct wrapper_context_s *ctx) +{ + if (ctx->pid != (pid_t)(-1)) + kill (ctx->pid, SIGTERM); + ksba_reader_release (ctx->reader); + if (ctx->fd) + close (ctx->fd); + if (ctx->log_fd) + close (ctx->log_fd); + xfree (ctx->line); + xfree (ctx); +} -/* The reader function used for returning the results from a - attr_fetch_ldap query. */ -static int -attr_fetch_fun_reader (void *cookie, char *buffer, int size) +/* Print the content of LINE to thye log stream but make sure to only + print complete lines. Using NULL for LINE will flush any pending + output. LINE may be modified by this fucntion. */ +static void +print_log_line (struct wrapper_context_s *ctx, char *line) { - struct attr_fetch_fun_cookie_s *h = cookie; - int rc; - struct timeval timeout, tout; + char *s; + size_t n; - if (h->eof_reached || !size) - return 0; + if (!line) + { + if (ctx->line && ctx->linelen) + { - dirmngr_tick (NULL); - if (h->err) + log_info ("%s\n", ctx->line); + ctx->linelen = 0; + } + return; + } + + while ((s = strchr (line, '\n'))) { - errno = h->sys_err; - return -1; + *s = 0; + if (ctx->line && ctx->linelen) + { + log_info ("%s", ctx->line); + ctx->linelen = 0; + log_printf ("%s\n", line); + } + else + log_info ("%s\n", line); + line = s + 1; } - - for (;;) + n = strlen (line); + if (n) { - /* Any pending stuff we need to return first? */ - if (h->values && h->values[0] && h->values[0]->bv_len) + if (ctx->linelen + n + 1 >= ctx->linesize) { - if (h->nread < h->values[0]->bv_len) + char *tmp; + size_t newsize; + + newsize = ctx->linesize + ((n + 255) & ~255) + 1; + tmp = (ctx->line ? xtryrealloc (ctx->line, newsize) + : xtrymalloc (newsize)); + if (!tmp) { - if (h->nread + size > h->values[0]->bv_len) - size = h->values[0]->bv_len - h->nread; - memcpy (buffer, h->values[0]->bv_val + h->nread, size); - h->nread += size; - return size; + log_error (_("error printing log line: %s\n"), strerror (errno)); + return; } - if (h->values) + ctx->line = tmp; + ctx->linesize = newsize; + } + memcpy (ctx->line + ctx->linelen, line, n); + ctx->linelen += n; + ctx->line[ctx->linelen] = 0; + } +} + + + +/* This function is run by a separate thread to maintain the list of + wrappers and to log error messages from these wrappers. */ +void * +ldap_wrapper_thread (void *dummy) +{ + fd_set read_fds; + int nfds, n; + struct timeval tv; + struct wrapper_context_s *ctx, *ctx_prev; + char line[256]; + + for (;;) + { + FD_ZERO (&read_fds); + + for (nfds = -1, ctx = wrapper_list; ctx; ctx = ctx->next) + { + if (ctx->log_fd != -1) { - ldap_value_free_len (h->values); - h->values = NULL; + FD_SET (ctx->log_fd, &read_fds); + if (ctx->log_fd > nfds) + nfds = ctx->log_fd; } } + nfds++; - /* If we still have a result from the last round, process that one. */ - if (h->result) + tv.tv_sec = 1; + tv.tv_usec = 0; + nfds = pth_select (nfds, &read_fds, NULL, NULL, &tv); + if ( nfds < 0 ) { - if (!h->item) - h->item = ldap_first_entry (h->ld, h->result); - else - h->item = ldap_next_entry (h->ld, h->item); + log_error (_("select failed: %s\n"), strerror (errno)); + pth_sleep (10); + continue; } - - /* Continue if we still hold an item. */ - if (h->result && h->item) + /* Note that there is no need to lock the list because we always + add entries at the head and thus traversing the list will + even work if we have a context switch in waitpid (which should + anyway only happen with Pth's hard system call mapping). */ + for (ctx = wrapper_list; ctx; ctx = ctx->next) { - if (h->values) - ldap_value_free_len (h->values); - h->values = ldap_get_values_len (h->ld, h->item, h->attr); - - if (h->values && opt.verbose) - log_info (_("found attribute `%s'\n"), h->attr); - - if (!h->values) + /* Check whether there is any logging to be done. */ + if (nfds && ctx->log_fd != -1 && FD_ISSET (ctx->log_fd, &read_fds)) { - /* Try again without or with ";binary" .. which worked with some - strange LDAP servers. */ - const char *s; - char *newattr; - - s = memistr (h->attr, strlen (h->attr), ";binary"); - if (s) - { - newattr = xstrdup (h->attr); - newattr[s - newattr] = 0; + /* Note that we do not need to use pth_read here because + we already know that the read won't block. */ + do + n = read (ctx->log_fd, line, sizeof line - 1); + while (n < 0 && errno == EINTR); + if (n < 0) + { + print_log_line (ctx, NULL); + log_error (_("error reading log from ldap wrapper %d: %s\n"), + ctx->pid, strerror (errno)); } - else + else if (!n) /* EOF */ { - newattr = xmalloc (strlen (h->attr) + 7 + 1); - strcpy (stpcpy (newattr, h->attr), ";binary"); + print_log_line (ctx, NULL); + close (ctx->log_fd); + ctx->log_fd = -1; + } + else + { + line[n] = 0; + print_log_line (ctx, line); } - - h->values = ldap_get_values_len (h->ld, h->item, newattr); - if (h->values && opt.verbose) - log_info (_("found attributes `%s' at second try\n"), newattr); - xfree (newattr); } - } - /* If there is stuff to return, jump to the top. Note, that we - only handle the first item in the list of values. */ - if (h->values && h->values[0] && h->values[0]->bv_len) - continue; - - /* Wait for the next result. */ - timeout.tv_sec = 0; - timeout.tv_usec = 0; - retry: - tout.tv_sec = 0; - tout.tv_usec = 100000; /* Temporary timeout after 100 ms. */ - if (h->result) - { - ldap_msgfree (h->result); - h->result = NULL; - } - rc = ldap_result (h->ld, h->msgid, 0, &tout, &h->result); - if (!rc) - { - /* We don't take an updated timeout into account, not all - systems do this properly in select and we don't know whether - ldap_result fixes for that. We also ignore the usec which is - not a problem as we set opt.ldaptimeout only to full seconds. - The timeout is restarted with every bit of data we get. */ - timeout.tv_usec += 100000; - while (timeout.tv_usec >= 1000000) + /* Check whether the process is still running. */ + if (ctx->pid != (pid_t)(-1)) { - timeout.tv_sec++; - timeout.tv_usec -= 1000000; - } - if (timeout.tv_sec < opt.ldaptimeout.tv_sec) - { - dirmngr_tick (NULL); - goto retry; + int i, status; + + while ( (i=waitpid (ctx->pid, &status, WNOHANG)) == -1 + && errno == EINTR) + ; + if (i == -1) + log_error (_("waiting for ldap wrapper %d failed: %s\n"), + (int)ctx->pid, strerror (errno)); + else if (i) + { + if (!WIFEXITED (status)) + log_info (_("ldap wrapper %d ready: terminated\n"), + (int)ctx->pid); + else + log_info (_("ldap wrapper %d ready: exit status %d\n"), + (int)ctx->pid, WEXITSTATUS (status)); + ctx->ready = 1; + ctx->pid = (pid_t)(-1); + } } - log_error (_("timeout while waiting for ldap_search result\n")); - h->err = gpg_error (GPG_ERR_TIMEOUT); - h->sys_err = errno = ETIMEDOUT; - return -1; - } - if (rc == -1) - { - log_error (_("ldap_result for an ldap_search failed: %s\n"), - strerror (errno)); - h->sys_err = errno; - h->err = gpg_error (GPG_ERR_NO_CRL_KNOWN); - return -1; - } - else if (rc == LDAP_RES_SEARCH_ENTRY) - ; /* Yep, we got a result. */ - else if (rc == LDAP_RES_SEARCH_RESULT) - { - int errcode; - - rc = ldap_parse_result (h->ld, h->result, &errcode, NULL, NULL, - NULL, NULL, 0); - if (rc) - log_error (_("ldap_parse_result failed\n")); - else - { - if (errcode) - log_info (_("ldap search result is: %s\n"), - ldap_err2string (errcode)); - } - h->eof_reached = 1; - return 0; - } - else - { - log_error (_("unexpected message type %d " - "returned for ldap_search\n"), rc); - h->sys_err = errno = 0; - h->err = gpg_error (GPG_ERR_NO_CRL_KNOWN); - return -1; + /* Check whether we should terminate the process. */ } + + /* Use a separate loop to check whether ready marked wrappers + may be removed. We may only do so if the ksba reader object + is not anymore in use. */ + again: + for (ctx_prev=NULL, ctx=wrapper_list; ctx; ctx_prev=ctx, ctx=ctx->next) + if (ctx->ready && !ctx->reader) + { + if (ctx_prev) + ctx_prev->next = ctx->next; + else + wrapper_list = ctx->next; + destroy_wrapper (ctx); + /* We need to restart because destroy_wrapper might have + done a context switch. */ + goto again; + } } - /*NOT REACHED*/ + /*NOTREACHED*/ } -/* The closer function used for returning the results from a - attr_fetch_ldap query. */ -static int -attr_fetch_fun_closer (void *cookie) + +/* This function is to be used to release a context associated with the + given reader object. */ +void +ldap_wrapper_release_context (ksba_reader_t reader) { - struct attr_fetch_fun_cookie_s *h = cookie; - - if (h->values) - ldap_value_free_len (h->values); - if (h->result) - { - ldap_msgfree (h->result); - h->result = NULL; - } - xfree (h->attr); - ldap_unbind (h->ld); - xfree (h); - return 0; + struct wrapper_context_s *ctx; + int fd; + + if (!reader ) + return; + + for (ctx=wrapper_list; ctx; ctx=ctx->next) + if (ctx->reader == reader) + { + ctx->reader = NULL; + if (ctx->fd != -1) + { + fd = ctx->fd; + ctx->fd = -1; + close (fd); + } + break; + } } -/* Perform an LDAP query. Returns an gpg error code or 0 on success. - The function returns a new stream at R_FP. */ -static gpg_error_t -attr_fetch_ldap_internal (const char *host, int port, - const char *user, const char *pass, - const char *dn, const char *attr, - FILE **r_fp) +/* This is the callback used by the ldap wrapper to feed the ksab + reader with the wrappers stdout. See the description of + ksba_reader_set_cb for details. */ +static int +reader_callback (void *cb_value, char *buffer, size_t count, size_t *nread) { - gpg_error_t err; - struct timeval timeout; - char *attrs[2]; - int rc; - int msgid; - LDAPMessage *result; - LDAP *ld; - struct attr_fetch_fun_cookie_s *cookie; - - *r_fp = NULL; - - attrs[0] = xstrdup (attr); - attrs[1] = NULL; - - if (DBG_LOOKUP) - log_debug ("fetching attribute `%s' from '%s:%d' for DN '%s'\n", - attr, host, port, dn); - - ld = ldap_init (host, port); - if (!ld) - { - log_error (_("ldap_init failed for '%s:%d': %s\n"), - host, port, strerror (errno)); - /* We do not return the system error because the host might - simply not be available and the user is not intersted inthese - details. */ - return gpg_error (GPG_ERR_NO_CRL_KNOWN); - } - msgid = ldap_simple_bind (ld, user, pass); - if (msgid == -1) - { - log_error (_("ldap_simple_bind failed for user '%s': %s\n"), - user? user : _("[none]"), strerror (errno)); - /* According to the documentation a variable ld->ld_errno will - be set. However, that structure is private and thus we can't - access. So we assume that the standard errno is used. */ - xfree (attrs[0]); - ldap_unbind (ld); - return gpg_error (GPG_ERR_NO_CRL_KNOWN); - } - - dirmngr_tick (NULL); - timeout = opt.ldaptimeout; - rc = ldap_result (ld, msgid, 0, &timeout, &result); - if (rc != LDAP_RES_BIND) - { - if (rc == -1) - log_error (_("ldap_result for bind failed: %s\n"), strerror (errno)); - else if (!rc) - log_error (_("timeout while waiting for ldap_bind to complete\n")); - else - { - log_error (_("unexpected message type %d returned for ldap_bind\n"), - rc); - ldap_msgfree (result); - } - xfree (attrs[0]); - ldap_unbind (ld); - return gpg_error (GPG_ERR_NO_CRL_KNOWN); - } - ldap_msgfree (result); - result = NULL; - - /* Start the search. */ - dirmngr_tick (NULL); - msgid = ldap_search (ld, dn, LDAP_SCOPE_BASE, "objectclass=*", attrs, 0); - if (msgid == -1) - { - log_error (_("ldap_search failed: %s\n"), strerror (errno)); - xfree (attrs[0]); - ldap_unbind (ld); - return gpg_error (GPG_ERR_NO_CRL_KNOWN); - } - - /* Setup the stream. */ - cookie = xtrycalloc (1, sizeof *cookie); - if (!cookie) + struct wrapper_context_s *ctx = cb_value; + size_t nleft = count; + + /* FIXME: We might want to add some internal buffering becuase the + ksba code does not not any buffering for itself (because a ksba + reader may be detached from another stream to read other data and + the it would be cumbersome to get back already buffered + stuff). */ + + if (!buffer && !count && !nread) + return -1; /* Rewind is not supported. */ + + /* If we ever encountered a read error don't allow to continue and + possible overwrite the last error cause. Bail out alos if the + file descriptor has been closed. */ + if (ctx->fd_error || ctx->fd == -1) { - err = gpg_error_from_errno (errno); - xfree (attrs[0]); - ldap_unbind (ld); - return err; + *nread = 0; + return -1; } - cookie->ld = ld; - cookie->msgid = msgid; - cookie->attr = attrs[0]; - *r_fp = funopen (cookie, attr_fetch_fun_reader, NULL, NULL, - attr_fetch_fun_closer); - if (!*r_fp) + while (nleft > 0) { - err = gpg_error_from_errno (errno); - attr_fetch_fun_closer (cookie); - return err; + int n = pth_read ( ctx->fd, buffer, nleft ); + if (n < 0 && errno == EINTR) + n = 0; + else if (n < 0) + { + ctx->fd_error = errno; + close (ctx->fd); + ctx->fd = -1; + return -1; + } + else if (!n) + { + if (nleft == count) + { + return -1; /* EOF. */ + } + break; + } + nleft -= n; + buffer += n; } + *nread = count - nleft; return 0; + } +/* Fork and exec the LDAP wrapper and returns a new libksba reader + object at READER. ARGV is a NULL terminated list or argumenst for + the wrapper; however the function adds the program's name as the + first arg. The function returns 0 on success or an error code. -/* Perform an LDAP query on all configured servers. On error the - error code of the last try is returned. */ -gpg_error_t -attr_fetch_ldap (const char *dn, const char *attr, FILE **r_fp) -{ - struct ldap_server_s *server; - gpg_error_t err = gpg_error (GPG_ERR_CONFIGURATION); - - for (server = opt.ldapservers; server; server = server->next) - { - err = attr_fetch_ldap_internal (server->host, server->port, - server->user, server->pass, - dn, attr, r_fp); - if (!err) - break; /* Probably found a result. Ready. */ - } - return err; -} + We can't use LDAP directly for these reasons: + 1. On some systems the LDAP library uses (indirectly) pthreads and + that is not compatible with PTh. + + 2. It is huge library in particular if TLS comes into play. So + problems with unfreed memory might turn up and we don't want + this in a long running daemon. + + 3. There is no easy way for timeouts. In particular the timeout + value does not work for DNS lookups (well, this is usual) and it + seems not to work while loading a large attribute like a + CRL. Having a separate process allows us to either tell than + process to commit suicide or have our own housekepping function + kill it after some time. The latter also allows proper + cancellation of a query at any point. + + 4. Given that we are going out to the network and usually get back + a long response, the frok/exec overhead is acceptable. -/* Helper for the URL based LDAP query. */ + Special hack to avoid passing a password through the command line + which is gloabbally visible: If the first element of ARGV is + "--pass" it will be removed and instead the environment variable + DIRMNGR_LDAP_PASS will be set to the next value of ARGV. On modern + OSes the environment is not visible to other other user. For those + old systems where it can't be avoided, we don't want to go into the + hassle of passing the password via stdin; it's just too complicated + and an LDAP password used for public directory lookups should be + that confidential. + */ static gpg_error_t -url_fetch_ldap_internal (const LDAPURLDesc *ludp, const char *attr, - unsigned char **value, size_t * valuelen) +ldap_wrapper (ksba_reader_t *reader, const char *argv[]) { gpg_error_t err; - LDAPMessage *result; - LDAP *ld; - int rc; + pid_t pid; + int rp[2], rp2[2]; + struct wrapper_context_s *ctx; + + /* 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 modules to the logging on its own. Given that we anyway + need a way to rip the child process and is best done using a + general ripping thread, that thread can do the logging too. */ - ld = ldap_init (ludp->lud_host, ludp->lud_port); - if (!ld) + *reader = NULL; + + if (pipe (rp) == -1) { - log_error (_("%s failed for `"), "ldap_init"); - print_sanitized_string (log_get_stream (), ludp->lud_host, 0); - log_printf (":%d': %s\n", ludp->lud_port, strerror (errno)); - return gpg_error (GPG_ERR_NO_CRL_KNOWN); + err = gpg_error_from_errno (errno); + log_error (_("error creating a pipe: %s\n"), strerror (errno)); + return err; } - if (ldap_simple_bind_s (ld, 0, 0)) + if (pipe (rp2) == -1) { - log_error (_("%s failed for `"), "ldap_simple_bind"); - print_sanitized_string (log_get_stream (), ludp->lud_host, 0); - log_printf (":%d': %s\n", ludp->lud_port, strerror (errno)); - return gpg_error (GPG_ERR_NO_CRL_KNOWN); + err = gpg_error_from_errno (errno); + log_error (_("error creating a pipe: %s\n"), strerror (errno)); + close (rp[0]); + close (rp[1]); + return err; } - - rc = ldap_search_st (ld, ludp->lud_dn, ludp->lud_scope, - ludp->lud_filter, ludp->lud_attrs, 0, - &opt.ldaptimeout, &result); - if (rc) + + pid = fork (); + if (pid == -1) { - log_error (_("%s failed for `"), "ldap_search"); - print_sanitized_string (log_get_stream (), ludp->lud_host, 0); - log_printf (":%d': %s\n", ludp->lud_port, strerror (errno)); - return gpg_error (GPG_ERR_NO_CRL_KNOWN); + err = gpg_error_from_errno (errno); + log_error (_("error forking process: %s\n"), strerror (errno)); + close (rp[0]); + close (rp[1]); + close (rp2[0]); + close (rp2[1]); + return err; } - err = get_attr_from_result_ldap (ld, result, - ludp->lud_attrs? ludp->lud_attrs[0] : attr, - value, valuelen); - ldap_msgfree (result); - return err; -} + if (!pid) + { /* Child. */ + char *pgmname = "/home/wk/w/dirmngr/src/dirmngr_ldap"; /*FIXME*/ + char **arg_list; + int n, i, j; + int fd; + + /* Create command line argument array. */ + for (i=0; argv[i]; i++) + ; + arg_list = xcalloc (i+2, sizeof *arg_list); + arg_list[0] = strrchr (pgmname, '/'); + if (arg_list[0]) + arg_list[0]++; + else + arg_list[0] = pgmname; + for (i=0,j=1; 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]; + /* Connect stderr to the second pipe. */ + if (rp2[1] != STDERR_FILENO && dup2 (rp2[1], STDERR_FILENO) == -1) + { + log_error (_("dup2 failed in child: %s\n"), strerror (errno)); + _exit (4); + } -/* Add HOST and PORT to our list of LDAP servers. Fixme: We should - better use an extra list of servers. */ -static void -add_server_to_servers (const char *host, int port) -{ - ldap_server_t server; - ldap_server_t last = NULL; - const char *s; + /* Connect stdin to /dev/null. */ + fd = open ("/dev/null", O_RDONLY); + if (fd == -1) + { + log_error (_("can't open `/dev/null': %s\n"), strerror (errno)); + _exit (4); + } + if (fd != STDIN_FILENO && dup2 (fd, STDIN_FILENO) == -1) + { + log_error (_("dup2 failed in child: %s\n"), strerror (errno)); + _exit (4); + } - for (server=opt.ldapservers; server; server = server->next) + /* Connect stdout to the first pipe. */ + if (rp[1] != STDOUT_FILENO && dup2 (rp[1], STDOUT_FILENO) == -1) + { + log_error (_("dup2 failed in child: %s\n"), strerror (errno)); + _exit (4); + } + + /* Close all files which will not be duped. */ + n = sysconf (_SC_OPEN_MAX); + if (n < 0) + n = MAX_OPEN_FDS; + for (i=0; i < n; i++) + { + if ( i == STDIN_FILENO || i == STDOUT_FILENO || i == STDERR_FILENO) + continue; + close(i); + } + errno = 0; + + execv (pgmname, arg_list); + log_error (_("error running `%s': %s\n"), pgmname, strerror (errno)); + _exit (31); + } + + /* Parent. */ + close (rp[1]); + close (rp2[1]); + + ctx = xtrycalloc (1, sizeof *ctx); + if (!ctx) { - if (!strcmp (server->host, host) && server->port == port) - return; /* already in list... */ - last = server; + err = gpg_error_from_errno (errno); + log_error (_("error allocating memory: %s\n"), strerror (errno)); + kill (pid, SIGTERM); + close (rp[0]); + close (rp2[0]); + return err; + } + ctx->pid = pid; + ctx->fd = rp[0]; + ctx->log_fd = rp2[0]; + + err = ksba_reader_new (reader); + if (!err) + err = ksba_reader_set_cb (*reader, reader_callback, ctx); + if (err) + { + log_error (_("error initializing reader object: %s\n"), + gpg_strerror (err)); + destroy_wrapper (ctx); + ksba_reader_release (*reader); + *reader = NULL; + return err; } - /* We assume that the host names are all supplied by our - configuration files and thus are sane. To keep this assumption - we must reject all invalid host names. */ - for (s=host; *s; s++) - if (!strchr ("abcdefghijklmnopqrstuvwxyz" - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "01234567890.-", *s)) - { - log_error (_("invalid char 0x%02x in host name" - " - not added\n"), *s); - return; - } + /* Hook the context into our list of running wrappers. */ + ctx->reader = *reader; + ctx->next = wrapper_list; + wrapper_list = ctx; - log_info (_("adding `%s:%d' to the ldap server list\n"), host, port); - server = xcalloc (1, sizeof *s); - server->host = xstrdup (host); - server->port = port; - if (last) - last->next = server; - else - opt.ldapservers = server; + return 0; } -/* Perform a LDAP query using a given URL. */ -gpg_error_t -url_fetch_ldap (const char *url, const char *attr, unsigned char **value, - size_t *valuelen) + +/* Perform an LDAP query. Returns an gpg error code or 0 on success. + The function returns a new stream at R_FP. */ +static gpg_error_t +run_ldap_wrapper (const char *host, int port, + const char *user, const char *pass, + const char *dn, const char *filter, const char *attr, + const char *url, + ksba_reader_t *reader) { - gpg_error_t err; - LDAPURLDesc *ludp = NULL; + const char *argv[20]; + int argc; + char portbuf[30]; - *value = NULL; - *valuelen = 0; - if (DBG_LOOKUP) + *reader = NULL; + + argc = 0; + if (pass) /* Note, that the password most be the first item. */ { - log_debug ("url_fetch_ldap: url=`"); - print_sanitized_string (log_get_stream (), url, 0); - log_printf ("' attr=`%s'\n", attr); + argv[argc++] = "--pass"; + argv[argc++] = pass; } - - if (!ldap_is_ldap_url (url)) + if (opt.verbose) + argv[argc++] = "-vv"; + if (host) { - log_error ("'"); - print_sanitized_string (log_get_stream (), url, 0); - log_printf (_("' is not an LDAP URL\n")); - return gpg_error (GPG_ERR_INV_URI); + argv[argc++] = "--host"; + argv[argc++] = host; } - - if (ldap_url_parse (url, &ludp)) + if (port) { - log_error ("'"); - print_sanitized_string (log_get_stream (), url, 0); - log_printf (_("' is an invalid LDAP URL\n")); - return gpg_error (GPG_ERR_BAD_URI); + sprintf (portbuf, "%d", port); + argv[argc++] = "--port"; + argv[argc++] = portbuf; } - - if (ludp->lud_host) + if (user) { - /* URL has host part: try a simple query. */ - if (opt.add_new_ldapservers) - add_server_to_servers (ludp->lud_host, ludp->lud_port); - err = url_fetch_ldap_internal (ludp, attr, value, valuelen); + argv[argc++] = "--user"; + argv[argc++] = user; } - else - err = gpg_error (GPG_ERR_NO_CRL_KNOWN); + if (dn) + { + argv[argc++] = "--dn"; + argv[argc++] = dn; + } + if (filter) + { + argv[argc++] = "--filter"; + argv[argc++] = filter; + } + if (attr) + { + argv[argc++] = "--attr"; + argv[argc++] = attr; + } + argv[argc++] = url? url : "ldap://"; + argv[argc] = NULL; + + return ldap_wrapper (reader, argv); +} + - if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN) + +/* Perform a LDAP query using a given URL. On success a new ksba + reader is returned. If HOST or PORT ar not 0, they are used to + override the values from the URL. */ +gpg_error_t +url_fetch_ldap (const char *url, const char *host, int port, + ksba_reader_t *reader) +{ + return run_ldap_wrapper (host, port, + NULL, NULL, + NULL, NULL, NULL, url, + reader); + + /* FIXME: This option might be used for DoS attacks. Becuase it + will enlarge the list of servers to consult without a limit and + all LDAP queries w/o a host are will then try each host in + turn. */ +/* if (opt.add_new_ldapservers) */ +/* add_server_to_servers (ludp->lud_host, ludp->lud_port); */ +} + + + +/* Perform an LDAP query on all configured servers. On error the + error code of the last try is returned. */ +gpg_error_t +attr_fetch_ldap (const char *dn, const char *attr, ksba_reader_t *reader) +{ + struct ldap_server_s *server; + gpg_error_t err = gpg_error (GPG_ERR_CONFIGURATION); + + *reader = NULL; + for (server = opt.ldapservers; server; server = server->next) { - /* CRL not found so far. */ - ldap_server_t server; - char *savehost; - int saveport; - - if (DBG_LOOKUP) - log_debug ("no hostname in URL or query failed; " - "trying default hostnames\n"); - savehost = ludp->lud_host; - saveport = ludp->lud_port; - for (server = opt.ldapservers; server; server = server->next) - { - ludp->lud_host = server->host; - ludp->lud_port = server->port; - err = url_fetch_ldap_internal (ludp, attr, value, valuelen); - if (!err) - break; - } - ludp->lud_host = savehost; - ludp->lud_port = saveport; + err = run_ldap_wrapper (server->host, server->port, + server->user, server->pass, + dn, "objectClass=*", attr, NULL, + reader); + if (!err) + break; /* Probably found a result. Ready. */ } - - ldap_free_urldesc (ludp); return err; } + + @@ -682,6 +790,88 @@ return result; } +/* Take the string STRING and escape it accoring to the URL rules. + Retun a newly allocated string. */ +static char * +escape4url (const char *string) +{ + const char *s; + char *buf, *p; + size_t n; + + if (!string) + string = ""; + + for (s=string,n=0; *s; s++) + if (strchr (UNENCODED_URL_CHARS, *s)) + n++; + else + n += 3; + + buf = malloc (n+1); + if (!buf) + return NULL; + + for (s=string,p=buf; *s; s++) + if (strchr (UNENCODED_URL_CHARS, *s)) + *p++ = *s; + else + { + sprintf (p, "%%%02X", *(const unsigned char *)s); + p += 3; + } + *p = 0; + + return buf; +} + + + +/* Create a LDAP URL from DN and FILTER and return it in URL. We don't + need the host and port because this will be specified using the + override options. */ +static gpg_error_t +make_url (char **url, const char *dn, const char *filter) +{ + gpg_error_t err; + char *u_dn, *u_filter; + char const attrs[] = (USERCERTIFICATE "," CACERTIFICATE); + + *url = NULL; + + u_dn = escape4url (dn); + if (!u_dn) + return gpg_error_from_errno (errno); + + u_filter = escape4url (filter); + if (!u_filter) + { + err = gpg_error_from_errno (errno); + xfree (u_dn); + return err; + } + *url = malloc ( 8 + strlen (u_dn) + + 1 + strlen (attrs) + + 5 + strlen (u_filter) + 1 ); + if (!*url) + { + err = gpg_error_from_errno (errno); + xfree (u_dn); + xfree (u_filter); + return err; + } + + stpcpy (stpcpy (stpcpy (stpcpy (stpcpy (stpcpy (*url, "ldap:///"), + u_dn), + "?"), + attrs), + "?sub?"), + u_filter); + xfree (u_dn); + xfree (u_filter); + return 0; +} + /* Prepare an LDAP query to return certificates maching PATTERNS using the SERVER. This function retruns an error code or 0 and a CONTEXT @@ -691,16 +881,15 @@ strlist_t patterns, const ldap_server_t server) { gpg_error_t err; - int rc; const char *host; int port; const char *user; const char *pass; const char *base; - LDAP *ld; - int msgid; - LDAPMessage *result; - strlist_t query_list = NULL, *query_list_tail, sl; + const char *argv[50]; + int argc; + char portbuf[30]; + *context = NULL; if (server) @@ -717,257 +906,206 @@ if (!base) base = ""; - if (DBG_LOOKUP) + argc = 0; + if (pass) /* Note: Must be the first item. */ { - log_debug ("start querying LDAP host=`%s:%d' base='", host, port); - print_sanitized_string (log_get_stream (), base, 0); - log_printf ("'\n"); + argv[argc++] = "--pass"; + argv[argc++] = pass; + } + if (opt.verbose) + argv[argc++] = "-vv"; + argv[argc++] = "--multi"; + if (host) + { + argv[argc++] = "--host"; + argv[argc++] = host; + } + if (port) + { + sprintf (portbuf, "%d", port); + argv[argc++] = "--port"; + argv[argc++] = portbuf; + } + if (user) + { + argv[argc++] = "--user"; + argv[argc++] = user; } - query_list_tail = &query_list; + for (; patterns; patterns = patterns->next) { + strlist_t sl; + char *url; + + if (argc >= sizeof argv -1) + { + /* Too many patterns. It does not make sense to allow an + arbitrary number of patters because the length of the + command line is limited anyway. */ + /* fixme: cleanup. */ + return gpg_error (GPG_ERR_RESOURCE_LIMIT); + } sl = parse_one_pattern (patterns->d); if (!sl) { log_error (_("start_cert_fetch: invalid pattern `%s'\n"), patterns->d); - free_strlist (query_list); + /* fixme: cleanup argv. */ return gpg_error (GPG_ERR_INV_USER_ID); } - *query_list_tail = sl; - query_list_tail = &sl; + if ((sl->flags & 1)) + err = make_url (&url, sl->d, "objectClass=*"); + else + err = make_url (&url, base, sl->d); + free_strlist (sl); + if (err) + { + /* fixme: cleanup argv. */ + return err; + } + argv[argc++] = url; } + argv[argc] = NULL; + *context = xtrycalloc (1, sizeof **context); + if (!*context) + return gpg_error_from_errno (errno); - ld = ldap_init (host, port); - if (!ld) - { - err = gpg_error_from_errno (errno); - log_error (_("%s failed for `"), "ldap_init"); - print_sanitized_string (log_get_stream (), host, 0); - log_printf (":%d': %s\n", port, strerror (errno)); - free_strlist (query_list); - return err; - } + err = ldap_wrapper (&(*context)->reader, argv); - msgid = ldap_simple_bind (ld, user, pass); - if (msgid == -1) + if (err) { - err = gpg_error_from_errno (errno); - log_error (_("%s failed for `"), "ldap_simple_bind"); - print_sanitized_string (log_get_stream (), host, 0); - log_printf (":%d' user `%s': %s\n", - port, user? user : _("[none]"),strerror (errno)); - ldap_unbind (ld); - free_strlist (query_list); - return err; + xfree (*context); + *context = NULL; } - rc = ldap_result (ld, msgid, 0, &opt.ldaptimeout, &result); - if (rc != LDAP_RES_BIND) - { - if (rc == -1 || !rc) - { - err = rc? gpg_error_from_errno (errno) : gpg_error (GPG_ERR_TIMEOUT); - log_error (_("%s failed for `"), "ldap_result/bind"); - print_sanitized_string (log_get_stream (), host, 0); - log_printf (":%d' user `%s': %s\n", - port, user? user : _("[none]"), gpg_strerror (err)); - } - else - { - log_error (_("unexpected message type %d returned for ldap_bind\n"), - rc); - ldap_msgfree (result); - err = gpg_error (GPG_ERR_BUG); - } - ldap_unbind (ld); - free_strlist (query_list); - return err; - } - ldap_msgfree (result); - - *context = xcalloc (1, sizeof **context); - (*context)->ld = ld; - (*context)->query_list = query_list; - (*context)->base = xstrdup (base); - return 0; } -/* Fixme: This is a strange helper. It does for example never return an - error code but instead sets a last value to whatever semantics LDAP - has. */ -static int -get_cert_ldap (cert_fetch_context_t context, - unsigned char **value, size_t * valuelen, int *last) -{ - int try_ca = 0; - char *dn; - - *last = 0; - if (DBG_LOOKUP) - { - dn = ldap_get_dn (context->ld, context->result); - log_debug ("get_cert_ldap: examining DN=`"); - print_sanitized_string (log_get_stream (), dn?dn:"[none]", 0); - log_printf ("'\n"); - } - - again: - if (!context->bervalues) - { - context->bercount = 0; - context->bervalues = ldap_get_values_len (context->ld, - context->result, - try_ca? CACERTATTR - : CERTATTR); - if (!context->bervalues) - context->bervalues = ldap_get_values_len (context->ld, - context->result, - try_ca? CACERTATTRBIN - : CERTATTRBIN); - } - - if (context->bervalues) - { - if (DBG_LOOKUP) - log_debug ("get_cert_ldap: got a %sCertificate\n", try_ca? "ca":"user"); - - *valuelen = context->bervalues[context->bercount]->bv_len; - *value = xmalloc (*valuelen); - memcpy (*value, context->bervalues[context->bercount]->bv_val, *valuelen); - context->bercount++; - if (!context->bervalues[context->bercount]) - { - ldap_value_free_len (context->bervalues); - context->bervalues = 0; - *last = 1; - } - } - else if (!try_ca) - { - try_ca = 1; - goto again; - } - else + +/* 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) +{ + gpg_error_t err; + size_t nread; + + while (count) { - *last = 1; + err = ksba_reader_read (reader, buffer, count, &nread); + if (err) + return err; + buffer += nread; + count -= nread; } - return 0; } /* Fetch the next certificate. Return 0 on success, GPG_ERR_EOF - when no (more) certifciates are available or any other error + if no (more) certificates are available or any other error code. */ gpg_error_t fetch_next_cert_ldap (cert_fetch_context_t context, - unsigned char **value, size_t *valuelen) + unsigned char **value, size_t *valuelen) { gpg_error_t err; - int last; - int rc; + unsigned char hdr[5]; + char *p, *pend; + int n; + int okay = 0; int truncated = 0; - char *attrs[5]; - attrs[0] = CERTATTR; - attrs[1] = CERTATTRBIN; - attrs[2] = CACERTATTR; - attrs[3] = CACERTATTRBIN; - attrs[4] = NULL; - - - next: *value = NULL; *valuelen = 0; - if (!context->result) + err = 0; + while (!err) { - context->query = context->query? context->query->next - : context->query_list; - if (!context->query) - return gpg_error (GPG_ERR_EOF); /* No more patterns. */ - - if ((context->query->flags & 1)) - { - if (DBG_LOOKUP) - log_debug ("ldap_search_st using base `%s'\n", context->query->d); - rc = ldap_search_st (context->ld, context->query->d, - LDAP_SCOPE_SUBTREE, - "objectClass=*", attrs, 0, - &opt.ldaptimeout, &context->result); - } - else + err = read_buffer (context->reader, hdr, 5); + if (err) + break; + n = (hdr[1] << 24)|(hdr[2]<<16)|(hdr[3]<<8)|hdr[4]; + if (*hdr == 'V' && okay) { - if (DBG_LOOKUP) - log_debug ("ldap_search_st using filter `%s', base `%s'\n", - context->query->d, context->base); - rc = ldap_search_st (context->ld, context->base, - LDAP_SCOPE_SUBTREE, - context->query->d, attrs, 0, - &opt.ldaptimeout, &context->result); + *value = xtrymalloc (n); + if (!*value) + return gpg_error_from_errno (errno); + *valuelen = n; + err = read_buffer (context->reader, *value, n); + break; /* Ready or error. */ } - - if (rc) + else if (!n && *hdr == 'A') + okay = 0; + else if (n) { - if (rc == LDAP_SIZELIMIT_EXCEEDED) + if (n > context->tmpbufsize) { - truncated = 1; - log_info (_("ldap_search hit the size limit of the server\n")); - /* Fixme: Shouldn't we bail out here? */ - } - else if (rc == LDAP_NO_SUCH_OBJECT) - { - /* Ignore this error. */ - if (DBG_LOOKUP) - log_debug ("ldap_search returned with no object\n"); - /* Fixme: Shouldn't we bail out here? */ - } - else + xfree (context->tmpbuf); + context->tmpbufsize = 0; + context->tmpbuf = xtrymalloc (n+1); + if (!context->tmpbuf) + return gpg_error_from_errno (errno); + context->tmpbufsize = n; + } + err = read_buffer (context->reader, context->tmpbuf, n); + if (err) + break; + if (*hdr == 'A') { - log_error (_("ldap_search failed: %s\n"), - ldap_err2string (ldap_result2error - (context->ld, - context->result, 0))); - /* FIXME we should write a ldap to gpg error mapper but - before we can do that we need to dig deeper into the - LDAP API definition. */ - return gpg_error (GPG_ERR_GENERAL); + p = context->tmpbuf; + p[n] = 0; /*(we allocated one extra byte for this.)*/ + if ( (pend = strchr (p, ';')) ) + *pend = 0; /* Strip off the extension. */ + if (!ascii_strcasecmp (p, USERCERTIFICATE)) + { + if (DBG_LOOKUP) + log_debug ("fetch_next_cert_ldap: got attribute `%s'\n", + USERCERTIFICATE); + okay = 1; + } + else if (!ascii_strcasecmp (p, CACERTIFICATE)) + { + if (DBG_LOOKUP) + log_debug ("fetch_next_cert_ldap: got attribute `%s'\n", + CACERTIFICATE); + okay = 1; + } + else + { + if (DBG_LOOKUP) + log_debug ("fetch_next_cert_ldap: got attribute `%s'" + " - ignored\n", p); + okay = 0; + } } } - context->result = ldap_first_entry (context->ld, context->result); } - - - if (!context->result) - goto next; - - err = get_cert_ldap (context, value, valuelen, &last); + if (err) - return err; - - if (last) - context->result = ldap_next_entry (context->ld, context->result); + { + xfree (*value); + *value = NULL; + *valuelen = 0; + } - if (!*value) - goto next; + return err; - return truncated? gpg_error (GPG_ERR_TRUNCATED) : 0; + +/* if (rc == LDAP_SIZELIMIT_EXCEEDED) */ +/* { */ + /* truncated = 1; */ +/* log_info (_("ldap_search hit the size limit of the server\n")); */ } + void end_cert_fetch_ldap (cert_fetch_context_t context) { if (context) { - free_strlist (context->query_list); - xfree (context->base); - ldap_unbind (context->ld); + xfree (context->tmpbuf); xfree (context); - - /* fixme: do we need to release the BERVALUES? */ } } Index: dirmngr/src/maperror.c diff -u /dev/null dirmngr/src/maperror.c:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/maperror.c Tue Nov 16 19:24:35 2004 @@ -0,0 +1,74 @@ +/* maperror.c - error code mapping for assuan + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of DirMngr. + * + * DirMngr is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DirMngr 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 + */ + +#include + +#include +#include + +#include "util.h" + +/* Map Assuan error code ERR to an GPG_ERR_ code. We need to + distinguish between genuine (and legacy) Assuan error codes and + application error codes shared with all GnuPG modules. The rule is + simple: All errors with a gpg_err_source of UNKNOWN are genuine; + all other Assuan codes are passed verbatim through. */ +gpg_error_t +map_assuan_err (int err) +{ + gpg_err_code_t ec; + + if (gpg_err_source (err)) + return err; + + switch (err) + { + case -1: ec = GPG_ERR_EOF; break; + case 0: ec = 0; break; + + case ASSUAN_Canceled: ec = GPG_ERR_CANCELED; break; + case ASSUAN_Invalid_Index: ec = GPG_ERR_INV_INDEX; break; + + case ASSUAN_Not_Implemented: ec = GPG_ERR_NOT_IMPLEMENTED; break; + case ASSUAN_Server_Fault: ec = GPG_ERR_ASSUAN_SERVER_FAULT; break; + case ASSUAN_No_Public_Key: ec = GPG_ERR_NO_PUBKEY; break; + case ASSUAN_No_Secret_Key: ec = GPG_ERR_NO_SECKEY; break; + + case ASSUAN_Cert_Revoked: ec = GPG_ERR_CERT_REVOKED; break; + case ASSUAN_No_CRL_For_Cert: ec = GPG_ERR_NO_CRL_KNOWN; break; + case ASSUAN_CRL_Too_Old: ec = GPG_ERR_CRL_TOO_OLD; break; + + case ASSUAN_Not_Trusted: ec = GPG_ERR_NOT_TRUSTED; break; + + case ASSUAN_Card_Error: ec = GPG_ERR_CARD; break; + case ASSUAN_Invalid_Card: ec = GPG_ERR_INV_CARD; break; + case ASSUAN_No_PKCS15_App: ec = GPG_ERR_NO_PKCS15_APP; break; + case ASSUAN_Card_Not_Present: ec= GPG_ERR_CARD_NOT_PRESENT; break; + case ASSUAN_Not_Confirmed: ec = GPG_ERR_NOT_CONFIRMED; break; + case ASSUAN_Invalid_Id: ec = GPG_ERR_INV_ID; break; + + default: + ec = err < 100? GPG_ERR_ASSUAN_SERVER_FAULT : GPG_ERR_ASSUAN; + break; + } + return gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, ec); +} + + Index: dirmngr/src/misc.c diff -u dirmngr/src/misc.c:1.7 dirmngr/src/misc.c:1.8 --- dirmngr/src/misc.c:1.7 Tue Apr 6 10:24:57 2004 +++ dirmngr/src/misc.c Tue Nov 16 19:24:35 2004 @@ -1,5 +1,5 @@ /* misc.c - miscellaneous - * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * Copyright (C) 2002 Klarälvdalens Datakonsult AB * Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc. * * This file is part of DirMngr. @@ -468,3 +468,104 @@ return buf; } + +/* Dump the serial number SERIALNO to the log stream. */ +void +dump_serial (ksba_sexp_t serialno) +{ + char *p; + + p = serial_hex (serialno); + log_printf ("%s", p?p:"?"); + xfree (p); +} + + +/* Dump the ISO time T to the log stream without a LF. */ +void +dump_isotime (dirmngr_isotime_t t) +{ + if (!t || !*t) + log_printf (_("[none]")); + else + log_printf ("%.4s-%.2s-%.2s %.2s:%.2s:%s", + t, t+4, t+6, t+9, t+11, t+13); +} + + +/* Dump STRING to the log file but choose the best readable + format. */ +void +dump_string (const char *string) +{ + + if (!string) + log_printf ("[error]"); + else + { + const unsigned char *s; + + for (s=string; *s; s++) + { + if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0)) + break; + } + if (!*s && *string != '[') + log_printf ("%s", string); + else + { + log_printf ( "[ "); + log_printhex (NULL, string, strlen (string)); + log_printf ( " ]"); + } + } +} + + +/* Dump an KSBA cert object to the log stream. Prefix the output with + TEXT. This is used for debugging. */ +void +dump_cert (const char *text, ksba_cert_t cert) +{ + ksba_sexp_t sexp; + char *p; + ksba_isotime_t t; + + log_debug ("BEGIN Certificate `%s':\n", text? text:""); + if (cert) + { + sexp = ksba_cert_get_serial (cert); + p = serial_hex (sexp); + log_debug (" serial: %s\n", p?p:"?"); + xfree (p); + ksba_free (sexp); + + ksba_cert_get_validity (cert, 0, t); + log_debug (" notBefore: "); + dump_isotime (t); + log_printf ("\n"); + ksba_cert_get_validity (cert, 1, t); + log_debug (" notAfter: "); + dump_isotime (t); + log_printf ("\n"); + + p = ksba_cert_get_issuer (cert, 0); + log_debug (" issuer: "); + dump_string (p); + ksba_free (p); + log_printf ("\n"); + + p = ksba_cert_get_subject (cert, 0); + log_debug (" subject: "); + dump_string (p); + ksba_free (p); + log_printf ("\n"); + + log_debug (" hash algo: %s\n", ksba_cert_get_digest_algo (cert)); + + p = get_fingerprint_hexstring (cert); + log_debug (" SHA1 Fingerprint: %s\n", p); + xfree (p); + } + log_debug ("END Certificate\n"); +} Index: dirmngr/src/misc.h diff -u dirmngr/src/misc.h:1.7 dirmngr/src/misc.h:1.8 --- dirmngr/src/misc.h:1.7 Tue Apr 6 10:24:57 2004 +++ dirmngr/src/misc.h Tue Nov 16 19:24:35 2004 @@ -1,5 +1,5 @@ /* misc.h - miscellaneous - * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * Copyright (C) 2002 Klarälvdalens Datakonsult AB * * This file is part of DirMngr. * @@ -86,6 +86,23 @@ char *get_fingerprint_hexstring (ksba_cert_t cert); +/* Dump the serial number SERIALNO to the log stream. */ +void dump_serial (ksba_sexp_t serialno); + +/* Dump the ISO time T to the log stream without a LF. */ +void dump_isotime (dirmngr_isotime_t t); + +/* Dump STRING to the log file but choose the best readable + format. */ +void dump_string (const char *string); + +/* Dump an KSBA cert object to the log stream. Prefix the output with + TEXT. This is used for debugging. */ +void dump_cert (const char *text, ksba_cert_t cert); + + + + #ifdef HAVE_FOPENCOOKIE /* We have to implement funopen in terms of glibc's fopencookie. */ FILE *funopen(void *cookie, Index: dirmngr/src/no-libgcrypt.c diff -u /dev/null dirmngr/src/no-libgcrypt.c:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/no-libgcrypt.c Tue Nov 16 19:24:35 2004 @@ -0,0 +1,107 @@ +/* no-libgcrypt.c - Replacement functions for libgcrypt. + * Copyright (C) 2003 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include +#include + +#include "../jnlib/logging.h" + +#include "i18n.h" +#include "no-libgcrypt.h" + + +/* Replace libgcrypt's malloc functions which are used by + ../jnlib/libjnlib.a . util.h defines macros to map them to xmalloc + etc. */ +static void +out_of_core (void) +{ + log_fatal (_("error allocating enough memory: %s\n"), strerror (errno)); +} + + +void * +gcry_malloc (size_t n) +{ + return malloc (n); +} + +void * +gcry_xmalloc (size_t n) +{ + void *p = malloc (n); + if (!p) + out_of_core (); + return p; +} + + +void * +gcry_realloc (void *a, size_t n) +{ + return realloc (a, n); +} + +void * +gcry_xrealloc (void *a, size_t n) +{ + void *p = realloc (a, n); + if (!p) + out_of_core (); + return p; +} + + + +void * +gcry_calloc (size_t n, size_t m) +{ + return calloc (n, m); +} + +void * +gcry_xcalloc (size_t n, size_t m) +{ + void *p = calloc (n, m); + if (!p) + out_of_core (); + return p; +} + + +char * +gcry_xstrdup (const char *string) +{ + void *p = malloc (strlen (string)+1); + if (!p) + out_of_core (); + strcpy( p, string ); + return p; +} + +void +gcry_free (void *a) +{ + if (a) + free (a); +} Index: dirmngr/src/no-libgcrypt.h diff -u /dev/null dirmngr/src/no-libgcrypt.h:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/no-libgcrypt.h Tue Nov 16 19:24:35 2004 @@ -0,0 +1,33 @@ +/* no-libgcrypt.h - Replacement functions for libgcrypt. + * Copyright (C) 2004 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifndef NO_LIBGCRYPT_H +#define NO_LIBGCRYPT_H + +void *gcry_malloc (size_t n); +void *gcry_xmalloc (size_t n); +void *gcry_realloc (void *a, size_t n); +void *gcry_xrealloc (void *a, size_t n); +void *gcry_calloc (size_t n, size_t m); +void *gcry_xcalloc (size_t n, size_t m); +char *gcry_xstrdup (const char *string); +void gcry_free (void *a); + +#endif /*NO_LIBGCRYPT_H*/ Index: dirmngr/src/server.c diff -u dirmngr/src/server.c:1.42 dirmngr/src/server.c:1.43 --- dirmngr/src/server.c:1.42 Thu Apr 29 19:09:58 2004 +++ dirmngr/src/server.c Tue Nov 16 19:24:35 2004 @@ -1,5 +1,5 @@ /* dirmngr.c - LDAP access - * Copyright (C) 2002 Klarälvdalens Datakonsult AB + * Copyright (C) 2002 Klarälvdalens Datakonsult AB * Copyright (C) 2003, 2004 g10 Code GmbH * * This file is part of DirMngr. @@ -37,6 +37,11 @@ #include "crlfetch.h" #include "dirmngr.h" #include "ocsp.h" +#include "certcache.h" + +/* To avoid DoS attacks we limit the size of a certificate to + something reasonable. */ +#define MAX_CERT_LENGTH (8*1024) #define PARM_ERROR(t) assuan_set_error (ctx, ASSUAN_Parameter_Error, (t)) @@ -48,57 +53,10 @@ /* Data used to associate an Assuan context with local server data */ struct server_local_s { ASSUAN_CONTEXT assuan_ctx; - crl_cache_t crl_cache; int message_fd; }; -/* Map Assuan error code ERR to an GPG_ERR_ code. We need to - distinguish between genuine (and legacy) Assuan error codes and - application error codes shared with all GnuPG modules. The rule is - simple: All errors with a gpg_err_source of UNKNOWN are genuine; - all other Assuan codes are passed verbatim through. */ -static gpg_error_t -map_assuan_err (int err) -{ - gpg_err_code_t ec; - - if (gpg_err_source (err)) - return err; - - switch (err) - { - case -1: ec = GPG_ERR_EOF; break; - case 0: ec = 0; break; - - case ASSUAN_Canceled: ec = GPG_ERR_CANCELED; break; - case ASSUAN_Invalid_Index: ec = GPG_ERR_INV_INDEX; break; - - case ASSUAN_Not_Implemented: ec = GPG_ERR_NOT_IMPLEMENTED; break; - case ASSUAN_Server_Fault: ec = GPG_ERR_ASSUAN_SERVER_FAULT; break; - case ASSUAN_No_Public_Key: ec = GPG_ERR_NO_PUBKEY; break; - case ASSUAN_No_Secret_Key: ec = GPG_ERR_NO_SECKEY; break; - - case ASSUAN_Cert_Revoked: ec = GPG_ERR_CERT_REVOKED; break; - case ASSUAN_No_CRL_For_Cert: ec = GPG_ERR_NO_CRL_KNOWN; break; - case ASSUAN_CRL_Too_Old: ec = GPG_ERR_CRL_TOO_OLD; break; - - case ASSUAN_Not_Trusted: ec = GPG_ERR_NOT_TRUSTED; break; - - case ASSUAN_Card_Error: ec = GPG_ERR_CARD; break; - case ASSUAN_Invalid_Card: ec = GPG_ERR_INV_CARD; break; - case ASSUAN_No_PKCS15_App: ec = GPG_ERR_NO_PKCS15_APP; break; - case ASSUAN_Card_Not_Present: ec= GPG_ERR_CARD_NOT_PRESENT; break; - case ASSUAN_Not_Confirmed: ec = GPG_ERR_NOT_CONFIRMED; break; - case ASSUAN_Invalid_Id: ec = GPG_ERR_INV_ID; break; - - default: - ec = err < 100? GPG_ERR_ASSUAN_SERVER_FAULT : GPG_ERR_ASSUAN; - break; - } - return gpg_err_make (GPG_ERR_SOURCE_UNKNOWN, ec); -} - /* Map GPG_ERR_xx error codes to Assuan status codes */ static int map_to_assuan_status (int rc) @@ -169,14 +127,8 @@ else buf = xstrdup (command); - /* FIXME: When changed to run as a system wide server, we should - setup a maxlen limit for the certificate. The problem is that - libassuan allocates a buffer of that size in advance which we - usually don't need. As long as dirmngr is used in server mode we - don't need to care about it because the user can toast his - applications in many other ways.*/ rc = assuan_inquire (ctrl->server_local->assuan_ctx, buf, - &value, &valuelen, 0); + &value, &valuelen, MAX_CERT_LENGTH); xfree (buf); if (rc) { @@ -184,6 +136,12 @@ return NULL; } + if (!valuelen) + { + xfree (value); + return NULL; + } + rc = ksba_cert_new (&cert); if (!rc) { @@ -236,70 +194,37 @@ } -/* Ask the client to return the certificate asscociated with the - current command. This is sometimes needed because the client usually - sends us just the cert ID, assuming that the request can be - satisfied from the cache, where the cert ID is used as key. */ +/* Locate the corresponding CRL for the certificate CERT, read and + verify the CRL and store it in the cache. */ static int -inquire_cert_and_load_crl (assuan_context_t ctx) +reload_crl (ctrl_t ctrl, ksba_cert_t cert) { - ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err; - assuan_error_t ae; - FILE *crl_fp = NULL; - unsigned char *value = NULL; - size_t valuelen; + ksba_reader_t reader = NULL; char *issuer = NULL; - ksba_cert_t issuer_cert = NULL; - int seq; - int found_dist_point = 0; ksba_name_t distpoint = NULL; ksba_name_t issuername = NULL; char *distpoint_uri = NULL; char *issuername_uri = NULL; + int any_dist_point = 0; + int seq; - ae = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0); - if (ae) - return map_assuan_err (ae); - -/* { */ -/* FILE *fp = fopen ("foo.der", "r"); */ -/* value = xmalloc (2000); */ -/* valuelen = fread (value, 1, 2000, fp); */ -/* fclose (fp); */ -/* } */ - - if (!valuelen) /* No data returned; return a comprehensible error. */ - return gpg_error (GPG_ERR_MISSING_CERT); - - err = ksba_cert_new (&issuer_cert); - if (err) - goto leave; - err = ksba_cert_init_from_mem (issuer_cert, value, valuelen); - if(err) - goto leave; - - xfree (value); - value = NULL; - - issuer = ksba_cert_get_issuer (issuer_cert, 0); - if (!issuer) - return gpg_error (GPG_ERR_BAD_CERT); /* No issuer in certificate. */ - - /* Loop over all distribution points, get the CRLs and put them - into the cache. */ + /* Loop over all distribution points, get the CRLs and put them into + the cache. */ if (DBG_X509) log_debug ("checking distribution points\n"); seq = 0; - while ( !(err = ksba_cert_get_crl_dist_point (issuer_cert, seq++, + while ( !(err = ksba_cert_get_crl_dist_point (cert, seq++, &distpoint, &issuername, NULL ))) { if (!distpoint && !issuername) { if (DBG_X509) - log_debug ("no issuername and no distpoint\n"); - break; /* Not allowed, so don't keep trying. */ + log_debug ("no issuer name and no distribution point\n"); + break; /* Not allowed; i.e. an invalid certificate. We give + up here and hope that the default method returns a + suitable CRL. */ } /* Get the URIs. */ @@ -309,18 +234,16 @@ issuername_uri = ksba_name_get_uri (issuername, 0); ksba_name_release (distpoint); distpoint = NULL; ksba_name_release (issuername); issuername = NULL; - found_dist_point = 1; + any_dist_point = 1; - xfree (value); value = NULL; - err = crl_fetch (distpoint_uri, &crl_fp); + err = crl_fetch (distpoint_uri, &reader); if (err) { log_error (_("crl_fetch via DP failed: %s\n"), gpg_strerror (err)); goto leave; } - err = crl_cache_insert (ctrl, ctrl->server_local->crl_cache, - distpoint_uri, crl_fp); + err = crl_cache_insert (ctrl, distpoint_uri, reader); if (err) { log_error (_("crl_cache_insert via DP failed: %s\n"), @@ -332,18 +255,26 @@ err = 0; /* If we did not found any distpoint, try something reasonable. */ - if (!found_dist_point ) + if (!any_dist_point ) { if (DBG_X509) log_debug ("no distribution point - trying issuer name\n"); - if (crl_fp) + if (reader) + { + crl_close_reader (reader); + reader = NULL; + } + + issuer = ksba_cert_get_issuer (cert, 0); + if (!issuer) { - fclose (crl_fp); - crl_fp = NULL; + log_error ("oops: issuer missing in certificate\n"); + err = gpg_error (GPG_ERR_INV_CERT_OBJ); + goto leave; } - xfree (value); value = NULL; - err = crl_fetch_default (issuer, &crl_fp); + + err = crl_fetch_default (issuer, &reader); if (err) { log_error (_("crl_fetch via issuer failed: %s\n"), @@ -351,8 +282,7 @@ goto leave; } - err = crl_cache_insert (ctrl, ctrl->server_local->crl_cache, - "default location(s)", crl_fp); + err = crl_cache_insert (ctrl, "default location(s)", reader); if (err) { log_error (_("crl_cache_insert via issuer failed: %s\n"), @@ -362,14 +292,58 @@ } leave: - if (crl_fp) - fclose (crl_fp); + if (reader) + crl_close_reader (reader); xfree (distpoint_uri); xfree (issuername_uri); ksba_name_release (distpoint); ksba_name_release (issuername); ksba_free (issuer); - ksba_cert_release (issuer_cert); + return err; +} + + + +/* Ask the client to return the certificate asscociated with the + current command. This is sometimes needed because the client usually + sends us just the cert ID, assuming that the request can be + satisfied from the cache, where the cert ID is used as key. */ +static int +inquire_cert_and_load_crl (assuan_context_t ctx) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + assuan_error_t ae; + unsigned char *value = NULL; + size_t valuelen; + ksba_cert_t cert = NULL; + + ae = assuan_inquire( ctx, "SENDCERT", &value, &valuelen, 0); + if (ae) + return map_assuan_err (ae); + +/* { */ +/* FILE *fp = fopen ("foo.der", "r"); */ +/* value = xmalloc (2000); */ +/* valuelen = fread (value, 1, 2000, fp); */ +/* fclose (fp); */ +/* } */ + + if (!valuelen) /* No data returned; return a comprehensible error. */ + return gpg_error (GPG_ERR_MISSING_CERT); + + err = ksba_cert_new (&cert); + if (err) + goto leave; + err = ksba_cert_init_from_mem (cert, value, valuelen); + if(err) + goto leave; + xfree (value); value = NULL; + + err = reload_crl (ctrl, cert); + + leave: + ksba_cert_release (cert); xfree (value); return err; } @@ -459,8 +433,7 @@ } else { - switch (crl_cache_isvalid (ctrl->server_local->crl_cache, - issuerhash, serialno, + switch (crl_cache_isvalid (issuerhash, serialno, ctrl->force_crl_refresh)) { case CRL_CACHE_VALID: @@ -493,6 +466,256 @@ } +/* If the line contains a SHA-1 fingerprint as the first argument, + return the FPR vuffer on success. The function checks that the + fingerprint consists of valid characters and prints and error + message if it does not and returns NULL. Fingerprints are + considered optional and thus no explicit error is returned. NULL is + also returned if there is no fingerprint at all available. + FPR must be a caller provided buffer of at least 20 bytes. + + Note that colons within the fingerprint are allowed to separate 2 + hex digits; this allows for easier cutting and pasting using the + usual fingerprint rendering. +*/ +static unsigned char * +get_fingerprint_from_line (const char *line, unsigned char *fpr) +{ + const char *s; + int i; + + for (s=line, i=0; *s && *s != ' '; s++ ) + { + if ( hexdigitp (s) && hexdigitp (s+1) ) + { + if ( i >= 20 ) + return NULL; /* Fingerprint too long. */ + fpr[i++] = xtoi_2 (s); + s++; + } + else if ( *s != ':' ) + return NULL; /* Invalid. */ + } + if ( i != 20 ) + return NULL; /* Fingerprint to short. */ + return fpr; +} + + + +/* CHECKCRL [] + + Check whether the certificate with FINGERPRINT (SHA-1 hash of the + entire X.509 certificate blob) is valid or not by consulting the + CRL responsible for this certificate. If the fingerprint has not + been given or the certificate is not know, the function + inquires the certficate using the + + INQUIRE TARGETCERT + + and the caller is expected to return the certificate for the + request (which should match FINGERPRINT) as a binary blob. + Processing then takes place without further interaction; in + particular dirmngr tries to locate other required certificate by + its own mechanism which includes a local certificate store as well + as a list of trusted root certificates. + + The return value is the usual gpg-error code or 0 for ducesss; + i.e. the certificate validity has been confirmed by a valid CRL. +*/ +static int +cmd_checkcrl (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + unsigned char fprbuffer[20], *fpr; + unsigned char issuerhash[20]; + char issuerhash_hex[41]; + ksba_cert_t cert; + char *serialno = NULL; + + fpr = get_fingerprint_from_line (line, fprbuffer); + cert = fpr? get_cert_byfpr (fpr) : NULL; + + if (!cert) + { + /* We do not have this certificate yet or the fingerprint has + not been given. Inquire it from the client. */ + assuan_error_t ae; + unsigned char *value = NULL; + size_t valuelen; + + ae = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT", + &value, &valuelen, MAX_CERT_LENGTH); + if (ae) + { + log_error (_("assuan_inquire failed: %s\n"), assuan_strerror (ae)); + err = map_assuan_err (ae); + goto leave; + } + + if (!valuelen) /* No data returned; return a comprehensible error. */ + err = gpg_error (GPG_ERR_MISSING_CERT); + else + { + err = ksba_cert_new (&cert); + if (!err) + err = ksba_cert_init_from_mem (cert, value, valuelen); + } + xfree (value); + if(err) + goto leave; + } + + assert (cert); + + /* Compute the hash value of the issuer name. */ + { + char *tmp; + int i; + + tmp = ksba_cert_get_issuer (cert, 0); + if (!tmp) + { + log_error ("oops: issuer missing in certificate\n"); + err = gpg_error (GPG_ERR_INV_CERT_OBJ); + goto leave; + } + gcry_md_hash_buffer (GCRY_MD_SHA1, issuerhash, tmp, strlen (tmp)); + xfree (tmp); + for (i=0,tmp=issuerhash_hex; i < 20; i++, tmp += 2) + sprintf (tmp, "%02X", issuerhash[i]); + } + + /* FIXME: We don't have a suitable check function so we need to format the + S/N as string first. */ + { + ksba_sexp_t serial; + unsigned char *p; + unsigned long n; + char *endp, *tmp; + int i; + + serial = ksba_cert_get_serial (cert); + if (!serial) + { + log_error ("oops: S/N missing in certificate\n"); + err = gpg_error (GPG_ERR_INV_CERT_OBJ); + goto leave; + } + p = serial; + if (*p != '(') + { + log_error ("oops: invalid S/N\n"); + err = gpg_error (GPG_ERR_INV_CERT_OBJ); + xfree (serial); + goto leave; + } + p++; + n = strtoul (p, &endp, 10); + p = endp; + if (*p != ':') + { + log_error ("oops: invalid S/N\n"); + err = gpg_error (GPG_ERR_INV_CERT_OBJ); + xfree (serial); + goto leave; + } + p++; + + serialno = tmp = xtrymalloc (n*2 + 1); + if (!serialno) + { + err = gpg_error_from_errno (errno); + xfree (serial); + goto leave; + } + + for (i=0; i < n; i++, tmp += 2) + sprintf (tmp, "%02X", p[i]); + *tmp = 0; + xfree (serial); + } + + /* Now use our old function to do the actual CRL check. */ + { + int reloaded = 0; + + again: + switch (crl_cache_isvalid (issuerhash_hex, serialno, + ctrl->force_crl_refresh)) + { + case CRL_CACHE_VALID: + err = 0; + break; + case CRL_CACHE_INVALID: + err = gpg_error (GPG_ERR_CERT_REVOKED); + break; + case CRL_CACHE_DONTKNOW: + if (reloaded) + err = gpg_error (GPG_ERR_NO_CRL_KNOWN); + else + { + reloaded = 1; + err = reload_crl (ctrl, cert); + if (!err) + goto again; + } + break; + case CRL_CACHE_CANTUSE: + err = gpg_error (GPG_ERR_NO_CRL_KNOWN); + break; + default: + log_fatal ("crl_cache_isvalid returned invalid status code\n"); + } + } + + leave: + if (err) + log_error (_("command %s failed: %s\n"), "CHECKCRL", gpg_strerror (err)); + ksba_cert_release (cert); + xfree (serialno); + return map_to_assuan_status (err); +} + + +/* CHECKOCSP [] + + Check whether the certificate with FINGERPRINT (SHA-1 hash of the + entire X.509 certificate blob) is valid or not by asking an OCSP + responder responsible for this certificate. The optional + fingerprint may be used for a quick check in case an OCSP check has + been down for this certificate recently (we always cache OCSP + responses for a couple of minutes). If the fingerprint has not been + given or there is no cached result, the function inquires the + certificate using the + + INQUIRE TARGETCERT + + and the caller is expected to return the certificate for the + request (which should match FINGERPRINT) as a binary blob. + Processing then takes place without further interaction; in + particular dirmngr tries to locate other required certificates by + its own mechanism which includes a local certificate store as well + as a list of trusted root certifciates. + + The return value is the usual gpg-error code or 0 for ducesss; + i.e. the certificate validity has been confirmed by a valid CRL. +*/ +static int +cmd_checkocsp (assuan_context_t ctx, char *line) +{ +/* ctrl_t ctrl = assuan_get_pointer (ctx); */ + gpg_error_t err; + + err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + + if (err) + log_error (_("command %s failed: %s\n"), "CHECKOCSP", gpg_strerror (err)); + return map_to_assuan_status (err); +} + + /* LOOKUP @@ -650,7 +873,7 @@ buf = xmalloc (strlen (line)+1); strcpy_escaped_plus (buf, line); - err = crl_cache_load (ctrl, ctrl->server_local->crl_cache, buf); + err = crl_cache_load (ctrl, buf); xfree (buf); if (err) log_error (_("command %s failed: %s\n"), "LOADCRL", gpg_strerror (err)); @@ -670,13 +893,12 @@ cmd_listcrls (assuan_context_t ctx, char *line) { gpg_error_t err; - ctrl_t ctrl = assuan_get_pointer (ctx); FILE *fp = assuan_get_data_fp (ctx); if (!fp) return PARM_ERROR (_("no data stream")); - err = crl_cache_list (ctrl->server_local->crl_cache, fp); + err = crl_cache_list (fp); if (err) log_error (_("command %s failed: %s\n"), "LISTCRLS", gpg_strerror (err)); return map_to_assuan_status (err); @@ -693,6 +915,8 @@ int (*handler)(ASSUAN_CONTEXT, char *line); } table[] = { { "ISVALID", cmd_isvalid }, + { "CHECKCRL", cmd_checkcrl }, + { "CHECKOCSP", cmd_checkocsp }, { "LOOKUP", cmd_lookup }, { "LOADCRL", cmd_loadcrl }, { "LISTCRLS", cmd_listcrls }, @@ -712,24 +936,31 @@ } -/* Startup the server and run the main loop. */ +/* Startup the server and run the main command loop. With FD = -1 + used stdin/stdout. */ void -start_command_handler (void) +start_command_handler (int fd) { int rc; - int filedes[2]; assuan_context_t ctx; struct server_control_s ctrl; memset (&ctrl, 0, sizeof ctrl); dirmngr_init_default_ctrl (&ctrl); - /* For now we use a simple pipe based server so that we can work - from scripts. We will later add options to run as a daemon and - wait for requests on a Unix domain socket. */ - filedes[0] = 0; - filedes[1] = 1; - rc = assuan_init_pipe_server (&ctx, filedes); + if (fd == -1) + { + int filedes[2]; + + filedes[0] = 0; + filedes[1] = 1; + rc = assuan_init_pipe_server (&ctx, filedes); + } + else + { + rc = assuan_init_connected_socket_server (&ctx, fd); + } + if (rc) { log_error (_("failed to initialize the server: %s\n"), @@ -750,7 +981,6 @@ assuan_set_pointer (ctx, &ctrl); ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); ctrl.server_local->assuan_ctx = ctx; - ctrl.server_local->crl_cache = crl_cache_init (); ctrl.server_local->message_fd = -1; if (DBG_ASSUAN) @@ -781,8 +1011,6 @@ if (primary_connection == &ctrl) primary_connection = NULL; - crl_cache_deinit (ctrl.server_local->crl_cache); - assuan_deinit_server (ctx); } Index: dirmngr/src/util.h diff -u /dev/null dirmngr/src/util.h:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/util.h Tue Nov 16 19:24:35 2004 @@ -0,0 +1,57 @@ +/* util.h + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of DirMngr. + * + * DirMngr is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DirMngr 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 + */ + +#ifndef UTIL_H +#define UTIL_H + +#include + +/*-- maperror.c --*/ +gpg_error_t map_assuan_err (int err); + + +/* Handy malloc macros - use only them. */ +#define xtrymalloc(a) gcry_malloc ((a)) +#define xtrycalloc(a,b) gcry_calloc ((a),(b)) +#define xtryrealloc(a,b) gcry_realloc ((a),(b)) +#define xtrystrdup(a) gcry_strdup ((a)) +#define xfree(a) gcry_free ((a)) + +#define xmalloc(a) gcry_xmalloc ((a)) +#define xcalloc(a,b) gcry_xcalloc ((a),(b)) +#define xrealloc(a,b) gcry_xrealloc ((a),(b)) +#define xstrdup(a) gcry_xstrdup ((a)) + +/* Macros to replace ctype ones and to avoid locale problems. */ +#define spacep(p) (*(p) == ' ' || *(p) == '\t') +#define digitp(p) (*(p) >= '0' && *(p) <= '9') +#define hexdigitp(a) (digitp (a) \ + || (*(a) >= 'A' && *(a) <= 'F') \ + || (*(a) >= 'a' && *(a) <= 'f')) +/* These atoi macros assume that the buffer has only valid digits. */ +#define atoi_1(p) (*(p) - '0' ) +#define atoi_2(p) ((atoi_1(p) * 10) + atoi_1((p)+1)) +#define atoi_4(p) ((atoi_2(p) * 100) + atoi_2((p)+2)) +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) + + +#endif /*UTIL_H*/ Index: dirmngr/src/validate.c diff -u /dev/null dirmngr/src/validate.c:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/validate.c Tue Nov 16 19:24:35 2004 @@ -0,0 +1,781 @@ +/* validate.c - Validate a certificate chain. + * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of DirMngr. + * + * DirMngr is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DirMngr 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 + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "dirmngr.h" +#include "certcache.h" +#include "validate.h" +#include "misc.h" + +static const char oid_kp_serverAuth[] = "1.3.6.1.5.5.7.3.1"; +static const char oid_kp_clientAuth[] = "1.3.6.1.5.5.7.3.2"; +static const char oid_kp_codeSigning[] = "1.3.6.1.5.5.7.3.3"; +static const char oid_kp_emailProtection[]= "1.3.6.1.5.5.7.3.4"; +static const char oid_kp_timeStamping[] = "1.3.6.1.5.5.7.3.8"; +static const char oid_kp_ocspSigning[] = "1.3.6.1.5.5.7.3.9"; + + + +static gpg_error_t check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert); + + + + +/* Check whether CERT contains critical extensions we don't know + about. */ +static gpg_error_t +unknown_criticals (ksba_cert_t cert) +{ + static const char *known[] = { + "2.5.29.15", /* keyUsage */ + "2.5.29.19", /* basic Constraints */ + "2.5.29.32", /* certificatePolicies */ + "2.5.29.37", /* extendedKeyUsage */ + NULL + }; + int i, idx, crit; + const char *oid; + gpg_error_t err, rc; + + rc = 0; + for (idx=0; !(err=ksba_cert_get_extension (cert, idx, + &oid, &crit, NULL, NULL));idx++) + { + if (!crit) + continue; + for (i=0; known[i] && strcmp (known[i],oid); i++) + ; + if (!known[i]) + { + log_error (_("critical certificate extension %s is not supported"), + oid); + rc = gpg_error (GPG_ERR_UNSUPPORTED_CERT); + } + } + if (err && gpg_err_code (err) != GPG_ERR_EOF) + rc = err; /* Such an error takes precendence. */ + + return rc; +} + + +/* Basic check for supported policies. */ +static gpg_error_t +check_cert_policy (ksba_cert_t cert) +{ + static char *allowed[] = { + "2.289.9.9", + NULL + }; + gpg_error_t err; + int idx; + char *p, *haystack; + char *policies; + int any_critical; + + err = ksba_cert_get_cert_policies (cert, &policies); + if (gpg_err_code (err) == GPG_ERR_NO_DATA) + return 0; /* No policy given. */ + if (err) + return err; + + /* STRING is a line delimited list of certifiate policies as stored + in the certificate. The line itself is colon delimited where the + first field is the OID of the policy and the second field either + N or C for normal or critical extension */ + if (opt.verbose > 1) + log_info ("certificate's policy list: %s\n", policies); + + /* The check is very minimal but won't give false positives */ + any_critical = !!strstr (policies, ":C"); + + /* See whether we find ALLOWED (which is an OID) in POLICIES */ + for (idx=0; allowed[idx]; idx++) + { + for (haystack=policies; (p=strstr (haystack, allowed[idx])); + haystack = p+1) + { + if ( !(p == policies || p[-1] == '\n') ) + continue; /* Does not match the begin of a line. */ + if (p[strlen (allowed[idx])] != ':') + continue; /* The length does not match. */ + /* Yep - it does match: Return okay. */ + xfree (policies); + return 0; + } + } + + if (!any_critical) + { + log_info (_("note: non-critical certificate policy not allowed")); + err = 0; + } + else + { + log_info (_("certificate policy not allowed")); + err = gpg_error (GPG_ERR_NO_POLICY_MATCH); + } + + xfree (policies); + return err; +} + + +static gpg_error_t +allowed_ca (ksba_cert_t cert, int *chainlen) +{ + gpg_error_t err; + int flag; + + err = ksba_cert_is_ca (cert, &flag, chainlen); + if (err) + return err; + if (!flag) + { + log_error (_("issuer certificate is not marked as a CA")); + return gpg_error (GPG_ERR_BAD_CA_CERT); + } + return 0; +} + + +/* Validate the certificate CHAIN up to the trust anchor. Optionally + return the closest expiration time in R_EXPTIME (this is useful for + caching issues). */ +gpg_error_t +validate_cert_chain (ksba_cert_t cert, ksba_isotime_t r_exptime) +{ + gpg_error_t err = 0; + int depth = 0, maxdepth; + char *issuer = NULL; + char *subject = NULL; + ksba_cert_t subject_cert = NULL, issuer_cert = NULL; + ksba_isotime_t current_time; + ksba_isotime_t exptime; + int any_expired = 0; + int any_revoked = 0; + int any_no_crl = 0; + int any_crl_too_old = 0; + int any_no_policy_match = 0; + + /* Get the current time. */ + get_isotime (current_time); + if (r_exptime) + *r_exptime = 0; + *exptime = 0; + + if (DBG_X509) + dump_cert ("subject", cert); + + /* We walk up the the path until we find a trust anchor. */ + subject_cert = cert; + maxdepth = 50; + + for (;;) + { + /* Get the subject and issuer name from the current + certificate. */ + xfree (issuer); + xfree (subject); + issuer = ksba_cert_get_issuer (subject_cert, 0); + subject = ksba_cert_get_subject (subject_cert, 0); + + if (!issuer) + { + log_error (_("no issuer found in certificate")); + err = gpg_error (GPG_ERR_BAD_CERT); + goto leave; + } + + /* Handle the notBefore and notAfter timestamps. */ + { + ksba_isotime_t not_before, not_after; + + err = ksba_cert_get_validity (subject_cert, 0, not_before); + if (!err) + err = ksba_cert_get_validity (subject_cert, 1, not_after); + if (err) + { + log_error (_("certificate with invalid validity: %s"), + gpg_strerror (err)); + err = gpg_error (GPG_ERR_BAD_CERT); + goto leave; + } + + /* Keep track of the nearest expiration time in EXPTIME. */ + if (*not_after) + { + if (!*exptime) + copy_time (exptime, not_after); + else if (strcmp (not_after, exptime) < 0 ) + copy_time (exptime, not_after); + } + + /* Check whether the certificate is already valid. */ + if (*not_before && strcmp (current_time, not_before) < 0 ) + { + log_error (_("certificate not yet valid")); + log_info ("(valid from "); + dump_isotime (not_before); + log_printf (")\n"); + err = gpg_error (GPG_ERR_CERT_TOO_YOUNG); + goto leave; + } + + /* Now check whether the certificate has expired. */ + if (*not_after && strcmp (current_time, not_after) > 0 ) + { + log_error (_("certificate has expired")); + log_info ("(expired at "); + dump_isotime (not_after); + log_printf (")\n"); + any_expired = 1; + } + } + + /* Do we have any critical extesnions in the certificate we + can't handle? */ + err = unknown_criticals (subject_cert); + if (err) + goto leave; /* yes. */ + + /* Check that given policies are allowed. */ + err = check_cert_policy (subject_cert); + if (gpg_err_code (err) == GPG_ERR_NO_POLICY_MATCH) + { + any_no_policy_match = 1; + err = 1; /*???? FIXME*/ + } + else if (err) + goto leave; + + /* Is this a self-signed certificate? */ + if (subject && !strcmp (issuer, subject)) + { /* Yes. */ + if (check_cert_sig (subject_cert, subject_cert) ) + { + log_error (_("selfsigned certificate has a BAD signature")); + err = gpg_error (depth? GPG_ERR_BAD_CERT_CHAIN + : GPG_ERR_BAD_CERT); + goto leave; + } + + /* Is this certificate allowed to act as a CA. */ + err = allowed_ca (subject_cert, NULL); + if (err) + goto leave; /* No. */ + + + err = is_trusted_cert (subject_cert); + if (!err) + ; /* Yes we trust this cert. */ + else if (gpg_err_code (err) == GPG_ERR_NOT_TRUSTED) + { + char *fpr; + + log_error (_("root certificate is not marked trusted")); + fpr = get_fingerprint_hexstring (subject_cert); + log_info (_("fingerprint=%s\n"), fpr? fpr : "?"); + xfree (fpr); + dump_cert ("issuer", subject_cert); + } + else + { + log_error (_("checking trustworthiness of " + "root certificate failed: %s\n"), + gpg_strerror (err)); + } + if (err) + goto leave; + + /* FIXME: Now check whether this certificate has been revoked. */ + + break; /* Okay: a self-signed certicate is an end-point. */ + } + + /* To avoid loops, we use an arbitary limit on tghe length of + the chain. */ + depth++; + if (depth > maxdepth) + { + log_error (_("certificate chain too long\n")); + err = gpg_error (GPG_ERR_BAD_CERT_CHAIN); + goto leave; + } + + /* Find the next cert up the tree. */ + ksba_cert_release (issuer_cert); issuer_cert = NULL; + err = find_issuing_cert (subject_cert, &issuer_cert); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) + { + log_error (_("issuer certificate not found")); + log_info ("issuer certificate: #/"); + dump_string (issuer); + log_printf ("\n"); + } + else + log_error (_("failed to find issuer certificate: %s\n"), + gpg_strerror (err)); + /* Use a better understandable error code. */ + err = gpg_error (GPG_ERR_MISSING_CERT); + goto leave; + } + +/* try_another_cert: */ + if (DBG_X509) + { + log_debug ("got issuer's certificate:\n"); + dump_cert ("issuer", issuer_cert); + } + + /* Now check the signature of the certificate. Well, not + really: We delay this until later so that fakedcertificates + can't be turned into a DoS easily. */ + err = check_cert_sig (issuer_cert, subject_cert); + if (err) + { + log_error (_("certificate has a BAD signature")); +#if 0 + if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE) + { + /* We now try to find other issuer certificates which + might have been used. This is required because some + CAs are reusing the issuer and subject DN for new + root certificates without using a authorityKeyIdentifier. */ + rc = find_up (kh, subject_cert, issuer, 1); + if (!rc) + { + ksba_cert_t tmp_cert; + + rc = keydb_get_cert (kh, &tmp_cert); + if (rc || !compare_certs (issuer_cert, tmp_cert)) + { + /* The find next did not work or returned an + identical certificate. We better stop here + to avoid infinite checks. */ + rc = gpg_error (GPG_ERR_BAD_SIGNATURE); + ksba_cert_release (tmp_cert); + } + else + { + do_list (0, lm, fp, _("found another possible matching " + "CA certificate - trying again")); + ksba_cert_release (issuer_cert); + issuer_cert = tmp_cert; + goto try_another_cert; + } + } + } +#endif + /* We give a more descriptive error code than the one + returned from the signature checking. */ + err = gpg_error (GPG_ERR_BAD_CERT_CHAIN); + goto leave; + } + + /* Check that the length of the chain is not longer than allowed + by the CA. */ + { + int chainlen; + + err = allowed_ca (issuer_cert, &chainlen); + if (err) + goto leave; + if (chainlen >= 0 && (depth - 1) > chainlen) + { + log_error (_("certificate chain longer than allowed by CA (%d)"), + chainlen); + err = gpg_error (GPG_ERR_BAD_CERT_CHAIN); + goto leave; + } + } + + /* May that certificate be used for certification? */ + err = cert_use_cert_p (issuer_cert); + if (err) + goto leave; /* No. */ + + /* FIXME: Now check whether this certificate has been revoked. */ + + if (opt.verbose) + log_info ("certificate is good\n"); + + /* Now to the next level up. */ + subject_cert = issuer_cert; + issuer_cert = NULL; + } + + if (!err) + { /* If we encountered an error somewhere during the checks, set + the error code to the most critical one */ + if (any_revoked) + err = gpg_error (GPG_ERR_CERT_REVOKED); + else if (any_expired) + err = gpg_error (GPG_ERR_CERT_EXPIRED); + else if (any_no_crl) + err = gpg_error (GPG_ERR_NO_CRL_KNOWN); + else if (any_crl_too_old) + err = gpg_error (GPG_ERR_CRL_TOO_OLD); + else if (any_no_policy_match) + err = gpg_error (GPG_ERR_NO_POLICY_MATCH); + } + + leave: + if (r_exptime) + copy_time (r_exptime, exptime); + xfree (issuer); + ksba_cert_release (issuer_cert); + if (subject_cert != cert) + ksba_cert_release (subject_cert); + return err; +} + + + +/* Return the public key algorithm id from the S-expression PKEY. + FIXME: libgcrypt should provide such a function. Note that this + implementation uses the names as used by libksba. */ +static int +pk_algo_from_sexp (gcry_sexp_t pkey) +{ + gcry_sexp_t l1, l2; + const char *name; + size_t n; + int algo; + + l1 = gcry_sexp_find_token (pkey, "public-key", 0); + if (!l1) + return 0; /* Not found. */ + l2 = gcry_sexp_cadr (l1); + gcry_sexp_release (l1); + + name = gcry_sexp_nth_data (l2, 0, &n); + if (!name) + algo = 0; /* Not found. */ + else if (n==3 && !memcmp (name, "rsa", 3)) + algo = GCRY_PK_RSA; + else if (n==3 && !memcmp (name, "dsa", 3)) + algo = GCRY_PK_DSA; + else if (n==13 && !memcmp (name, "ambiguous-rsa", 13)) + algo = GCRY_PK_RSA; + else + algo = 0; + gcry_sexp_release (l2); + return algo; +} + + +/* Check the signature on CERT using the ISSUER_CERT. This function + does only test the cryptographic signature and nothing else. It is + assumed that the ISSUER_CERT is valid. */ +static gpg_error_t +check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert) +{ + gpg_error_t err; + const char *algoid; + gcry_md_hd_t md; + int i, algo; + ksba_sexp_t p; + size_t n; + gcry_sexp_t s_sig, s_hash, s_pkey; + const char *s; + char algo_name[16+1]; /* hash algorithm name converted to lower case. */ + int digestlen; + unsigned char *digest; + + /* Hash the target certificate using the algorithm from that certificate. */ + algoid = ksba_cert_get_digest_algo (cert); + algo = gcry_md_map_name (algoid); + if (!algo) + { + log_error (_("unknown hash algorithm `%s'\n"), algoid? algoid:"?"); + return gpg_error (GPG_ERR_GENERAL); + } + s = gcry_md_algo_name (algo); + for (i=0; *s && i < sizeof algo_name - 1; s++, i++) + algo_name[i] = tolower (*s); + algo_name[i] = 0; + + err = gcry_md_open (&md, algo, 0); + if (err) + { + log_error ("md_open failed: %s\n", gpg_strerror (err)); + return err; + } + if (DBG_HASHING) + gcry_md_start_debug (md, "hash.cert"); + err = ksba_cert_hash (cert, 1, HASH_FNC, md); + if (err) + { + log_error ("ksba_cert_hash failed: %s\n", gpg_strerror (err)); + gcry_md_close (md); + return err; + } + gcry_md_final (md); + + /* Get the signature value out of the target certificate. */ + p = ksba_cert_get_sig_val (cert); + n = gcry_sexp_canon_len (p, 0, NULL, NULL); + if (!n) + { + log_error ("libksba did not return a proper S-Exp\n"); + gcry_md_close (md); + ksba_free (p); + return gpg_error (GPG_ERR_BUG); + } + if (DBG_X509) + { + int j; + log_debug ("signature value:"); + for (j=0; j < n; j++) + log_printf (" %02X", p[j]); + log_printf ("\n"); + } + + err = gcry_sexp_sscan ( &s_sig, NULL, p, n); + ksba_free (p); + if (err) + { + log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (err)); + gcry_md_close (md); + return err; + } + + /* Get the public key from the issuer certificate. */ + p = ksba_cert_get_public_key (issuer_cert); + n = gcry_sexp_canon_len (p, 0, NULL, NULL); + if (!n) + { + log_error ("libksba did not return a proper S-Exp\n"); + gcry_md_close (md); + ksba_free (p); + gcry_sexp_release (s_sig); + return gpg_error (GPG_ERR_BUG); + } + err = gcry_sexp_sscan ( &s_pkey, NULL, p, n); + ksba_free (p); + if (err) + { + log_error ("gcry_sexp_scan failed: %s\n", gpg_strerror (err)); + gcry_md_close (md); + gcry_sexp_release (s_sig); + return err; + } + + + /* Prepare the values for signature verification. At this point we + have these values: + + S_PKEY - S-expression with the issuer's public key. + S_SIG - Signature value as given in the certrificate. + MD - Finalized hash context with hash of the certificate. + ALGO_NAME - Lowercase hash algorithm name + */ + digestlen = gcry_md_get_algo_dlen (algo); + digest = gcry_md_read (md, algo); + if (pk_algo_from_sexp (s_pkey) == GCRY_PK_DSA) + { + if (digestlen != 20) + { + log_error (_("DSA requires the use of a 160 bit hash algorithm\n")); + gcry_md_close (md); + gcry_sexp_release (s_sig); + gcry_sexp_release (s_pkey); + return gpg_error (GPG_ERR_INTERNAL); + } + if ( gcry_sexp_build (&s_hash, NULL, "(data(flags raw)(value %b))", + (int)digestlen, digest) ) + BUG (); + } + else /* Not DSA. */ + { + if ( gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash %s %b))", + algo_name, (int)digestlen, digest) ) + BUG (); + + } + + err = gcry_pk_verify (s_sig, s_hash, s_pkey); + if (DBG_CRYPTO) + log_debug ("gcry_pk_verify: %s\n", gpg_strerror (err)); + gcry_md_close (md); + gcry_sexp_release (s_sig); + gcry_sexp_release (s_hash); + gcry_sexp_release (s_pkey); + return err; +} + + + +/* Return 0 if the cert is usable for encryption. A MODE of 0 checks + for signing, a MODE of 1 checks for encryption, a MODE of 2 checks + for verification and a MODE of 3 for decryption (just for + debugging). MODE 4 is for certificate signing, MODE 5 for OCSP + response signing. */ +static int +cert_usage_p (ksba_cert_t cert, int mode) +{ + gpg_error_t err; + unsigned int use; + char *extkeyusages; + int have_ocsp_signing = 0; + + err = ksba_cert_get_ext_key_usages (cert, &extkeyusages); + if (gpg_err_code (err) == GPG_ERR_NO_DATA) + err = 0; /* No policy given. */ + if (!err) + { + unsigned int extusemask = ~0; /* Allow all. */ + + if (extkeyusages) + { + char *p, *pend; + int any_critical = 0; + + extusemask = 0; + + p = extkeyusages; + while (p && (pend=strchr (p, ':'))) + { + *pend++ = 0; + /* Only care about critical flagged usages. */ + if ( *pend == 'C' ) + { + any_critical = 1; + if ( !strcmp (p, oid_kp_serverAuth)) + extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE + | KSBA_KEYUSAGE_KEY_ENCIPHERMENT + | KSBA_KEYUSAGE_KEY_AGREEMENT); + else if ( !strcmp (p, oid_kp_clientAuth)) + extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE + | KSBA_KEYUSAGE_KEY_AGREEMENT); + else if ( !strcmp (p, oid_kp_codeSigning)) + extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE); + else if ( !strcmp (p, oid_kp_emailProtection)) + extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE + | KSBA_KEYUSAGE_NON_REPUDIATION + | KSBA_KEYUSAGE_KEY_ENCIPHERMENT + | KSBA_KEYUSAGE_KEY_AGREEMENT); + else if ( !strcmp (p, oid_kp_timeStamping)) + extusemask |= (KSBA_KEYUSAGE_DIGITAL_SIGNATURE + | KSBA_KEYUSAGE_NON_REPUDIATION); + } + + /* This is a hack to cope with OCSP. Note that we do + not yet fully comply with the requirements and that + the entire CRL/OCSP checking thing should undergo a + thorough review and probably redesign. */ + if ( !strcmp (p, oid_kp_ocspSigning)) + have_ocsp_signing = 1; + + if ((p = strchr (pend, '\n'))) + p++; + } + xfree (extkeyusages); + extkeyusages = NULL; + + if (!any_critical) + extusemask = ~0; /* Reset to the don't care mask. */ + } + + + err = ksba_cert_get_key_usage (cert, &use); + if (gpg_err_code (err) == GPG_ERR_NO_DATA) + { + err = 0; + if (opt.verbose && mode < 2) + log_info (_("no key usage specified - assuming all usages\n")); + use = ~0; + } + + /* Apply extKeyUsage. */ + use &= extusemask; + + } + if (err) + { + log_error (_("error getting key usage information: %s\n"), + gpg_strerror (err)); + xfree (extkeyusages); + return err; + } + + if (mode == 4) + { + if ((use & (KSBA_KEYUSAGE_KEY_CERT_SIGN))) + return 0; + log_info (_("certificate should have not " + "been used for certification\n")); + return gpg_error (GPG_ERR_WRONG_KEY_USAGE); + } + + if (mode == 5) + { + if (use != ~0 + && (have_ocsp_signing + || (use & (KSBA_KEYUSAGE_KEY_CERT_SIGN + |KSBA_KEYUSAGE_CRL_SIGN)))) + return 0; + log_info (_("certificate should have not " + "been used for OCSP response signing\n")); + return gpg_error (GPG_ERR_WRONG_KEY_USAGE); + } + + if ((use & ((mode&1)? + (KSBA_KEYUSAGE_KEY_ENCIPHERMENT|KSBA_KEYUSAGE_DATA_ENCIPHERMENT): + (KSBA_KEYUSAGE_DIGITAL_SIGNATURE|KSBA_KEYUSAGE_NON_REPUDIATION))) + ) + return 0; + + log_info (mode==3? _("certificate should have not been used " + "for encryption\n"): + mode==2? _("certificate should have not been used for signing\n"): + mode==1? _("certificate is not usable for encryption\n"): + _("certificate is not usable for signing\n")); + return gpg_error (GPG_ERR_WRONG_KEY_USAGE); +} + +/* Return 0 if the certificate CERT is usable for certification. */ +gpg_error_t +cert_use_cert_p (ksba_cert_t cert) +{ + return cert_usage_p (cert, 4); +} + +/* Return 0 if the certificate CERT is usable for signing OCSP + responses. */ +gpg_error_t +cert_use_ocsp_p (ksba_cert_t cert) +{ + return cert_usage_p (cert, 5); +} + Index: dirmngr/src/validate.h diff -u /dev/null dirmngr/src/validate.h:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/src/validate.h Tue Nov 16 19:24:35 2004 @@ -0,0 +1,37 @@ +/* validate.h - Certificate validation + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of DirMngr. + * + * DirMngr is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DirMngr 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 + */ + +#ifndef VALIDATE_H +#define VALIDATE_H + + +/* Validate the certificate CHAIN up to the trust anchor. Optionally + return the closest expiration time in R_EXPTIME. */ +gpg_error_t validate_cert_chain (ksba_cert_t cert, ksba_isotime_t r_exptime); + +/* Return 0 if the certificate CERT is usable for certification. */ +gpg_error_t cert_use_cert_p (ksba_cert_t cert); + +/* Return 0 if the certificate CERT is usable for signing OCSP + responses. */ +gpg_error_t cert_use_ocsp_p (ksba_cert_t cert); + + +#endif /*VALIDATE_H*/ Index: dirmngr/tests/Makefile.am diff -u dirmngr/tests/Makefile.am:1.8 dirmngr/tests/Makefile.am:1.9 --- dirmngr/tests/Makefile.am:1.8 Wed Dec 3 22:22:14 2003 +++ dirmngr/tests/Makefile.am Tue Nov 16 19:24:35 2004 @@ -10,11 +10,14 @@ TESTS = -noinst_PROGRAMS = test-dirmngr asschk +noinst_PROGRAMS = test-dirmngr asschk show-multi LDADD = ../jnlib/libjnlib.a @LIBASSUAN_LIBS@ @LIBGCRYPT_LIBS@ @KSBA_LIBS@ asschk_SOURCES = asschk.c +show_multi_SOURCERS = show-multi.c +show_multi_LDADD = + Index: dirmngr/tests/show-multi.c diff -u /dev/null dirmngr/tests/show-multi.c:1.1 --- /dev/null Tue Nov 16 19:24:36 2004 +++ dirmngr/tests/show-multi.c Tue Nov 16 19:24:35 2004 @@ -0,0 +1,170 @@ +/* show-multi.c - test tool to show dirmngr_ldap --multi output + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of DirMngr. + * + * DirMngr is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * DirMngr 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 + */ + + +#include +#include +#include +#include +#include +#include + +#define PGM "show-multi" + +/* Print diagnostic message and exit with failure. */ +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + putc ('\n', stderr); + + exit (1); +} + + +static void +copy_n_bytes (FILE *fp, size_t n) +{ + int c; + + while (n-- && (c=getc(fp))!=EOF) + if ( c == '\\' ) + fputs ("\\\\", stdout); + else if ( c == '\n' ) + fputs ("\\n", stdout); + else if ( c == '\r' ) + fputs ("\\r", stdout); + else if ( c == '\t' ) + fputs ("\\t", stdout); + else if ( c == '\f' ) + fputs ("\\f", stdout); + else if ( c == '\v' ) + fputs ("\\v", stdout); + else if ( c == '\b' ) + fputs ("\\b", stdout); + else if ( c == '\a' ) + fputs ("\\a", stdout); + else if (c < 0x20 || c >= 0x7f) + printf ("\\x%02X", (unsigned int)c); + else + putchar (c); + +} + + + +static void +show_data (FILE *fp) +{ + unsigned char hdr[5]; + size_t length; + int n; + + + while ((n=fread (hdr, 1, 5, fp)) == 5) + { + length = (hdr[1] << 24)|(hdr[2]<<16)|(hdr[3]<<8)|hdr[4]; + if (*hdr == 'I') + { + printf ("ITEM\n"); + if (length) + die ("header type 'I' with a non-zero length\n"); + } + else if (*hdr == 'A') + { + printf (" ATTRIBUTE "); + copy_n_bytes (fp, length); + putchar ('\n'); + } + else if (*hdr == 'V') + { + printf (" VALUE "); + copy_n_bytes (fp, length); + putchar ('\n'); + } + else + die ("invalid header type 0x%02X\n", *hdr); + } + if (ferror (fp)) + die ("error reading input: %s\n", strerror (errno)); + else if (n) + die ("header record too short\n"); +} + + + +int +main (int argc, char **argv) +{ + int last_argc = -1; + + if (argc) + { + argc--; argv++; + } + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + { + puts ( + "Usage: " PGM " [OPTION] [FILE]\n" + "Show the output of dirmngr_ldap --multi\n\n" + " --help display this help and exit\n\n" + "With no FILE, or when FILE is -, read standard input.\n"); + exit (0); + } + } + + if (argc > 1) + die ("usage: " PGM " [OPTION] [FILE] (try --help for more information)\n"); + + if (argc && strcmp (*argv, "-")) + { + FILE *fp = fopen (*argv, "rb"); + if (!fp) + die ("can't open `%s': %s", *argv, strerror (errno)); + show_data (fp); + fclose (fp); + } + else + show_data (stdin); + + return 0; +} + + +/* +Local Variables: +compile-command: "gcc -Wall -g -o show-multi show-multi.c" +End: +*/ From cvs at cvs.gnupg.org Wed Nov 17 16:58:20 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Wed Nov 17 16:58:23 2004 Subject: gnupg (9 files) Message-ID: Date: Wednesday, November 17, 2004 @ 17:04:21 Author: wk Path: /cvs/gnupg/gnupg Modified: AUTHORS ChangeLog README g10/ChangeLog g10/app-openpgp.c g10/cardglue.c g10/g10.c g10/keydb.h g10/passphrase.c (open_info_file): New. (main): Unconditionally implement --status-file, --logger-file, --attribute-file, --passphrase-file, --command-file. This is not generally useful but easy to support and might make scripting under Windows easier. -------------------+ AUTHORS | 2 ChangeLog | 5 ++ README | 2 g10/ChangeLog | 28 ++++++++++++- g10/app-openpgp.c | 45 ++++++++++++--------- g10/cardglue.c | 93 ++++++++++++++++++++++++++++++++++++++----- g10/g10.c | 110 ++++++++++++++++++++++++++++++++-------------------- g10/keydb.h | 4 + g10/passphrase.c | 28 ++++++++----- 9 files changed, 229 insertions(+), 88 deletions(-) Index: gnupg/AUTHORS diff -u gnupg/AUTHORS:1.36 gnupg/AUTHORS:1.37 --- gnupg/AUTHORS:1.36 Thu Oct 21 18:56:22 2004 +++ gnupg/AUTHORS Wed Nov 17 17:04:21 2004 @@ -9,7 +9,7 @@ Birger Langkjer Translations [da] -Britov Ivanovich Translations [ru] +Maxim Britov Translations [ru] Daniel Resare Translations [sv] Index: gnupg/ChangeLog diff -u gnupg/ChangeLog:1.220 gnupg/ChangeLog:1.221 --- gnupg/ChangeLog:1.220 Sat Nov 6 14:18:13 2004 +++ gnupg/ChangeLog Wed Nov 17 17:04:21 2004 @@ -7,6 +7,11 @@ * README, configure.ac: Add --enable-backsigs to enable the experimental backsigs code. +2004-11-04 Werner Koch + + * AUTHORS: Use Maxim Britov. I am not that accustomed to the + Russian way of writing names. + 2004-10-28 Werner Koch Released 1.3.92. Index: gnupg/README diff -u gnupg/README:1.89 gnupg/README:1.90 --- gnupg/README:1.89 Fri Nov 5 04:45:06 2004 +++ gnupg/README Wed Nov 17 17:04:21 2004 @@ -603,7 +603,7 @@ --enable-selinux-support This prevents access to certain files and won't - allow import or export of secret keys. + allow import or export of secret keys. --disable-gnupg-iconv If iconv is available it is used to convert Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.638 gnupg/g10/ChangeLog:1.639 --- gnupg/g10/ChangeLog:1.638 Thu Nov 4 23:28:39 2004 +++ gnupg/g10/ChangeLog Wed Nov 17 17:04:21 2004 @@ -1,3 +1,27 @@ +2004-11-17 Werner Koch + + * g10.c (open_info_file): New. + (main): Unconditionally implement --status-file, --logger-file, + --attribute-file, --passphrase-file, --command-file. This is not + generally useful but easy to support and might make scripting + under Windows easier. + +2004-11-11 Werner Koch + + * passphrase.c (readn): Fixed test against EINTR. + +2004-11-05 Werner Koch + + * app-openpgp.c: Made more strings translatable. + (verify_chv3, do_change_pin): Add a special prefix to the prompt + of the Admin PIN prompts. + * passphrase.c (ask_passphrase): Add arg TRYAGAIN_TEXT. Changed + call callers. + * cardglue.c (pin_cb): Make use of the OPAQUE arg to pass + arguments to the PIN callback. Use this to implement a way to + check for correct PIN repetition. Changed all callers to pass an + opaque argument. Improved detection of Admin PIN prompts. + 2004-11-04 David Shaw * plaintext.c (handle_plaintext): Don't try and create a @@ -20,9 +44,9 @@ 2004-11-03 Timo Schulz - * passphrase.c (readn, writen): Use w32_strerror instead + * passphrase.c (readn, writen): Use w32_strerror instead of just showing the error number. - * misc.c [_WIN32]: Fix warning about missing prototypes. + * misc.c [_WIN32]: Fix warning about missing prototypes. 2004-10-28 David Shaw Index: gnupg/g10/app-openpgp.c diff -u gnupg/g10/app-openpgp.c:1.19 gnupg/g10/app-openpgp.c:1.20 --- gnupg/g10/app-openpgp.c:1.19 Tue Oct 26 09:51:15 2004 +++ gnupg/g10/app-openpgp.c Wed Nov 17 17:04:21 2004 @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: app-openpgp.c,v 1.19 2004/10/26 07:51:15 wk Exp $ + * $Id: app-openpgp.c,v 1.20 2004/11/17 16:04:21 wk Exp $ */ #include @@ -815,7 +815,10 @@ " is permanently locked\n"), value[6]); xfree (relptr); - rc = pincb (pincb_arg, _("Admin PIN"), &pinvalue); + /* Note to translators: Do not translate the "|A|" prefix but + keep it at the start of the string. We need this elsewhere + to get some infos on the string. */ + rc = pincb (pincb_arg, _("|A|Admin PIN"), &pinvalue); if (rc) { log_info (_("PIN callback returned error: %s\n"), gpg_strerror (rc)); @@ -953,10 +956,14 @@ else app->did_chv1 = app->did_chv2 = 0; - rc = pincb (pincb_arg, chvno == 3? "New Admin PIN" : "New PIN", &pinvalue); + /* Note to translators: Do not translate the "|A|" prefix but + keep it at the start of the string. We need this elsewhere + to get some infos on the string. */ + rc = pincb (pincb_arg, chvno == 3? _("|A|New Admin PIN") : _("New PIN"), + &pinvalue); if (rc) { - log_error ("error getting new PIN: %s\n", gpg_strerror (rc)); + log_error (_("error getting new PIN: %s\n"), gpg_strerror (rc)); goto leave; } @@ -1022,14 +1029,14 @@ rc = iso7816_get_data (app->slot, 0x006E, &buffer, &buflen); if (rc) { - log_error ("error reading application data\n"); + log_error (_("error reading application data\n")); return gpg_error (GPG_ERR_GENERAL); } fpr = find_tlv (buffer, buflen, 0x00C5, &n); if (!fpr || n != 60) { rc = gpg_error (GPG_ERR_GENERAL); - log_error ("error reading fingerprint DO\n"); + log_error (_("error reading fingerprint DO\n")); goto leave; } fpr += 20*keyno; @@ -1038,13 +1045,13 @@ if (i!=20 && !force) { rc = gpg_error (GPG_ERR_EEXIST); - log_error ("key already exists\n"); + log_error (_("key already exists\n")); goto leave; } else if (i!=20) - log_info ("existing key will be replaced\n"); + log_info (_("existing key will be replaced\n")); else - log_info ("generating new key\n"); + log_info (_("generating new key\n")); rc = verify_chv3 (app, pincb, pincb_arg); @@ -1054,7 +1061,7 @@ xfree (buffer); buffer = NULL; #if 1 - log_info ("please wait while key is being generated ...\n"); + log_info (_("please wait while key is being generated ...\n")); start_at = time (NULL); rc = iso7816_generate_keypair #else @@ -1069,16 +1076,16 @@ if (rc) { rc = gpg_error (GPG_ERR_CARD); - log_error ("generating key failed\n"); + log_error (_("generating key failed\n")); goto leave; } - log_info ("key generation completed (%d seconds)\n", + log_info (_("key generation completed (%d seconds)\n"), (int)(time (NULL) - start_at)); keydata = find_tlv (buffer, buflen, 0x7F49, &keydatalen); if (!keydata) { rc = gpg_error (GPG_ERR_CARD); - log_error ("response does not contain the public key data\n"); + log_error (_("response does not contain the public key data\n")); goto leave; } @@ -1086,7 +1093,7 @@ if (!m) { rc = gpg_error (GPG_ERR_CARD); - log_error ("response does not contain the RSA modulus\n"); + log_error (_("response does not contain the RSA modulus\n")); goto leave; } /* log_printhex ("RSA n:", m, mlen); */ @@ -1096,7 +1103,7 @@ if (!e) { rc = gpg_error (GPG_ERR_CARD); - log_error ("response does not contain the RSA public exponent\n"); + log_error (_("response does not contain the RSA public exponent\n")); goto leave; } /* log_printhex ("RSA e:", e, elen); */ @@ -1129,7 +1136,7 @@ ul = (value[0] << 16) | (value[1] << 8) | value[2]; else { - log_error ("invalid structure of OpenPGP card (DO 0x93)\n"); + log_error (_("invalid structure of OpenPGP card (DO 0x93)\n")); ul = 0; } return ul; @@ -1164,14 +1171,14 @@ rc = get_cached_data (app, 0x006E, &buffer, &buflen); if (rc) { - log_error ("error reading application data\n"); + log_error (_("error reading application data\n")); return gpg_error (GPG_ERR_GENERAL); } fpr = find_tlv (buffer, buflen, 0x00C5, &n); if (!fpr || n != 60) { xfree (buffer); - log_error ("error reading fingerprint DO\n"); + log_error (_("error reading fingerprint DO\n")); return gpg_error (GPG_ERR_GENERAL); } fpr += (keyno-1)*20; @@ -1290,7 +1297,7 @@ memcpy (data+15, indata, indatalen); sigcount = get_sig_counter (app); - log_info ("signatures created so far: %lu\n", sigcount); + log_info (_("signatures created so far: %lu\n"), sigcount); if (!app->did_chv1 || app->force_chv1 ) { Index: gnupg/g10/cardglue.c diff -u gnupg/g10/cardglue.c:1.18 gnupg/g10/cardglue.c:1.19 --- gnupg/g10/cardglue.c:1.18 Fri Oct 15 15:16:57 2004 +++ gnupg/g10/cardglue.c Wed Nov 17 17:04:21 2004 @@ -49,6 +49,12 @@ }; +struct pin_cb_info_s +{ + int repeat; +}; + + static char *default_reader_port; static APP current_app; @@ -620,28 +626,69 @@ static int pin_cb (void *opaque, const char *info, char **retstr) { + struct pin_cb_info_s *parm = opaque; char *value; int canceled; - int isadmin = (info && strstr (info, "dmin")); - + int isadmin = 0; + const char *again_text = NULL; *retstr = NULL; log_debug ("asking for PIN '%s'\n", info); + /* We use a special prefix to check whether the Admin PIN has been + requested. */ + if (info && !strncmp (info, "|A|", 3)) + { + isadmin = 1; + info += 3; + } + + again: if (is_status_enabled()) write_status_text (STATUS_NEED_PASSPHRASE_PIN, isadmin? "OPENPGP 3" : "OPENPGP 1"); - value = ask_passphrase (info, + value = ask_passphrase (info, again_text, isadmin? "passphrase.adminpin.ask" : "passphrase.pin.ask", - isadmin? _("Enter Admin PIN: ") : _("Enter PIN: "), + isadmin? _("Enter Admin PIN: ") + : _("Enter PIN: "), &canceled); + again_text = NULL; if (!value && canceled) return -1; else if (!value) return G10ERR_GENERAL; + if (parm->repeat) + { + char *value2; + + value2 = ask_passphrase (info, NULL, + "passphrase.pin.repeat", + _("Repeat this PIN: "), + &canceled); + if (!value && canceled) + { + xfree (value); + return -1; + } + else if (!value) + { + xfree (value); + return G10ERR_GENERAL; + } + if (strcmp (value, value2)) + { + again_text = N_("PIN not correctly repeated; try again"); + xfree (value2); + xfree (value); + value = NULL; + goto again; + } + xfree (value2); + } + *retstr = value; return 0; } @@ -654,12 +701,15 @@ const unsigned char *value, size_t valuelen) { APP app; + struct pin_cb_info_s parm; + + memset (&parm, 0, sizeof parm); app = current_app? current_app : open_card (); if (!app) return gpg_error (GPG_ERR_CARD); - return app->fnc.setattr (app, name, pin_cb, NULL, value, valuelen); + return app->fnc.setattr (app, name, pin_cb, &parm, value, valuelen); } @@ -670,7 +720,7 @@ const char *keyword = line; int keywordlen; - log_debug ("got status line `%s'\n", line); +/* log_debug ("got status line `%s'\n", line); */ for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) ; while (spacep (line)) @@ -722,6 +772,9 @@ APP app; char keynostr[20]; struct ctrl_ctx_s ctrl; + struct pin_cb_info_s parm; + + memset (&parm, 0, sizeof parm); app = current_app? current_app : open_card (); if (!app) @@ -734,7 +787,7 @@ return app->fnc.genkey (app, &ctrl, keynostr, force? 1:0, - pin_cb, NULL); + pin_cb, &parm); } /* Send a PKSIGN command to the SCdaemon. */ @@ -745,6 +798,9 @@ { APP app; int rc; + struct pin_cb_info_s parm; + + memset (&parm, 0, sizeof parm); *r_buf = NULL; *r_buflen = 0; @@ -761,7 +817,7 @@ return rc; return app->fnc.sign (app, serialno, hashalgo, - pin_cb, NULL, + pin_cb, &parm, indata, indatalen, r_buf, r_buflen); } @@ -775,6 +831,9 @@ { APP app; int rc; + struct pin_cb_info_s parm; + + memset (&parm, 0, sizeof parm); *r_buf = NULL; *r_buflen = 0; @@ -791,7 +850,7 @@ return rc; return app->fnc.decipher (app, serialno, - pin_cb, NULL, + pin_cb, &parm, indata, indatalen, r_buf, r_buflen); } @@ -803,6 +862,10 @@ APP app; char chvnostr[20]; int reset = 0; + struct pin_cb_info_s parm; + + memset (&parm, 0, sizeof parm); + parm.repeat = 1; reset = (chvno >= 100); chvno %= 100; @@ -813,7 +876,7 @@ sprintf (chvnostr, "%d", chvno); return app->fnc.change_pin (app, NULL, chvnostr, reset, - pin_cb, NULL); + pin_cb, &parm); } /* Perform a CHECKPIN operation. SERIALNO should be the serial @@ -823,12 +886,15 @@ agent_scd_checkpin (const char *serialnobuf) { APP app; + struct pin_cb_info_s parm; + + memset (&parm, 0, sizeof parm); app = current_app? current_app : open_card (); if (!app) return gpg_error (GPG_ERR_CARD); - return app->fnc.check_pin (app, serialnobuf, pin_cb, NULL); + return app->fnc.check_pin (app, serialnobuf, pin_cb, &parm); } @@ -841,6 +907,9 @@ const unsigned char *e, size_t elen) { APP app; + struct pin_cb_info_s parm; + + memset (&parm, 0, sizeof parm); app = current_app? current_app : open_card (); if (!app) @@ -848,5 +917,5 @@ return app_openpgp_storekey (app, keyno, template, template_len, created_at, m, mlen, e, elen, - pin_cb, NULL); + pin_cb, &parm); } Index: gnupg/g10/g10.c diff -u gnupg/g10/g10.c:1.287 gnupg/g10/g10.c:1.288 --- gnupg/g10/g10.c:1.287 Thu Oct 21 21:18:47 2004 +++ gnupg/g10/g10.c Wed Nov 17 17:04:21 2004 @@ -33,6 +33,7 @@ #ifdef HAVE_STAT #include /* for stat() */ #endif +#include #define INCLUDED_BY_MAIN_MODULE 1 #include "packet.h" @@ -57,6 +58,12 @@ #include "ccid-driver.h" #endif +#if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__) +#define MY_O_BINARY O_BINARY +#else +#define MY_O_BINARY 0 +#endif + enum cmd_and_opt_values @@ -174,13 +181,9 @@ oDebugAll, oDebugCCIDDriver, oStatusFD, -#ifdef __riscos__ oStatusFile, -#endif /* __riscos__ */ oAttributeFD, -#ifdef __riscos__ oAttributeFile, -#endif /* __riscos__ */ oSKComments, oNoSKComments, oEmitVersion, @@ -205,13 +208,9 @@ oBZ2CompressLevel, oBZ2DecompressLowmem, oPasswdFD, -#ifdef __riscos__ oPasswdFile, -#endif /* __riscos__ */ oCommandFD, -#ifdef __riscos__ oCommandFile, -#endif /* __riscos__ */ oQuickRandom, oNoVerbose, oTrustDBName, @@ -284,9 +283,7 @@ oHiddenEncryptTo, oNoEncryptTo, oLoggerFD, -#ifdef __riscos__ oLoggerFile, -#endif /* __riscos__ */ oUtf8Strings, oNoUtf8Strings, oDisableCipherAlgo, @@ -487,13 +484,9 @@ { oDebug, "debug" ,4|16, "@"}, { oDebugAll, "debug-all" ,0, "@"}, { oStatusFD, "status-fd" ,1, "@"}, -#ifdef __riscos__ { oStatusFile, "status-file" ,2, "@"}, -#endif /* __riscos__ */ { oAttributeFD, "attribute-fd" ,1, "@" }, -#ifdef __riscos__ { oAttributeFile, "attribute-file" ,2, "@" }, -#endif /* __riscos__ */ { oNoSKComments, "no-sk-comments", 0, "@"}, { oSKComments, "sk-comments", 0, "@"}, { oCompletesNeeded, "completes-needed", 1, "@"}, @@ -554,17 +547,13 @@ { aPipeMode, "pipemode", 0, "@" }, { oKOption, NULL, 0, "@"}, { oPasswdFD, "passphrase-fd",1, "@" }, -#ifdef __riscos__ { oPasswdFile, "passphrase-file",2, "@" }, -#endif /* __riscos__ */ { oCommandFD, "command-fd",1, "@" }, -#ifdef __riscos__ { oCommandFile, "command-file",2, "@" }, -#endif /* __riscos__ */ { oQuickRandom, "quick-random", 0, "@"}, { oNoVerbose, "no-verbose", 0, "@"}, { oTrustDBName, "trustdb-name", 2, "@" }, - { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */ + { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, { oNoPermissionWarn, "no-permission-warning", 0, "@" }, { oNoMDCWarn, "no-mdc-warning", 0, "@" }, { oNoArmor, "no-armor", 0, "@"}, @@ -613,9 +602,7 @@ { oLockMultiple, "lock-multiple", 0, "@" }, { oLockNever, "lock-never", 0, "@" }, { oLoggerFD, "logger-fd",1, "@" }, -#ifdef __riscos__ { oLoggerFile, "logger-file",2, "@" }, -#endif /* __riscos__ */ { oUseEmbeddedFilename, "use-embedded-filename", 0, "@" }, { oNoUseEmbeddedFilename, "no-use-embedded-filename", 0, "@" }, { oUtf8Strings, "utf8-strings", 0, "@" }, @@ -930,6 +917,51 @@ } +/* Helper to open a file FNAME either for reading or writing to be + used with --status-file etc functions. Not generally useful but it + avoids the riscos specific functions and well some Windows people + might like it too. Prints an error message and returns -1 on + error. On success the file descriptor is returned. */ +static int +open_info_file (const char *fname, int for_write) +{ +#ifdef __riscos__ + return riscos_fdopenfile (fname, for_write); +#elif defined (ENABLE_SELINUX_HACKS) + /* We can't allow these even when testing for a secured filename + because files to be secured might not yet been secured. This is + similar to the option file but in that case it is unlikely that + sensitive information may be retrieved by means of error + messages. */ + return -1; +#else + int fd; + +/* if (is_secured_filename (fname)) */ +/* { */ +/* fd = -1; */ +/* errno = EPERM; */ +/* } */ +/* else */ +/* { */ + do + { + if (for_write) + fd = open (fname, O_CREAT | O_TRUNC | O_WRONLY, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + else + fd = open (fname, O_RDONLY | MY_O_BINARY); + } + while (fd == -1 && errno == EINTR); +/* } */ + if ( fd == -1) + log_error ( for_write? _("can't create `%s': %s\n") + : _("can't open `%s': %s\n"), fname, strerror(errno)); + + return fd; +#endif +} + static void set_cmd( enum cmd_and_opt_values *ret_cmd, enum cmd_and_opt_values new_cmd ) { @@ -1950,34 +1982,30 @@ case oStatusFD: set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) ); break; -#ifdef __riscos__ case oStatusFile: - set_status_fd( iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) ); + set_status_fd ( open_info_file (pargs.r.ret_str, 1) ); break; -#endif /* __riscos__ */ case oAttributeFD: set_attrib_fd(iobuf_translate_file_handle (pargs.r.ret_int, 1)); break; -#ifdef __riscos__ case oAttributeFile: - set_attrib_fd(iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) ); + set_attrib_fd ( open_info_file (pargs.r.ret_str, 1) ); break; -#endif /* __riscos__ */ case oLoggerFD: log_set_logfile( NULL, - iobuf_translate_file_handle (pargs.r.ret_int, 1) ); + iobuf_translate_file_handle (pargs.r.ret_int, 1)); break; -#ifdef __riscos__ case oLoggerFile: - log_set_logfile( NULL, - iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 1), 1) ); + log_set_logfile( NULL, open_info_file (pargs.r.ret_str, 1) ); break; -#endif /* __riscos__ */ + case oWithFingerprint: opt.with_fingerprint = 1; with_fpr=1; /*fall thru*/ case oFingerprint: opt.fingerprint++; break; - case oSecretKeyring: append_to_strlist( &sec_nrings, pargs.r.ret_str); break; + case oSecretKeyring: + append_to_strlist( &sec_nrings, pargs.r.ret_str); + break; case oOptions: /* config files may not be nested (silently ignore them) */ if( !configfp ) { @@ -2212,21 +2240,21 @@ pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0); opt.use_agent = 0; break; -#ifdef __riscos__ case oPasswdFile: - pwfd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0); + pwfd = open_info_file (pargs.r.ret_str, 0); break; -#endif /* __riscos__ */ case oCommandFD: opt.command_fd = iobuf_translate_file_handle (pargs.r.ret_int, 0); break; -#ifdef __riscos__ case oCommandFile: - opt.command_fd = iobuf_translate_file_handle ( riscos_fdopenfile (pargs.r.ret_str, 0), 0); + opt.command_fd = open_info_file (pargs.r.ret_str, 0); + break; + case oCipherAlgo: + def_cipher_string = m_strdup(pargs.r.ret_str); + break; + case oDigestAlgo: + def_digest_string = m_strdup(pargs.r.ret_str); break; -#endif /* __riscos__ */ - case oCipherAlgo: def_cipher_string = m_strdup(pargs.r.ret_str); break; - case oDigestAlgo: def_digest_string = m_strdup(pargs.r.ret_str); break; case oCompressAlgo: /* If it is all digits, stick a Z in front of it for later. This is for backwards compatibility with Index: gnupg/g10/keydb.h diff -u gnupg/g10/keydb.h:1.86 gnupg/g10/keydb.h:1.87 --- gnupg/g10/keydb.h:1.86 Thu Sep 23 15:32:30 2004 +++ gnupg/g10/keydb.h Wed Nov 17 17:04:21 2004 @@ -187,7 +187,9 @@ int have_static_passphrase(void); void read_passphrase_from_fd( int fd ); void passphrase_clear_cache ( u32 *keyid, int algo ); -char *ask_passphrase (const char *description, const char *promptid, +char *ask_passphrase (const char *description, + const char *tryagain_text, + const char *promptid, const char *prompt, int *canceled); DEK *passphrase_to_dek( u32 *keyid, int pubkey_algo, int cipher_algo, STRING2KEY *s2k, int mode, Index: gnupg/g10/passphrase.c diff -u gnupg/g10/passphrase.c:1.68 gnupg/g10/passphrase.c:1.69 --- gnupg/g10/passphrase.c:1.68 Wed Nov 3 21:03:46 2004 +++ gnupg/g10/passphrase.c Wed Nov 17 17:04:21 2004 @@ -267,19 +267,20 @@ size_t nleft = buflen; int nread; char *p; - + p = buf; - while (nleft > 0) + while( nleft > 0 ) { - nread = read (fd, buf, nleft); - if (nread < 0) + nread = read ( fd, buf, nleft ); + if( nread < 0 ) { - if (nread == EINTR) + if (errno == EINTR) nread = 0; - else { - log_error ("read() error: %s\n", strerror (errno)); - return -1; - } + else + { + log_error ( "read() error: %s\n", strerror (errno) ); + return -1; + } } else if (!nread) break; /* EOF */ @@ -1030,6 +1031,7 @@ */ char * ask_passphrase (const char *description, + const char *tryagain_text, const char *promptid, const char *prompt, int *canceled) { @@ -1044,7 +1046,9 @@ agent_died: if ( opt.use_agent ) { - pw = agent_get_passphrase (NULL, 0, description, canceled ); + pw = agent_get_passphrase (NULL, 0, + tryagain_text? tryagain_text :description, + canceled ); if (!pw) { if (!opt.use_agent) @@ -1063,6 +1067,8 @@ pw = NULL; } else { + if (tryagain_text) + tty_printf(_("%s.\n"), tryagain_text); pw = cpr_get_hidden(promptid? promptid : "passphrase.ask", prompt?prompt : _("Enter passphrase: ") ); tty_kill_prompt(); @@ -1177,7 +1183,7 @@ agent_died: if( next_pw ) { - /* Simply return the passpharse we already have in NEXT_PW. */ + /* Simply return the passphrase we already have in NEXT_PW. */ pw = next_pw; next_pw = NULL; } From cvs at cvs.gnupg.org Thu Nov 18 16:31:40 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Thu Nov 18 16:31:43 2004 Subject: dirmngr (11 files) Message-ID: Date: Thursday, November 18, 2004 @ 16:37:48 Author: wk Path: /cvs/dirmngr/dirmngr Modified: doc/dirmngr.texi src/ChangeLog src/certcache.c src/certcache.h src/crlcache.c src/dirmngr-client.c src/dirmngr.c src/dirmngr_ldap.c src/ldap.c src/server.c src/validate.c * dirmngr-client.c: New options --cache-cert and --validate. (do_cache, do_validate): New. * server.c (cmd_cachecert, cmd_validate): New. * crlcache.c (get_issuer_cert): Make use of the certificate cache. (crl_parse_insert): Validate the issuer certificate. * dirmngr.c (handle_signal): Reinitialize the certificate cache on a HUP. (struct opts): Add --homedir to enable the already implemented code. (handle_signal): Print stats on SIGUSR1. * certcache.c (clean_cache_slot, cert_cache_init) (cert_cache_deinit): New. (acquire_cache_read_lock, acquire_cache_write_lock) (release_cache_lock): New. Use them where needed. (put_cert): Renamed from put_loaded_cert. (cache_cert): New. (cert_cache_print_stats): New. ----------------------+ doc/dirmngr.texi | 110 ++++++++++++++ src/ChangeLog | 21 ++ src/certcache.c | 362 +++++++++++++++++++++++++++++++++++++++++++++++-- src/certcache.h | 17 ++ src/crlcache.c | 18 ++ src/dirmngr-client.c | 106 +++++++++++++- src/dirmngr.c | 13 + src/dirmngr_ldap.c | 2 src/ldap.c | 21 +- src/server.c | 110 ++++++++++++++ src/validate.c | 8 - 11 files changed, 754 insertions(+), 34 deletions(-) Index: dirmngr/doc/dirmngr.texi diff -u dirmngr/doc/dirmngr.texi:1.14 dirmngr/doc/dirmngr.texi:1.15 --- dirmngr/doc/dirmngr.texi:1.14 Tue Nov 16 19:24:35 2004 +++ dirmngr/doc/dirmngr.texi Thu Nov 18 16:37:48 2004 @@ -115,6 +115,7 @@ @menu * Dirmngr Commands:: List of all commands. * Dirmngr Options:: List of all options. +* Dirmngr Signals:: Use of signals. * Dirmngr Examples:: Some usage examples. * Dirmngr Protocol:: The protocol dirmngr uses. * Dirmngr Client:: How to use the Dirmngr client tool. @@ -352,6 +353,44 @@ @end table + +@c +@c Dirmngr Signals +@c +@node Dirmngr Signals +@chapter Use of signals. +A running @command{dirmngr} may be controlled by signals, i.e. using +the @command{kill} command to send a signal to the process. + +Here is a list of supported signals: + +@table @gnupgtabopt + +@item SIGHUP +@cpindex SIGHUP +This signals flushes all internally cached CRLs as well as any cached +certificates. Then the certificate cache is reinitialized as on +startup. + +@item SIGTERM +@cpindex SIGTERM +Shuts down the process but waits until all current requests are +fulfilled. If the process has received 3 of these signals and requests +are still pending, a shutdown is forced. + +@item SIGINT +@cpindex SIGINT +Shuts down the process immediately. + + +@item SIGUSR1 +@cpindex SIGUSR1 +This prints some caching statistics to the log file. + +@end table + + + @c @c Examples @c @@ -360,12 +399,30 @@ @c man begin 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: @example -$ dirmngr --server -v + dirmngr --server -v @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 +This will force it to go into the backround, read the default +certificates (including the trusted root certificates) and listen on a +socket for client requests. It does also print information about the +socket used but they are only for compatibilty reasons with old GnuPG +versions and may be ignored. + + + @c man end + + + @c @c Assuan Protocol @c @@ -380,6 +437,8 @@ * Dirmngr ISVALID:: Validate a certificate using a CRL or OCSP. * Dirmngr CHECKCRL:: Validate a certificate using a CRL. * Dirmngr CHECKOCSP:: Validate a certificate using OCSP. +* Dirmngr CACHECERT:: Put a certificate into the internal cache. +* Dirmngr VALIDATE:: Validate a certificate for debugging. @end menu @node Dirmngr LOOKUP @@ -504,6 +563,45 @@ The return code is 0 for success; i.e. the certificate has not been revoked or one of the usual error codes from libgpg-error. +@node Dirmngr CACHECERT +@section Put a certificate into the internal cache + +Put a certificate into the internal cache. This command might be +useful if a client knows in advance certificates required for a test and +wnats to make sure they get added to the internal cache. It is also +helpful for debugging. To get the actual certificate, this command +immediately inquires it using + +@example + S: INQUIRE TARGETCERT + C: D + C: END +@end example + +Thus the caller is expected to return the certificate for the request +as a binary blob. + +@noindent +The return code is 0 for success; i.e. the certificate has not been +succesfully cached or one of the usual error codes from libgpg-error. + +@node Dirmngr VALIDATE +@section Validate a certificate for debugging + +Validate a certificate using the certificate validation fucntion used +internally by dirmngr. This command is only useful for debugging. To +get the actual certificate, this command immediately inquires it using + +@example + S: INQUIRE TARGETCERT + C: D + C: END +@end example + +Thus the caller is expected to return the certificate for the request +as a binary blob. + + @c ------------------------------------------- @c Dirmngr Client @@ -594,6 +692,16 @@ also implicitly use with @code{--ping}. +@item --cache-cert +@opindex cache-cert +Put the given certificate into the cache of a running dirmngr. This is +mainly useful for debugging. + +@item --validate +@opindex validate +Validate the given certificate using dirmngr's internal validation code. +This is mainly useful for debugging. + @end table Index: dirmngr/src/ChangeLog diff -u dirmngr/src/ChangeLog:1.21 dirmngr/src/ChangeLog:1.22 --- dirmngr/src/ChangeLog:1.21 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/ChangeLog Thu Nov 18 16:37:48 2004 @@ -1,3 +1,24 @@ +2004-11-18 Werner Koch + + * dirmngr-client.c: New options --cache-cert and --validate. + (do_cache, do_validate): New. + * server.c (cmd_cachecert, cmd_validate): New. + + * crlcache.c (get_issuer_cert): Make use of the certificate cache. + (crl_parse_insert): Validate the issuer certificate. + + * dirmngr.c (handle_signal): Reinitialize the certificate cache on + a HUP. + (struct opts): Add --homedir to enable the already implemented code. + (handle_signal): Print stats on SIGUSR1. + * certcache.c (clean_cache_slot, cert_cache_init) + (cert_cache_deinit): New. + (acquire_cache_read_lock, acquire_cache_write_lock) + (release_cache_lock): New. Use them where needed. + (put_cert): Renamed from put_loaded_cert. + (cache_cert): New. + (cert_cache_print_stats): New. + 2004-11-16 Werner Koch * Makefile.am (AM_CPPFLAGS): Define DIRMNGR_SYSCONFDIR and Index: dirmngr/src/certcache.c diff -u dirmngr/src/certcache.c:1.1 dirmngr/src/certcache.c:1.2 --- dirmngr/src/certcache.c:1.1 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/certcache.c Thu Nov 18 16:37:48 2004 @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include #include @@ -31,6 +34,8 @@ #include "misc.h" #include "certcache.h" +#define MAX_EXTRA_CACHED_CERTS 200 /* FIXME: This is a debugging value. */ + /* A certificate cache item. This consists of a the ksba cert object and some meta data for easier lookup. We use a hash table to keep @@ -46,21 +51,58 @@ ksba_sexp_t sn; /* The malloced serial number */ struct { - int trusted; /* This is a trusted root certificate. */ - - - - + unsigned int loaded:1; /* It has been explicitly loaded. */ + unsigned int trusted:1; /* This is a trusted root certificate. */ } flags; }; typedef struct cert_item_s *cert_item_t; -/* The actual cert cache consisting of 256 slots for items idnex by +/* The actual cert cache consisting of 256 slots for items indexed by the first byte of the fingerprint. */ static cert_item_t cert_cache[256]; +/* This is the global cache_lock variable. In general looking is not + needed but it would take extra efforts to make sure that no + indirect use of pth functions is done, so we simply lock it + always. */ +static pth_rwlock_t cert_cache_lock = PTH_RWLOCK_INIT; + +/* Flag to track whether the cache has been initialized. */ +static int initialization_done; + +/* Total number of certificates loaded during initialization and + cached during operation. */ +static unsigned int total_loaded_certificates; +static unsigned int total_extra_certificates; + +/* Helper to do the cahce locking. */ +static void +acquire_cache_read_lock (void) +{ + if (!pth_rwlock_acquire (&cert_cache_lock, PTH_RWLOCK_RD, FALSE, NULL)) + log_fatal (_("can't acquire read lock on the certificate cache: %s\n"), + strerror (errno)); +} + +static void +acquire_cache_write_lock (void) +{ + if (!pth_rwlock_acquire (&cert_cache_lock, PTH_RWLOCK_RW, FALSE, NULL)) + log_fatal (_("can't acquire write lock on the certificate cache: %s\n"), + strerror (errno)); +} + +static void +release_cache_lock (void) +{ + if (!pth_rwlock_release (&cert_cache_lock)) + log_fatal (_("can't release lock on the certificate cache: %s\n"), + strerror (errno)); +} + + /* Return false if both serial numbers match. Can't be used for sorting. */ static int @@ -120,6 +162,296 @@ } +/* Cleanup one slot. This releases all resourses but keeps the actual + slot in the cache marked for reuse. */ +static void +clean_cache_slot (cert_item_t ci) +{ + ksba_cert_t cert; + + if (!ci->cert) + return; /* Already cleaned. */ + + ksba_free (ci->sn); + ci->sn = NULL; + ksba_free (ci->issuer_dn); + ci->issuer_dn = NULL; + cert = ci->cert; + ci->cert = NULL; + + ksba_cert_release (cert); +} + + +/* Put the certificate CERT into the cache. It is assumed that the + cache is locked while this function is called. */ +static gpg_error_t +put_cert (ksba_cert_t cert, int is_loaded, int is_trusted) +{ + unsigned char fpr[20]; + cert_item_t ci; + + /* If we already reached the caching limit, drop a couple of certs + from the cache. Our dropping strategy is simple: We keep a + static index counter and use this to start looking for + certificates, then we drop 5 percent of the oldest certificates + starting at that index. For a large cache this is a fair way of + removing items. An LRU strategy would be better of course. + Because we append new entries to the head of the list and we want + to remove old ones first, we need to do this from the tail. The + implementation is not very efficient but compared to the long + time it takes to retrieve a certifciate from an external resource + it seems to be reasonable. */ + if (!is_loaded && total_extra_certificates >= MAX_EXTRA_CACHED_CERTS) + { + static int idx; + cert_item_t ci_mark; + int i; + unsigned int drop_count; + + drop_count = MAX_EXTRA_CACHED_CERTS / 20; + if (drop_count < 2) + drop_count = 2; + + log_info (_("dropping %u certificates from the cache\n"), drop_count); + assert (idx < 256); + for (i=idx; drop_count; i = ((i+1)%256)) + { + ci_mark = NULL; + for (ci = cert_cache[i]; ci; ci = ci->next) + if (ci->cert && !ci->flags.loaded) + ci_mark = ci; + if (ci_mark) + { + clean_cache_slot (ci_mark); + drop_count--; + total_extra_certificates--; + } + } + if (i==idx) + idx++; + else + idx = i; + idx %= 256; + } + + compute_fpr (cert, fpr); + for (ci=cert_cache[*fpr]; ci; ci = ci->next) + if (ci->cert && !memcmp (ci->fpr, fpr, 20)) + return gpg_error (GPG_ERR_DUP_VALUE); + /* Try to reuse an existing entry. */ + for (ci=cert_cache[*fpr]; ci; ci = ci->next) + if (!ci->cert) + break; + if (!ci) + { /* No: Create a new entry. */ + ci = xtrycalloc (1, sizeof *ci); + if (!ci) + return gpg_error_from_errno (errno); + ci->next = cert_cache[*fpr]; + cert_cache[*fpr] = ci; + } + else + memset (&ci->flags, 0, sizeof ci->flags); + + ksba_cert_ref (cert); + ci->cert = cert; + memcpy (ci->fpr, fpr, 20); + ci->sn = ksba_cert_get_serial (cert); + ci->issuer_dn = ksba_cert_get_issuer (cert, 0); + if (!ci->issuer_dn || !ci->sn) + { + clean_cache_slot (ci); + return gpg_error (GPG_ERR_INV_CERT_OBJ); + } + ci->flags.loaded = !!is_loaded; + ci->flags.trusted = !!is_trusted; + + if (is_loaded) + total_loaded_certificates++; + else + total_extra_certificates++; + + return 0; +} + + +/* Load certificates from the directory DIRNAME. All certificates + matching the pattern "*.crt" are loaded. We assume that + certificates are DER encoded and not PEM encapsulated. The cache + should be in a locked state when calling this fucntion. */ +static gpg_error_t +load_certs_from_dir (const char *dirname, int are_trusted) +{ + gpg_error_t err; + DIR *dir; + struct dirent *ep; + char *p; + size_t n; + FILE *fp; + ksba_reader_t reader; + ksba_cert_t cert; + char *fname = NULL; + + dir = opendir (dirname); + if (!dir) + { + log_info (_("can't access directory `%s': %s\n"), + dirname, strerror (errno)); + return 0; /* We do not consider this a severe error. */ + } + + while ( (ep=readdir (dir)) ) + { + p = ep->d_name; + if (*p == '.' || !*p) + continue; /* Skip any hidden files and invalid entries. */ + n = strlen (p); + if ( n < 5 || strcmp (p+n-4,".crt") ) + continue; /* Not the desired "*.crt" pattern. */ + + xfree (fname); + fname = make_filename (dirname, p, NULL); + fp = fopen (fname, "rb"); + if (!fp) + { + log_error (_("can't open `%s': %s\n"), + fname, strerror (errno)); + continue; + } + err = ksba_reader_new (&reader); + if (!err) + err = ksba_reader_set_file (reader, fp); + if (err) + { + log_error (_("can't setup KSBA reader: %s\n"), gpg_strerror (err)); + ksba_reader_release (reader); + fclose (fp); + continue; + } + + err = ksba_cert_new (&cert); + if (!err) + err = ksba_cert_read_der (cert, reader); + ksba_reader_release (reader); + fclose (fp); + if (err) + { + log_error (_("can't parse certificate `%s': %s\n"), + fname, gpg_strerror (err)); + ksba_cert_release (cert); + continue; + } + + err = put_cert (cert, 1, are_trusted); + ksba_cert_release (cert); + if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) + log_info (_("certificate `%s' already cached\n"), fname); + else if (!err) + log_info (_("certificate `%s' loaded\n"), fname); + else + log_error (_("error loading certificate `%s': %s\n"), + fname, gpg_strerror (err)); + } + + xfree (fname); + closedir (dir); + return 0; +} + + +/* Initialize the certificate cache if not yet done. */ +void +cert_cache_init (void) +{ + char *dname; + + if (initialization_done) + return; + acquire_cache_write_lock (); + + dname = make_filename (opt.homedir, "trusted-certs", NULL); + load_certs_from_dir (dname, 1); + xfree (dname); + + dname = make_filename (opt.homedir, "extra-certs", NULL); + load_certs_from_dir (dname, 0); + xfree (dname); + + initialization_done = 1; + release_cache_lock (); + + cert_cache_print_stats (); +} + +/* Deinitialize the certificate cache. With FULL set to true even the + unused certificate slots are released. */ +void +cert_cache_deinit (int full) +{ + cert_item_t ci, ci2; + int i; + + if (!initialization_done) + return; + + acquire_cache_write_lock (); + + for (i=0; i < 256; i++) + for (ci=cert_cache[i]; ci; ci = ci->next) + clean_cache_slot (ci); + + if (full) + { + for (i=0; i < 256; i++) + { + for (ci=cert_cache[i]; ci; ci = ci2) + { + ci2 = ci->next; + xfree (ci); + } + cert_cache[i] = NULL; + } + } + + total_loaded_certificates = 0; + total_extra_certificates = 0; + initialization_done = 0; + release_cache_lock (); +} + +/* Print some statistics to the log file. */ +void +cert_cache_print_stats (void) +{ + log_info (_("permanently loaded certificates: %u\n"), + total_loaded_certificates); + log_info (_(" runtime cached certificates: %u\n"), + total_extra_certificates); +} + + +/* Put CERT into the certificate cache. */ +gpg_error_t +cache_cert (ksba_cert_t cert) +{ + gpg_error_t err; + + acquire_cache_write_lock (); + err = put_cert (cert, 0, 0); + release_cache_lock (); + if (gpg_err_code (err) == GPG_ERR_DUP_VALUE) + log_info (_("certificate already cached\n")); + else if (!err) + log_info (_("certificate cached\n")); + else + log_error (_("error caching certificate: %s\n"), + gpg_strerror (err)); + return err; +} + + + /* Return a certificate object for the given fingerprint. FPR is expected to be a 20 byte binary SHA-1 fingerprint. If no matching @@ -132,13 +464,16 @@ { cert_item_t ci; + acquire_cache_read_lock (); for (ci=cert_cache[*fpr]; ci; ci = ci->next) if (ci->cert && !memcmp (ci->fpr, fpr, 20)) { ksba_cert_ref (ci->cert); + release_cache_lock (); return ci->cert; } + release_cache_lock (); return NULL; } @@ -151,6 +486,7 @@ cert_item_t ci; int i; + acquire_cache_read_lock (); for (i=0; i < 256; i++) { for (ci=cert_cache[i]; ci; ci = ci->next) @@ -158,10 +494,12 @@ && !compare_serialno (ci->sn, serialno)) { ksba_cert_ref (ci->cert); + release_cache_lock (); return ci->cert; } } + release_cache_lock (); return NULL; } @@ -175,6 +513,7 @@ cert_item_t ci; int i; + acquire_cache_read_lock (); for (i=0; i < 256; i++) { for (ci=cert_cache[i]; ci; ci = ci->next) @@ -182,10 +521,12 @@ if (!seq--) { ksba_cert_ref (ci->cert); + release_cache_lock (); return ci->cert; } } + release_cache_lock (); return NULL; } @@ -219,18 +560,23 @@ compute_fpr (cert, fpr); + acquire_cache_read_lock (); for (ci=cert_cache[*fpr]; ci; ci = ci->next) if (ci->cert && !memcmp (ci->fpr, fpr, 20)) { if (ci->flags.trusted) - return 0; /* Yes it is trusted. */ + { + release_cache_lock (); + return 0; /* Yes, it is trusted. */ + } break; } + release_cache_lock (); return gpg_error (GPG_ERR_NOT_TRUSTED); } - + /* Given the certificate CERT locate the issuer for this certificate and return it at R_CERT. Returns 0 on success or GPG_ERR_NOT_FOUND. */ Index: dirmngr/src/certcache.h diff -u dirmngr/src/certcache.h:1.1 dirmngr/src/certcache.h:1.2 --- dirmngr/src/certcache.h:1.1 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/certcache.h Thu Nov 18 16:37:48 2004 @@ -21,6 +21,18 @@ #ifndef CERTCACHE_H #define CERTCACHE_H +/* First time initialization of the certificate cache. */ +void cert_cache_init (void); + +/* Deinitialize the certificate cache. */ +void cert_cache_deinit (int full); + +/* Print some statistics to the log file. */ +void cert_cache_print_stats (void); + + +/* Put CERT into the certificate cache. */ +gpg_error_t cache_cert (ksba_cert_t cert); /* Return 0 if the certificate is a trusted certificate. Returns GPG_ERR_NOT_TRUSTED if it is not trusted or other error codes in @@ -35,6 +47,11 @@ ksba_cert_t get_cert_byfpr (const unsigned char *fpr); +/* Return the certificate matching ISSUER_DN. SEQ should initially be + set to 0 and bumped up to get the next issuer with that DN. */ +ksba_cert_t get_cert_byissuer (const char *issuer_dn, unsigned int seq); + + /* Given the certificate CERT locate the issuer for this certificate and return it at R_CERT. Returns 0 on success or GPG_ERR_NOT_FOUND. */ Index: dirmngr/src/crlcache.c diff -u dirmngr/src/crlcache.c:1.46 dirmngr/src/crlcache.c:1.47 --- dirmngr/src/crlcache.c:1.46 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/crlcache.c Thu Nov 18 16:37:48 2004 @@ -97,6 +97,8 @@ #include #include "dirmngr.h" +#include "validate.h" +#include "certcache.h" #include "crlcache.h" #include "crlfetch.h" #include "misc.h" @@ -1263,6 +1265,11 @@ ksba_cert_t issuer_cert = NULL; ksba_reader_t reader; + /* First check whether it has already been cached. */ + issuer_cert = get_cert_byissuer (issuer, 0); + if (issuer_cert) + return issuer_cert; /* Done. */ + /* Ask back to the service requester to return the certificate. This is because we can assume that he already used the certificate while checking for the CRL. */ @@ -1297,6 +1304,9 @@ log_error (_("invalid issuer certificate: %s\n"), gpg_strerror (err) ); ksba_reader_release (reader); + if (!err) + cache_cert (issuer_cert); + return issuer_cert; } @@ -1543,6 +1553,14 @@ gpg_strerror (err)); goto failure; } + err = validate_cert_chain (issuer_cert, NULL); + if (err) + { + log_error (_("error checking validity of CRL " + "signing certificate: %s\n"), + gpg_strerror (err)); + goto failure; + } } break; Index: dirmngr/src/dirmngr-client.c diff -u dirmngr/src/dirmngr-client.c:1.1 dirmngr/src/dirmngr-client.c:1.2 --- dirmngr/src/dirmngr-client.c:1.1 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/dirmngr-client.c Thu Nov 18 16:37:48 2004 @@ -52,6 +52,8 @@ oOCSP = 500, oPing, + oCacheCert, + oValidate, oUseDaemon, oDummy }; @@ -61,9 +63,11 @@ static ARGPARSE_OPTS opts[] = { { oVerbose, "verbose", 0, N_("verbose") }, { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, + { oUseDaemon,"use-daemon",0, N_("force use of the daemon")}, { oOCSP, "ocsp", 0, N_("use OCSP instead of CRLs") }, { oPing, "ping", 0, N_("check whether a dirmngr is running")}, - { oUseDaemon,"use-daemon",0, N_("force use of the daemon")}, + { oCacheCert,"cache-cert",0, N_("add a certificate to the cache")}, + { oValidate, "validate", 0, N_("validate a certificate")}, {0} }; @@ -97,6 +101,10 @@ unsigned char **rbuf, size_t *rbuflen); static gpg_error_t do_check (assuan_context_t ctx, const unsigned char *cert, size_t certlen); +static gpg_error_t do_cache (assuan_context_t ctx, + const unsigned char *cert, size_t certlen); +static gpg_error_t do_validate (assuan_context_t ctx, + const unsigned char *cert, size_t certlen); @@ -156,9 +164,11 @@ gpg_error_t err; unsigned char *certbuf; size_t certbuflen; - int do_ping = 0; + int cmd_ping = 0; int use_daemon = 0; - + int cmd_cache_cert = 0; + int cmd_validate = 0; + set_strusage (my_strusage); log_set_prefix ("dirmngr-client", JNLIB_LOG_WITH_PREFIX); @@ -180,9 +190,12 @@ { case oVerbose: opt.verbose++; break; case oQuiet: opt.quiet++; break; - case oOCSP: opt.use_ocsp++; break; - case oPing: do_ping = 1; break; case oUseDaemon: use_daemon = 1; break; + + case oOCSP: opt.use_ocsp++; break; + case oPing: cmd_ping = 1; break; + case oCacheCert: cmd_cache_cert = 1; break; + case oValidate: cmd_validate = 1; break; default : pargs.err = 2; break; } @@ -190,7 +203,7 @@ if (log_get_errorcount (0)) exit (2); - if (do_ping) + if (cmd_ping) err = 0; else if (!argc) { @@ -221,11 +234,23 @@ exit (2); } - ctx = start_dirmngr (do_ping || use_daemon); + ctx = start_dirmngr (cmd_ping || use_daemon); if (!ctx) exit (2); - if (!do_ping) + if (cmd_ping) + ; + else if (cmd_cache_cert) + { + err = do_cache (ctx, certbuf, certbuflen); + xfree (certbuf); + } + else if (cmd_validate) + { + err = do_validate (ctx, certbuf, certbuflen); + xfree (certbuf); + } + else { err = do_check (ctx, certbuf, certbuflen); xfree (certbuf); @@ -233,12 +258,33 @@ assuan_disconnect (ctx); - if (do_ping) + if (cmd_ping) { if (!opt.quiet) log_info (_("a dirmngr daemon is up and running\n")); return 0; } + else if (cmd_cache_cert) + { + if (err && gpg_err_code (err) == GPG_ERR_DUP_VALUE ) + { + if (!opt.quiet) + log_info (_("certificate already cached\n")); + } + else if (err) + { + log_error (_("error caching certificate: %s\n"), + gpg_strerror (err)); + return 1; + } + return 0; + } + else if (cmd_validate && err) + { + log_error (_("validation of certificate failed: %s\n"), + gpg_strerror (err)); + return 1; + } else if (!err) { if (!opt.quiet) @@ -472,3 +518,45 @@ log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay"); return map_assuan_err (ae); } + +/* Check the certificate CERT,CERTLEN for validity using a CRL or OCSP. + Return a proper error code. */ +static gpg_error_t +do_cache (assuan_context_t ctx, const unsigned char *cert, size_t certlen) +{ + assuan_error_t ae; + struct inq_cert_parm_s parm; + + memset (&parm, 0, sizeof parm); + parm.ctx = ctx; + parm.cert = cert; + parm.certlen = certlen; + + ae = assuan_transact (ctx, "CACHECERT", NULL, NULL, + inq_cert, &parm, + NULL, NULL); + if (opt.verbose > 1) + log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay"); + return map_assuan_err (ae); +} + +/* Check the certificate CERT,CERTLEN for validity using dirmngrs + internal validate feature. Return a proper error code. */ +static gpg_error_t +do_validate (assuan_context_t ctx, const unsigned char *cert, size_t certlen) +{ + assuan_error_t ae; + struct inq_cert_parm_s parm; + + memset (&parm, 0, sizeof parm); + parm.ctx = ctx; + parm.cert = cert; + parm.certlen = certlen; + + ae = assuan_transact (ctx, "VALIDATE", NULL, NULL, + inq_cert, &parm, + NULL, NULL); + if (opt.verbose > 1) + log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay"); + return map_assuan_err (ae); +} Index: dirmngr/src/dirmngr.c diff -u dirmngr/src/dirmngr.c:1.41 dirmngr/src/dirmngr.c:1.42 --- dirmngr/src/dirmngr.c:1.41 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/dirmngr.c Thu Nov 18 16:37:48 2004 @@ -43,6 +43,7 @@ #define JNLIB_NEED_LOG_LOGV #include "dirmngr.h" +#include "certcache.h" #include "crlcache.h" #include "crlfetch.h" #include "misc.h" @@ -137,6 +138,7 @@ { oDebugAll, "debug-all" ,0, "@"}, { oDebugWait, "debug-wait", 1, "@"}, { oNoGreeting, "no-greeting", 0, "@"}, + { oHomedir, "homedir", 2, "@" }, {0} }; @@ -679,6 +681,7 @@ } launch_ripper_thread (); + cert_cache_init (); crl_cache_init (); start_command_handler (-1); } @@ -830,6 +833,7 @@ launch_ripper_thread (); + cert_cache_init (); crl_cache_init (); handle_connections (fd); close (fd); @@ -846,6 +850,7 @@ else if (cmd == aLoadCRL) { launch_ripper_thread (); + cert_cache_init (); crl_cache_init (); if (!argc) rc = crl_cache_load (NULL, NULL); @@ -863,6 +868,7 @@ wrong_args ("--fetch-crl URL"); launch_ripper_thread (); + cert_cache_init (); crl_cache_init (); rc = crl_fetch (argv[0], &reader); if (rc) @@ -947,6 +953,7 @@ cleanup (void) { crl_cache_deinit (); + cert_cache_deinit (1); free_ldapservers_list (opt.ldapservers); opt.ldapservers = NULL; @@ -1140,10 +1147,14 @@ 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 (); break; case SIGUSR1: - log_info (_("SIGUSR1 received - no action defined\n")); + cert_cache_print_stats (); break; case SIGUSR2: Index: dirmngr/src/dirmngr_ldap.c diff -u dirmngr/src/dirmngr_ldap.c:1.1 dirmngr/src/dirmngr_ldap.c:1.2 --- dirmngr/src/dirmngr_ldap.c:1.1 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/dirmngr_ldap.c Thu Nov 18 16:37:48 2004 @@ -209,8 +209,6 @@ if (opt.port < 0 || opt.port > 65535) log_error (_("invalid port number %d\n"), opt.port); - sleep (5); - if (log_get_errorcount (0)) exit (2); Index: dirmngr/src/ldap.c diff -u dirmngr/src/ldap.c:1.33 dirmngr/src/ldap.c:1.34 --- dirmngr/src/ldap.c:1.33 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/ldap.c Thu Nov 18 16:37:48 2004 @@ -472,8 +472,8 @@ return err; } - pid = fork (); - if (pid == -1) + pid = pth_fork (); + if (pid == (pid_t)(-1)) { err = gpg_error_from_errno (errno); log_error (_("error forking process: %s\n"), strerror (errno)); @@ -510,13 +510,6 @@ else arg_list[j] = (char*)argv[i]; - /* Connect stderr to the second pipe. */ - if (rp2[1] != STDERR_FILENO && dup2 (rp2[1], STDERR_FILENO) == -1) - { - log_error (_("dup2 failed in child: %s\n"), strerror (errno)); - _exit (4); - } - /* Connect stdin to /dev/null. */ fd = open ("/dev/null", O_RDONLY); if (fd == -1) @@ -536,6 +529,14 @@ log_error (_("dup2 failed in child: %s\n"), strerror (errno)); _exit (4); } + + /* Connect stderr to the second pipe. */ + if (rp2[1] != STDERR_FILENO && dup2 (rp2[1], STDERR_FILENO) == -1) + { + log_error (_("dup2 failed in child: %s\n"), strerror (errno)); + _exit (4); + } + /* Close all files which will not be duped. */ n = sysconf (_SC_OPEN_MAX); @@ -557,7 +558,7 @@ /* Parent. */ close (rp[1]); close (rp2[1]); - + ctx = xtrycalloc (1, sizeof *ctx); if (!ctx) { Index: dirmngr/src/server.c diff -u dirmngr/src/server.c:1.43 dirmngr/src/server.c:1.44 --- dirmngr/src/server.c:1.43 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/server.c Thu Nov 18 16:37:48 2004 @@ -38,6 +38,7 @@ #include "dirmngr.h" #include "ocsp.h" #include "certcache.h" +#include "validate.h" /* To avoid DoS attacks we limit the size of a certificate to something reasonable. */ @@ -905,6 +906,113 @@ } +/* CACHECERT + + Put a certificate into the internal cache. This command might be + usedful if a client knows in advance certificates required for a + test and wnats to make sure they get added to the internal cache. + It is also helpful for debugging. To get the actual certificate, + this command immediately inquires it using + + INQUIRE TARGETCERT + + and the caller is expected to return the certificate for the + request as a binary blob. +*/ +static int +cmd_cachecert (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + ksba_cert_t cert = NULL; + assuan_error_t ae; + unsigned char *value = NULL; + size_t valuelen; + + ae = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT", + &value, &valuelen, MAX_CERT_LENGTH); + if (ae) + { + log_error (_("assuan_inquire failed: %s\n"), assuan_strerror (ae)); + err = map_assuan_err (ae); + goto leave; + } + + if (!valuelen) /* No data returned; return a comprehensible error. */ + err = gpg_error (GPG_ERR_MISSING_CERT); + else + { + err = ksba_cert_new (&cert); + if (!err) + err = ksba_cert_init_from_mem (cert, value, valuelen); + } + xfree (value); + if(err) + goto leave; + + err = cache_cert (cert); + + leave: + if (err) + log_error (_("command %s failed: %s\n"), "CACHECERT", gpg_strerror (err)); + ksba_cert_release (cert); + return map_to_assuan_status (err); +} + + +/* VALIDATE + + Validate a certificate using the certificate validationj fucntion + used internally by dirmngr. This command is only useful for + debugging. To get the actual certificate, this command immediately + inquires it using + + INQUIRE TARGETCERT + + and the caller is expected to return the certificate for the + request as a binary blob. +*/ +static int +cmd_validate (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err; + ksba_cert_t cert = NULL; + assuan_error_t ae; + unsigned char *value = NULL; + size_t valuelen; + + ae = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT", + &value, &valuelen, MAX_CERT_LENGTH); + if (ae) + { + log_error (_("assuan_inquire failed: %s\n"), assuan_strerror (ae)); + err = map_assuan_err (ae); + goto leave; + } + + if (!valuelen) /* No data returned; return a comprehensible error. */ + err = gpg_error (GPG_ERR_MISSING_CERT); + else + { + err = ksba_cert_new (&cert); + if (!err) + err = ksba_cert_init_from_mem (cert, value, valuelen); + } + xfree (value); + if(err) + goto leave; + + err = validate_cert_chain (cert, NULL); + + leave: + if (err) + log_error (_("command %s failed: %s\n"), "VALIDATE", gpg_strerror (err)); + ksba_cert_release (cert); + return map_to_assuan_status (err); +} + + /* Tell the assuan library about our commands. */ static int @@ -920,6 +1028,8 @@ { "LOOKUP", cmd_lookup }, { "LOADCRL", cmd_loadcrl }, { "LISTCRLS", cmd_listcrls }, + { "CACHECERT", cmd_cachecert }, + { "VALIDATE", cmd_validate }, { "INPUT", NULL }, { "OUTPUT", NULL }, { NULL } Index: dirmngr/src/validate.c diff -u dirmngr/src/validate.c:1.1 dirmngr/src/validate.c:1.2 --- dirmngr/src/validate.c:1.1 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/validate.c Thu Nov 18 16:37:48 2004 @@ -169,6 +169,8 @@ /* Validate the certificate CHAIN up to the trust anchor. Optionally return the closest expiration time in R_EXPTIME (this is useful for caching issues). */ + + /* FIXME: We need to check for evoked certifciates too. */ gpg_error_t validate_cert_chain (ksba_cert_t cert, ksba_isotime_t r_exptime) { @@ -320,7 +322,7 @@ break; /* Okay: a self-signed certicate is an end-point. */ } - /* To avoid loops, we use an arbitary limit on tghe length of + /* To avoid loops, we use an arbitary limit on the length of the chain. */ depth++; if (depth > maxdepth) @@ -357,8 +359,8 @@ dump_cert ("issuer", issuer_cert); } - /* Now check the signature of the certificate. Well, not - really: We delay this until later so that fakedcertificates + /* Now check the signature of the certificate. Well, we + shouldnot delay this until later so that faked certificates can't be turned into a DoS easily. */ err = check_cert_sig (issuer_cert, subject_cert); if (err) From cvs at cvs.gnupg.org Thu Nov 18 16:54:59 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Thu Nov 18 16:55:02 2004 Subject: gnupg/g10 (ChangeLog g10.c) Message-ID: Date: Thursday, November 18, 2004 @ 17:01:08 Author: wk Path: /cvs/gnupg/gnupg/g10 Modified: ChangeLog g10.c (S_IRGRP) [HAVE_DOSISH_SYSTEM]: Define to 0. -----------+ ChangeLog | 4 ++++ g10.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.639 gnupg/g10/ChangeLog:1.640 --- gnupg/g10/ChangeLog:1.639 Wed Nov 17 17:04:21 2004 +++ gnupg/g10/ChangeLog Thu Nov 18 17:01:08 2004 @@ -1,3 +1,7 @@ +2004-11-18 Werner Koch + + * g10.c (S_IRGRP) [HAVE_DOSISH_SYSTEM]: Define to 0. + 2004-11-17 Werner Koch * g10.c (open_info_file): New. Index: gnupg/g10/g10.c diff -u gnupg/g10/g10.c:1.288 gnupg/g10/g10.c:1.289 --- gnupg/g10/g10.c:1.288 Wed Nov 17 17:04:21 2004 +++ gnupg/g10/g10.c Thu Nov 18 17:01:08 2004 @@ -60,12 +60,15 @@ #if defined(HAVE_DOSISH_SYSTEM) || defined(__CYGWIN__) #define MY_O_BINARY O_BINARY +#ifndef S_IRGRP +# define S_IRGRP 0 +# define S_IWGRP 0 +#endif #else #define MY_O_BINARY 0 #endif - enum cmd_and_opt_values { aNull = 0, From cvs at cvs.gnupg.org Thu Nov 18 20:09:21 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Thu Nov 18 20:09:24 2004 Subject: dirmngr/src (ChangeLog certcache.c dirmngr.c) Message-ID: Date: Thursday, November 18, 2004 @ 20:15:33 Author: wk Path: /cvs/dirmngr/dirmngr/src Modified: ChangeLog certcache.c dirmngr.c * dirmngr.c (main): Do not cd / if not running detached. * dirmngr.c (handle_signal): Reinitialize the certificate cache on a HUP. (struct opts): Add --homedir to enable the already implemented code. (handle_signal): Print stats on SIGUSR1. * certcache.c (clean_cache_slot, cert_cache_init) (cert_cache_deinit): New. (acquire_cache_read_lock, acquire_cache_write_lock) (release_cache_lock): New. Use them where needed. (put_cert): Renamed from put_loaded_cert. (cache_cert): New. (cert_cache_print_stats): New. (compare_serialno): Fixed. -------------+ ChangeLog | 4 ++++ certcache.c | 4 +++- dirmngr.c | 11 +++++------ 3 files changed, 12 insertions(+), 7 deletions(-) Index: dirmngr/src/ChangeLog diff -u dirmngr/src/ChangeLog:1.22 dirmngr/src/ChangeLog:1.23 --- dirmngr/src/ChangeLog:1.22 Thu Nov 18 16:37:48 2004 +++ dirmngr/src/ChangeLog Thu Nov 18 20:15:33 2004 @@ -1,5 +1,7 @@ 2004-11-18 Werner Koch + * dirmngr.c (main): Do not cd / if not running detached. + * dirmngr-client.c: New options --cache-cert and --validate. (do_cache, do_validate): New. * server.c (cmd_cachecert, cmd_validate): New. @@ -11,6 +13,7 @@ a HUP. (struct opts): Add --homedir to enable the already implemented code. (handle_signal): Print stats on SIGUSR1. + * certcache.c (clean_cache_slot, cert_cache_init) (cert_cache_deinit): New. (acquire_cache_read_lock, acquire_cache_write_lock) @@ -18,6 +21,7 @@ (put_cert): Renamed from put_loaded_cert. (cache_cert): New. (cert_cache_print_stats): New. + (compare_serialno): Fixed. 2004-11-16 Werner Koch Index: dirmngr/src/certcache.c diff -u dirmngr/src/certcache.c:1.2 dirmngr/src/certcache.c:1.3 --- dirmngr/src/certcache.c:1.2 Thu Nov 18 16:37:48 2004 +++ dirmngr/src/certcache.c Thu Nov 18 20:15:33 2004 @@ -127,7 +127,9 @@ } if (n_a != n_b) return 0; - + a++; + b++; + for (; n_a && *a == *b; n_a--, a++, b++) ; return !!n_a; Index: dirmngr/src/dirmngr.c diff -u dirmngr/src/dirmngr.c:1.42 dirmngr/src/dirmngr.c:1.43 --- dirmngr/src/dirmngr.c:1.42 Thu Nov 18 16:37:48 2004 +++ dirmngr/src/dirmngr.c Thu Nov 18 20:15:33 2004 @@ -823,14 +823,13 @@ log_get_prefix (&oldflags); log_set_prefix (NULL, oldflags | JNLIB_LOG_RUN_DETACHED); opt.running_detached = 1; - } - if (chdir("/")) - { - log_error (_("chdir to / failed: %s\n"), strerror (errno)); - dirmngr_exit (1); + if (chdir("/")) + { + log_error (_("chdir to / failed: %s\n"), strerror (errno)); + dirmngr_exit (1); + } } - launch_ripper_thread (); cert_cache_init (); From cvs at cvs.gnupg.org Fri Nov 19 13:17:20 2004 From: cvs at cvs.gnupg.org (cvs user werner) Date: Fri Nov 19 13:17:30 2004 Subject: misc-scripts (4 files) Message-ID: Date: Friday, November 19, 2004 @ 13:17:20 Author: werner Path: /cvs/wk/misc-scripts Added: rfc822parse.c rfc822parse.h Modified: ChangeLog scrutmime.c (parse_message): Increase buffer to 1000 to detect EXE files with a long header before the PE mark. ---------------+ ChangeLog | 5 rfc822parse.c | 1254 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ rfc822parse.h | 80 +++ scrutmime.c | 10 4 files changed, 1346 insertions(+), 3 deletions(-) From cvs at cvs.gnupg.org Fri Nov 19 16:21:14 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Fri Nov 19 16:21:19 2004 Subject: dirmngr (16 files) Message-ID: Date: Friday, November 19, 2004 @ 16:27:28 Author: wk Path: /cvs/dirmngr/dirmngr Modified: ChangeLog configure.ac src/ChangeLog src/certcache.c src/certcache.h src/crlcache.c src/crlcache.h src/crlfetch.c src/crlfetch.h src/dirmngr-client.c src/dirmngr.c src/dirmngr.h src/ldap.c src/server.c src/validate.c src/validate.h * configure.ac: Require libassuan 0.6.8. * dirmngr-client.c (status_cb): New. Use it in very verbose mode. * server.c (start_command_handler): Malloc the control structure and properly release it. Removed the primary_connection hack. Cleanup running wrappers. (dirmngr_status): Return an error code. (dirmngr_tick): Return an error code and detect a cancellation. Use wall time and not CPU time. * validate.c (validate_cert_chain): Add CTRL arg and changed callers. * crlcache.c (crl_cache_isvalid): * crlfetch.c (ca_cert_fetch, start_cert_fetch, crl_fetch_default) (crl_fetch): Ditto. * ldap.c (ldap_wrapper, run_ldap_wrapper, url_fetch_ldap) (attr_fetch_ldap, start_cert_fetch_ldap): Ditto. (ldap_wrapper_release_context): Reset the stored CTRL. (reader_callback): Periodically call dirmngr_tick. (ldap_wrapper_release_context): Print an error message for read errors. (ldap_wrapper_connection_cleanup): New. ----------------------+ ChangeLog | 4 ++ configure.ac | 2 - src/ChangeLog | 22 +++++++++++ src/certcache.c | 2 - src/certcache.h | 3 + src/crlcache.c | 6 +-- src/crlcache.h | 3 + src/crlfetch.c | 18 ++++----- src/crlfetch.h | 22 +++++++---- src/dirmngr-client.c | 15 ++++++- src/dirmngr.c | 6 ++- src/dirmngr.h | 5 +- src/ldap.c | 98 ++++++++++++++++++++++++++++++++++++++++--------- src/server.c | 95 ++++++++++++++++++++++++++++------------------- src/validate.c | 4 +- src/validate.h | 3 + 16 files changed, 219 insertions(+), 89 deletions(-) Index: dirmngr/ChangeLog diff -u dirmngr/ChangeLog:1.76 dirmngr/ChangeLog:1.77 --- dirmngr/ChangeLog:1.76 Tue Nov 16 19:24:36 2004 +++ dirmngr/ChangeLog Fri Nov 19 16:27:28 2004 @@ -1,3 +1,7 @@ +2004-11-19 Werner Koch + + * configure.ac: Require libassuan 0.6.8. + 2004-11-15 Werner Koch * tests/show-multi.c: New. Index: dirmngr/configure.ac diff -u dirmngr/configure.ac:1.61 dirmngr/configure.ac:1.62 --- dirmngr/configure.ac:1.61 Tue Nov 16 19:24:36 2004 +++ dirmngr/configure.ac Fri Nov 19 16:27:28 2004 @@ -29,7 +29,7 @@ NEED_LIBGCRYPT_API=1 NEED_LIBGCRYPT_VERSION=1.1.94 -NEED_LIBASSUAN_VERSION=0.6.5 +NEED_LIBASSUAN_VERSION=0.6.8 NEED_KSBA_VERSION=0.9.6 Index: dirmngr/src/ChangeLog diff -u dirmngr/src/ChangeLog:1.23 dirmngr/src/ChangeLog:1.24 --- dirmngr/src/ChangeLog:1.23 Thu Nov 18 20:15:33 2004 +++ dirmngr/src/ChangeLog Fri Nov 19 16:27:28 2004 @@ -1,3 +1,25 @@ +2004-11-19 Werner Koch + + * dirmngr-client.c (status_cb): New. Use it in very verbose mode. + + * server.c (start_command_handler): Malloc the control structure + and properly release it. Removed the primary_connection + hack. Cleanup running wrappers. + (dirmngr_status): Return an error code. + (dirmngr_tick): Return an error code and detect a + cancellation. Use wall time and not CPU time. + * validate.c (validate_cert_chain): Add CTRL arg and changed callers. + * crlcache.c (crl_cache_isvalid): + * crlfetch.c (ca_cert_fetch, start_cert_fetch, crl_fetch_default) + (crl_fetch): Ditto. + * ldap.c (ldap_wrapper, run_ldap_wrapper, url_fetch_ldap) + (attr_fetch_ldap, start_cert_fetch_ldap): Ditto. + (ldap_wrapper_release_context): Reset the stored CTRL. + (reader_callback): Periodically call dirmngr_tick. + (ldap_wrapper_release_context): Print an error message for read + errors. + (ldap_wrapper_connection_cleanup): New. + 2004-11-18 Werner Koch * dirmngr.c (main): Do not cd / if not running detached. Index: dirmngr/src/certcache.c diff -u dirmngr/src/certcache.c:1.3 dirmngr/src/certcache.c:1.4 --- dirmngr/src/certcache.c:1.3 Thu Nov 18 20:15:33 2004 +++ dirmngr/src/certcache.c Fri Nov 19 16:27:28 2004 @@ -583,7 +583,7 @@ and return it at R_CERT. Returns 0 on success or GPG_ERR_NOT_FOUND. */ gpg_error_t -find_issuing_cert (ksba_cert_t cert, ksba_cert_t *r_cert) +find_issuing_cert (ctrl_t ctrl, ksba_cert_t cert, ksba_cert_t *r_cert) { gpg_error_t err; char *issuer_dn; Index: dirmngr/src/certcache.h diff -u dirmngr/src/certcache.h:1.2 dirmngr/src/certcache.h:1.3 --- dirmngr/src/certcache.h:1.2 Thu Nov 18 16:37:48 2004 +++ dirmngr/src/certcache.h Fri Nov 19 16:27:28 2004 @@ -55,7 +55,8 @@ /* Given the certificate CERT locate the issuer for this certificate and return it at R_CERT. Returns 0 on success or GPG_ERR_NOT_FOUND. */ -gpg_error_t find_issuing_cert (ksba_cert_t cert, ksba_cert_t *r_cert); +gpg_error_t find_issuing_cert (ctrl_t ctrl, + ksba_cert_t cert, ksba_cert_t *r_cert); Index: dirmngr/src/crlcache.c diff -u dirmngr/src/crlcache.c:1.47 dirmngr/src/crlcache.c:1.48 --- dirmngr/src/crlcache.c:1.47 Thu Nov 18 16:37:48 2004 +++ dirmngr/src/crlcache.c Fri Nov 19 16:27:28 2004 @@ -1135,7 +1135,7 @@ that invoking this function several times won't load the CRL over and over. */ crl_cache_result_t -crl_cache_isvalid (const char *issuer_hash, const char *serialno, +crl_cache_isvalid (ctrl_t ctrl, const char *issuer_hash, const char *serialno, int force_refresh) { crl_cache_t cache = get_current_cache (); @@ -1282,7 +1282,7 @@ log_debug ("certificate for CRL issuer not returned by caller" " - doing lookup\n"); - err = ca_cert_fetch (issuer, &reader); + err = ca_cert_fetch (ctrl, issuer, &reader); if (err) { log_error (_("error fetching certificate for issuer: %s\n"), @@ -1553,7 +1553,7 @@ gpg_strerror (err)); goto failure; } - err = validate_cert_chain (issuer_cert, NULL); + err = validate_cert_chain (ctrl, issuer_cert, NULL); if (err) { log_error (_("error checking validity of CRL " Index: dirmngr/src/crlcache.h diff -u dirmngr/src/crlcache.h:1.22 dirmngr/src/crlcache.h:1.23 --- dirmngr/src/crlcache.h:1.22 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/crlcache.h Fri Nov 19 16:27:28 2004 @@ -56,7 +56,8 @@ void crl_cache_deinit (void); int crl_cache_flush(void); -crl_cache_result_t crl_cache_isvalid (const char *issuer_hash, +crl_cache_result_t crl_cache_isvalid (ctrl_t ctrl, + const char *issuer_hash, const char *cert_id, int force_refresh); Index: dirmngr/src/crlfetch.c diff -u dirmngr/src/crlfetch.c:1.19 dirmngr/src/crlfetch.c:1.20 --- dirmngr/src/crlfetch.c:1.19 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/crlfetch.c Fri Nov 19 16:27:28 2004 @@ -34,7 +34,7 @@ object in READER. Note that this reader object should be closed only using ldap_close_reader. */ gpg_error_t -crl_fetch (const char *url, ksba_reader_t *reader) +crl_fetch (ctrl_t ctrl, const char *url, ksba_reader_t *reader) { gpg_error_t err; parsed_uri_t uri; @@ -103,7 +103,7 @@ { const char *s; - err = url_fetch_ldap (url, NULL, 0, reader); + err = url_fetch_ldap (ctrl, url, NULL, 0, reader); /* if (err) */ /* { */ /* /\* If the function failed we try again using our default */ @@ -142,26 +142,26 @@ /* Fetch CRL for ISSUER using a default server. Return the entire CRL as a newly opened stream returned in R_FP. */ gpg_error_t -crl_fetch_default (const char *issuer, ksba_reader_t *reader) +crl_fetch_default (ctrl_t ctrl, const char *issuer, ksba_reader_t *reader) { - return attr_fetch_ldap (issuer, "certificateRevocationList;binary", - reader); + return attr_fetch_ldap (ctrl, issuer, "certificateRevocationList;binary", + reader); } /* Fetch a CA certificate for DN using the default server. */ int -ca_cert_fetch (const char *dn, ksba_reader_t *reader) +ca_cert_fetch (ctrl_t ctrl, const char *dn, ksba_reader_t *reader) { - return attr_fetch_ldap (dn, "cACertificate;binary", reader); + return attr_fetch_ldap (ctrl, dn, "cACertificate;binary", reader); } gpg_error_t -start_cert_fetch (cert_fetch_context_t *context, +start_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context, strlist_t patterns, const ldap_server_t server) { - return start_cert_fetch_ldap (context, patterns, server); + return start_cert_fetch_ldap (ctrl, context, patterns, server); } gpg_error_t Index: dirmngr/src/crlfetch.h diff -u dirmngr/src/crlfetch.h:1.11 dirmngr/src/crlfetch.h:1.12 --- dirmngr/src/crlfetch.h:1.11 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/crlfetch.h Fri Nov 19 16:27:28 2004 @@ -31,18 +31,20 @@ /* Fetch CRL from URL. */ -gpg_error_t crl_fetch (const char* url, ksba_reader_t *reader); +gpg_error_t crl_fetch (ctrl_t ctrl, const char* url, ksba_reader_t *reader); /* Fetch CRL for ISSUER using default server. */ -gpg_error_t crl_fetch_default (const char* issuer, ksba_reader_t *reader); +gpg_error_t crl_fetch_default (ctrl_t ctrl, + const char* issuer, ksba_reader_t *reader); /* Fetch cert for DN. */ -int ca_cert_fetch (const char *dn, ksba_reader_t *reader); +int ca_cert_fetch (ctrl_t ctrl, const char *dn, ksba_reader_t *reader); /* Query the server for certs matching patterns. */ -gpg_error_t start_cert_fetch (cert_fetch_context_t *context, +gpg_error_t start_cert_fetch (ctrl_t ctrl, + cert_fetch_context_t *context, strlist_t patterns, const ldap_server_t server); gpg_error_t fetch_next_cert(cert_fetch_context_t context, @@ -57,14 +59,18 @@ /*-- ldap.c --*/ void *ldap_wrapper_thread (void*); void ldap_wrapper_release_context (ksba_reader_t reader); +void ldap_wrapper_connection_cleanup (ctrl_t); -gpg_error_t url_fetch_ldap (const char *url, const char *host, int port, - ksba_reader_t *reader); -gpg_error_t attr_fetch_ldap (const char *dn, const char *attr, +gpg_error_t url_fetch_ldap (ctrl_t ctrl, + const char *url, const char *host, int port, ksba_reader_t *reader); +gpg_error_t attr_fetch_ldap (ctrl_t ctrl, + const char *dn, const char *attr, + ksba_reader_t *reader); -gpg_error_t start_cert_fetch_ldap(cert_fetch_context_t *context, +gpg_error_t start_cert_fetch_ldap(ctrl_t ctrl, + cert_fetch_context_t *context, strlist_t patterns, const ldap_server_t server ); gpg_error_t fetch_next_cert_ldap (cert_fetch_context_t context, Index: dirmngr/src/dirmngr-client.c diff -u dirmngr/src/dirmngr-client.c:1.2 dirmngr/src/dirmngr-client.c:1.3 --- dirmngr/src/dirmngr-client.c:1.2 Thu Nov 18 16:37:48 2004 +++ dirmngr/src/dirmngr-client.c Fri Nov 19 16:27:28 2004 @@ -305,6 +305,15 @@ } +/* Print status line from the assuan protocol. */ +static assuan_error_t +status_cb (void *opaque, const char *line) +{ + if (opt.verbose > 2) + log_info (_("got status: `%s'\n"), line); + return 0; +} + /* Try to connect to the dirmngr via socket or fork it off and work by pipes. Handle the server's initial greeting */ static assuan_context_t @@ -513,7 +522,7 @@ ae = assuan_transact (ctx, opt.use_ocsp? "CHECKOCSP":"CHECKCRL", NULL, NULL, inq_cert, &parm, - NULL, NULL); + status_cb, NULL); if (opt.verbose > 1) log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay"); return map_assuan_err (ae); @@ -534,7 +543,7 @@ ae = assuan_transact (ctx, "CACHECERT", NULL, NULL, inq_cert, &parm, - NULL, NULL); + status_cb, NULL); if (opt.verbose > 1) log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay"); return map_assuan_err (ae); @@ -555,7 +564,7 @@ ae = assuan_transact (ctx, "VALIDATE", NULL, NULL, inq_cert, &parm, - NULL, NULL); + status_cb, NULL); if (opt.verbose > 1) log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay"); return map_assuan_err (ae); Index: dirmngr/src/dirmngr.c diff -u dirmngr/src/dirmngr.c:1.43 dirmngr/src/dirmngr.c:1.44 --- dirmngr/src/dirmngr.c:1.43 Thu Nov 18 20:15:33 2004 +++ dirmngr/src/dirmngr.c Fri Nov 19 16:27:28 2004 @@ -862,14 +862,18 @@ else if (cmd == aFetchCRL) { ksba_reader_t reader; + struct server_control_s ctrlbuf; if (argc != 1) wrong_args ("--fetch-crl URL"); + memset (&ctrlbuf, 0, sizeof ctrlbuf); + dirmngr_init_default_ctrl (&ctrlbuf); + launch_ripper_thread (); cert_cache_init (); crl_cache_init (); - rc = crl_fetch (argv[0], &reader); + rc = crl_fetch (&ctrlbuf, argv[0], &reader); if (rc) log_error (_("fetching CRL from `%s' failed: %s\n"), argv[0], gpg_strerror (rc)); Index: dirmngr/src/dirmngr.h diff -u dirmngr/src/dirmngr.h:1.19 dirmngr/src/dirmngr.h:1.20 --- dirmngr/src/dirmngr.h:1.19 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/dirmngr.h Fri Nov 19 16:27:28 2004 @@ -110,6 +110,7 @@ struct server_local_s; struct server_control_s { + int refcount; /* Count additional references to this object. */ int no_server; /* We are not running under server control. */ int status_fd; /* Only for non-server mode. */ struct server_local_s *server_local; @@ -127,8 +128,8 @@ ksba_cert_t get_cert_local (ctrl_t ctrl, const char *issuer); ksba_cert_t get_issuing_cert_local (ctrl_t ctrl, const char *issuer); void start_command_handler (int fd); -void dirmngr_status (ctrl_t ctrl, const char *keyword, ...); -void dirmngr_tick (ctrl_t ctrl); +gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...); +gpg_error_t dirmngr_tick (ctrl_t ctrl); #endif /*DIRMNGR_H*/ Index: dirmngr/src/ldap.c diff -u dirmngr/src/ldap.c:1.34 dirmngr/src/ldap.c:1.35 --- dirmngr/src/ldap.c:1.34 Thu Nov 18 16:37:48 2004 +++ dirmngr/src/ldap.c Fri Nov 19 16:27:28 2004 @@ -67,9 +67,13 @@ struct wrapper_context_s *next; 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. */ - int fd_error; /* Set to the errno of the last read error if any. */ - int log_fd; /* Connected with stdoerr 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. */ + 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). */ @@ -341,13 +345,40 @@ ctx->fd = -1; close (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; } } +/* Cleanup all resources hel by the connection associated with + CTRL. This is used after a cancel to kill running wrappers. */ +void +ldap_wrapper_connection_cleanup (ctrl_t ctrl) +{ + struct wrapper_context_s *ctx; + + 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)) + kill (ctx->pid, SIGTERM); + if (ctx->fd_error) + log_info (_("reading from ldap wrapper %d failed: %s\n"), + ctx->printable_pid, gpg_strerror (ctx->fd_error)); + } +} -/* This is the callback used by the ldap wrapper to feed the ksab +/* This is the callback used by the ldap wrapper to feed the ksba reader with the wrappers stdout. See the description of ksba_reader_set_cb for details. */ static int @@ -356,7 +387,7 @@ struct wrapper_context_s *ctx = cb_value; size_t nleft = count; - /* FIXME: We might want to add some internal buffering becuase the + /* FIXME: We might want to add some internal buffering because the ksba code does not not any buffering for itself (because a ksba reader may be detached from another stream to read other data and the it would be cumbersome to get back already buffered @@ -366,7 +397,7 @@ return -1; /* Rewind is not supported. */ /* If we ever encountered a read error don't allow to continue and - possible overwrite the last error cause. Bail out alos if the + possible overwrite the last error cause. Bail out also if the file descriptor has been closed. */ if (ctx->fd_error || ctx->fd == -1) { @@ -376,26 +407,50 @@ while (nleft > 0) { - int n = pth_read ( ctx->fd, buffer, nleft ); - if (n < 0 && errno == EINTR) - n = 0; + int n; + pth_event_t evt; + gpg_error_t err; + + evt = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0) ); + n = pth_read_ev ( ctx->fd, buffer, nleft, evt); + if (n < 0 && evt && pth_event_occurred (evt) ) + { + n = 0; + err = dirmngr_tick (ctx->ctrl); + if (err) + { + ctx->fd_error = err; + close (ctx->fd); + ctx->fd = -1; + if (evt) + pth_event_free (evt, PTH_FREE_THIS); + return -1; + } + + } else if (n < 0) { - ctx->fd_error = errno; + ctx->fd_error = gpg_error_from_errno (errno); close (ctx->fd); ctx->fd = -1; + if (evt) + pth_event_free (evt, PTH_FREE_THIS); return -1; } else if (!n) { if (nleft == count) { + if (evt) + pth_event_free (evt, PTH_FREE_THIS); return -1; /* EOF. */ } break; } nleft -= n; buffer += n; + if (evt) + pth_event_free (evt, PTH_FREE_THIS); } *nread = count - nleft; @@ -439,7 +494,7 @@ that confidential. */ static gpg_error_t -ldap_wrapper (ksba_reader_t *reader, const char *argv[]) +ldap_wrapper (ctrl_t ctrl, ksba_reader_t *reader, const char *argv[]) { gpg_error_t err; pid_t pid; @@ -570,8 +625,11 @@ return err; } ctx->pid = pid; + ctx->printable_pid = (int)pid; ctx->fd = rp[0]; ctx->log_fd = rp2[0]; + ctx->ctrl = ctrl; + ctrl->refcount++; err = ksba_reader_new (reader); if (!err) @@ -599,7 +657,8 @@ /* Perform an LDAP query. Returns an gpg error code or 0 on success. The function returns a new stream at R_FP. */ static gpg_error_t -run_ldap_wrapper (const char *host, int port, +run_ldap_wrapper (ctrl_t ctrl, + const char *host, int port, const char *user, const char *pass, const char *dn, const char *filter, const char *attr, const char *url, @@ -653,7 +712,7 @@ argv[argc++] = url? url : "ldap://"; argv[argc] = NULL; - return ldap_wrapper (reader, argv); + return ldap_wrapper (ctrl, reader, argv); } @@ -663,10 +722,11 @@ reader is returned. If HOST or PORT ar not 0, they are used to override the values from the URL. */ gpg_error_t -url_fetch_ldap (const char *url, const char *host, int port, +url_fetch_ldap (ctrl_t ctrl, const char *url, const char *host, int port, ksba_reader_t *reader) { - return run_ldap_wrapper (host, port, + return run_ldap_wrapper (ctrl, + host, port, NULL, NULL, NULL, NULL, NULL, url, reader); @@ -684,7 +744,8 @@ /* Perform an LDAP query on all configured servers. On error the error code of the last try is returned. */ gpg_error_t -attr_fetch_ldap (const char *dn, const char *attr, ksba_reader_t *reader) +attr_fetch_ldap (ctrl_t ctrl, + const char *dn, const char *attr, ksba_reader_t *reader) { struct ldap_server_s *server; gpg_error_t err = gpg_error (GPG_ERR_CONFIGURATION); @@ -692,7 +753,8 @@ *reader = NULL; for (server = opt.ldapservers; server; server = server->next) { - err = run_ldap_wrapper (server->host, server->port, + err = run_ldap_wrapper (ctrl, + server->host, server->port, server->user, server->pass, dn, "objectClass=*", attr, NULL, reader); @@ -878,7 +940,7 @@ the SERVER. This function retruns an error code or 0 and a CONTEXT on success. */ gpg_error_t -start_cert_fetch_ldap (cert_fetch_context_t *context, +start_cert_fetch_ldap (ctrl_t ctrl, cert_fetch_context_t *context, strlist_t patterns, const ldap_server_t server) { gpg_error_t err; @@ -973,7 +1035,7 @@ if (!*context) return gpg_error_from_errno (errno); - err = ldap_wrapper (&(*context)->reader, argv); + err = ldap_wrapper (ctrl, &(*context)->reader, argv); if (err) { Index: dirmngr/src/server.c diff -u dirmngr/src/server.c:1.44 dirmngr/src/server.c:1.45 --- dirmngr/src/server.c:1.44 Thu Nov 18 16:37:48 2004 +++ dirmngr/src/server.c Fri Nov 19 16:27:28 2004 @@ -47,14 +47,9 @@ #define PARM_ERROR(t) assuan_set_error (ctx, ASSUAN_Parameter_Error, (t)) -/* We keep track of the primary client using us. This is mainly a - hack to send the progress info back. */ -static ctrl_t primary_connection; - /* Data used to associate an Assuan context with local server data */ struct server_local_s { ASSUAN_CONTEXT assuan_ctx; - int message_fd; }; @@ -237,7 +232,7 @@ ksba_name_release (issuername); issuername = NULL; any_dist_point = 1; - err = crl_fetch (distpoint_uri, &reader); + err = crl_fetch (ctrl, distpoint_uri, &reader); if (err) { log_error (_("crl_fetch via DP failed: %s\n"), gpg_strerror (err)); @@ -275,7 +270,7 @@ goto leave; } - err = crl_fetch_default (issuer, &reader); + err = crl_fetch_default (ctrl, issuer, &reader); if (err) { log_error (_("crl_fetch via issuer failed: %s\n"), @@ -434,7 +429,8 @@ } else { - switch (crl_cache_isvalid (issuerhash, serialno, + switch (crl_cache_isvalid (ctrl, + issuerhash, serialno, ctrl->force_crl_refresh)) { case CRL_CACHE_VALID: @@ -643,7 +639,8 @@ int reloaded = 0; again: - switch (crl_cache_isvalid (issuerhash_hex, serialno, + switch (crl_cache_isvalid (ctrl, + issuerhash_hex, serialno, ctrl->force_crl_refresh)) { case CRL_CACHE_VALID: @@ -729,6 +726,7 @@ static int cmd_lookup (assuan_context_t ctx, char *line) { + ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err = 0; assuan_error_t ae; char *p; @@ -775,7 +773,7 @@ ldapserver->base?ldapserver->base : "[default]"); /* Fetch certificates matching pattern */ - err = start_cert_fetch (&fetch_context, list, ldapserver); + err = start_cert_fetch (ctrl, &fetch_context, list, ldapserver); if (err) { log_error (_("start_cert_fetch failed: %s\n"), gpg_strerror (err)); @@ -1003,7 +1001,7 @@ if(err) goto leave; - err = validate_cert_chain (cert, NULL); + err = validate_cert_chain (ctrl, cert, NULL); leave: if (err) @@ -1053,10 +1051,20 @@ { int rc; assuan_context_t ctx; - struct server_control_s ctrl; + ctrl_t ctrl; - memset (&ctrl, 0, sizeof ctrl); - dirmngr_init_default_ctrl (&ctrl); + ctrl = xtrycalloc (1, sizeof *ctrl); + if (ctrl) + ctrl->server_local = xtrycalloc (1, sizeof *ctrl->server_local); + if (!ctrl || !ctrl->server_local) + { + log_error (_("can't allocate control structure: %s\n"), + strerror (errno)); + xfree (ctrl); + return; + } + + dirmngr_init_default_ctrl (ctrl); if (fd == -1) { @@ -1088,17 +1096,12 @@ assuan_set_hello_line (ctx, "Dirmngr " VERSION " at your service"); assuan_register_option_handler (ctx, option_handler); - assuan_set_pointer (ctx, &ctrl); - ctrl.server_local = xcalloc (1, sizeof *ctrl.server_local); - ctrl.server_local->assuan_ctx = ctx; - ctrl.server_local->message_fd = -1; + ctrl->server_local->assuan_ctx = ctx; + assuan_set_pointer (ctx, ctrl); if (DBG_ASSUAN) assuan_set_log_stream (ctx, log_get_stream ()); - if (!primary_connection) - primary_connection = &ctrl; - for (;;) { rc = assuan_accept (ctx); @@ -1118,20 +1121,29 @@ } } - if (primary_connection == &ctrl) - primary_connection = NULL; - + ldap_wrapper_connection_cleanup (ctrl); + ctrl->server_local->assuan_ctx = NULL; assuan_deinit_server (ctx); + + if (ctrl->refcount) + log_error ("oops: connection control structure still referenced (%d)\n", + ctrl->refcount); + else + { + xfree (ctrl->server_local); + xfree (ctrl); + } } /* Send a status line back to the client. KEYWORD is the status keyword, the optioal string argumenst are blank separated added to the line, the last argument must be a NULL. */ -void +gpg_error_t dirmngr_status (ctrl_t ctrl, const char *keyword, ...) { + gpg_error_t err = 0; va_list arg_ptr; const char *text; @@ -1156,34 +1168,41 @@ *p++ = *text++; } *p = 0; - assuan_write_status (ctx, keyword, buf); + err = map_assuan_err (assuan_write_status (ctx, keyword, buf)); } va_end (arg_ptr); + return err; } /* Note, that we ignore CTRL for now but use the first connection to send the progress info back. */ -void +gpg_error_t dirmngr_tick (ctrl_t ctrl) { - static clock_t next_tick = 0; - clock_t now = clock (); + static time_t next_tick = 0; + gpg_error_t err = 0; + time_t now = time (NULL); if (!next_tick) { - next_tick = now + CLOCKS_PER_SEC; - if (next_tick < now) - next_tick = 0; + next_tick = now + 1; } else if ( now > next_tick ) { - next_tick = now + CLOCKS_PER_SEC; - if (next_tick < now) - next_tick = 0; - - if (primary_connection) - dirmngr_status (primary_connection, "PROGRESS", "tick", "? 0 0", NULL); + if (ctrl) + { + err = dirmngr_status (ctrl, "PROGRESS", "tick", "? 0 0", NULL); + if (err) + { + /* Take this as in indication for a cancel request. */ + err = gpg_error (GPG_ERR_CANCELED); + } + now = time (NULL); + } + + next_tick = now + 1; } + return err; } Index: dirmngr/src/validate.c diff -u dirmngr/src/validate.c:1.2 dirmngr/src/validate.c:1.3 --- dirmngr/src/validate.c:1.2 Thu Nov 18 16:37:48 2004 +++ dirmngr/src/validate.c Fri Nov 19 16:27:28 2004 @@ -172,7 +172,7 @@ /* FIXME: We need to check for evoked certifciates too. */ gpg_error_t -validate_cert_chain (ksba_cert_t cert, ksba_isotime_t r_exptime) +validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime) { gpg_error_t err = 0; int depth = 0, maxdepth; @@ -334,7 +334,7 @@ /* Find the next cert up the tree. */ ksba_cert_release (issuer_cert); issuer_cert = NULL; - err = find_issuing_cert (subject_cert, &issuer_cert); + err = find_issuing_cert (ctrl, subject_cert, &issuer_cert); if (err) { if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) Index: dirmngr/src/validate.h diff -u dirmngr/src/validate.h:1.1 dirmngr/src/validate.h:1.2 --- dirmngr/src/validate.h:1.1 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/validate.h Fri Nov 19 16:27:28 2004 @@ -24,7 +24,8 @@ /* Validate the certificate CHAIN up to the trust anchor. Optionally return the closest expiration time in R_EXPTIME. */ -gpg_error_t validate_cert_chain (ksba_cert_t cert, ksba_isotime_t r_exptime); +gpg_error_t validate_cert_chain (ctrl_t ctrl, + ksba_cert_t cert, ksba_isotime_t r_exptime); /* Return 0 if the certificate CERT is usable for certification. */ gpg_error_t cert_use_cert_p (ksba_cert_t cert); From cvs at cvs.gnupg.org Tue Nov 23 14:14:07 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Tue Nov 23 16:53:05 2004 Subject: dirmngr (17 files) Message-ID: Date: Tuesday, November 23, 2004 @ 14:20:44 Author: wk Path: /cvs/dirmngr/dirmngr Added: src/b64enc.c Modified: TODO src/ChangeLog src/Makefile.am src/certcache.c src/crlfetch.c src/dirmngr-client.c src/dirmngr_ldap.c src/ldap.c src/misc.c src/misc.h src/no-libgcrypt.c src/no-libgcrypt.h src/ocsp.c src/ocsp.h src/server.c src/util.h * dirmngr-client.c (do_lookup): New. (main): New option --lookup. (data_cb): New. * b64enc.c: New. Taken from GnuPG 1.9. * no-libgcrypt.c (gcry_strdup): Added. * ocsp.c (ocsp_isvalid): New arg CERT and lookup the issuer certificate using the standard methods. * server.c (cmd_lookup): Truncation is now also an indication for error. (cmd_checkocsp): Implemented. * dirmngr_ldap.c (fetch_ldap): Write an error marker for a truncated search. * ldap.c (add_server_to_servers): Reactivated. (url_fetch_ldap): Call it here and try all configured servers in case of a a failed lookup. (fetch_next_cert_ldap): Detect the truncation error flag. * misc.c (host_and_port_from_url, remove_percent_escapes): New. ----------------------+ TODO | 12 -- src/ChangeLog | 24 +++++ src/Makefile.am | 2 src/b64enc.c | 213 +++++++++++++++++++++++++++++++++++++++++++++++++ src/certcache.c | 6 - src/crlfetch.c | 31 ------- src/dirmngr-client.c | 106 ++++++++++++++++++++++-- src/dirmngr_ldap.c | 13 ++ src/ldap.c | 104 ++++++++++++++++++----- src/misc.c | 104 +++++++++++++++++++++++ src/misc.h | 5 - src/no-libgcrypt.c | 6 + src/no-libgcrypt.h | 1 src/ocsp.c | 56 ++++++++---- src/ocsp.h | 3 src/server.c | 49 ++++++++++- src/util.h | 17 +++ 17 files changed, 644 insertions(+), 108 deletions(-) Index: dirmngr/TODO diff -u dirmngr/TODO:1.14 dirmngr/TODO:1.15 --- dirmngr/TODO:1.14 Tue Nov 16 19:24:36 2004 +++ dirmngr/TODO Tue Nov 23 14:20:44 2004 @@ -2,9 +2,6 @@ * Audit the code! -* Dirmngr as system daemon - We need to limit the length of inquires etc. - * Write a useful README * Map LDAP error codes @@ -15,15 +12,6 @@ This is the server where a baseDN has been given and that baseDN is contained in the search pattern. -* Properly parse LDAP attributes from the URL and remove the bad hack in crl_fetch. - -* Add --honor-http-proxy - * Properly use locks in crlcache.c -* truncated - Need to updated the code in ldap.c - -* In daemon mode we should put the cache files into /var/cache/dirmngr - Index: dirmngr/src/ChangeLog diff -u dirmngr/src/ChangeLog:1.25 dirmngr/src/ChangeLog:1.26 --- dirmngr/src/ChangeLog:1.25 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/ChangeLog Tue Nov 23 14:20:44 2004 @@ -1,3 +1,27 @@ +2004-11-23 Werner Koch + + * dirmngr-client.c (do_lookup): New. + (main): New option --lookup. + (data_cb): New. + * b64enc.c: New. Taken from GnuPG 1.9. + * no-libgcrypt.c (gcry_strdup): Added. + + * ocsp.c (ocsp_isvalid): New arg CERT and lookup the issuer + certificate using the standard methods. + + * server.c (cmd_lookup): Truncation is now also an indication for + error. + (cmd_checkocsp): Implemented. + + * dirmngr_ldap.c (fetch_ldap): Write an error marker for a + truncated search. + * ldap.c (add_server_to_servers): Reactivated. + (url_fetch_ldap): Call it here and try all configured servers in + case of a a failed lookup. + (fetch_next_cert_ldap): Detect the truncation error flag. + + * misc.c (host_and_port_from_url, remove_percent_escapes): New. + 2004-11-22 Werner Koch * dirmngr_ldap.c (main): New option --proxy. Index: dirmngr/src/Makefile.am diff -u dirmngr/src/Makefile.am:1.19 dirmngr/src/Makefile.am:1.20 --- dirmngr/src/Makefile.am:1.19 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/Makefile.am Tue Nov 23 14:20:44 2004 @@ -56,7 +56,7 @@ $(LDAP_LIBS) -dirmngr_client_SOURCES = dirmngr-client.c i18n.h util.h maperror.c \ +dirmngr_client_SOURCES = dirmngr-client.c i18n.h util.h b64enc.c maperror.c \ no-libgcrypt.c no-libgcrypt.h dirmngr_client_LDADD = ../jnlib/libjnlib.a $(LIBOBJS) $(LIBASSUAN_LIBS) \ $(GPG_ERROR_LIBS) Index: dirmngr/src/b64enc.c diff -u /dev/null dirmngr/src/b64enc.c:1.1 --- /dev/null Tue Nov 23 14:20:45 2004 +++ dirmngr/src/b64enc.c Tue Nov 23 14:20:44 2004 @@ -0,0 +1,213 @@ +/* b64enc.c - Simple Base64 encoder. + * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include +#include +#include +#include +#include +#include + +#include "i18n.h" +#include "util.h" + +#define B64ENC_DID_HEADER 1 +#define B64ENC_DID_TRAILER 2 +#define B64ENC_NO_LINEFEEDS 16 + + +/* The base-64 character list */ +static unsigned char bintoasc[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; + +/* Prepare for base-64 writing to the stream FP. If TITLE is not NULL + and not an empty string, this string will be used as the title for + the armor lines, with TITLE being an empty string, we don't write + the header lines and furthermore even don't write any linefeeds. + With TITLE beeing NULL, we merely don't write header but make sure + that lines are not too long. Note, that we don't write any output + unless at least one byte get written using b64enc_write. */ +gpg_error_t +b64enc_start (struct b64state *state, FILE *fp, const char *title) +{ + memset (state, 0, sizeof *state); + state->fp = fp; + if (title && !*title) + state->flags |= B64ENC_NO_LINEFEEDS; + else if (title) + { + state->title = xtrystrdup (title); + if (!state->title) + return gpg_error_from_errno (errno); + } + return 0; +} + + +/* Write NBYTES from BUFFER to the Base 64 stream identified by + STATE. With BUFFER and NBYTES being 0, merely do a fflush on the + stream. */ +gpg_error_t +b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) +{ + unsigned char radbuf[4]; + int idx, quad_count; + const unsigned char *p; + FILE *fp = state->fp; + + + if (!nbytes) + { + if (buffer && fflush (fp)) + goto write_error; + return 0; + } + + if (!(state->flags & B64ENC_DID_HEADER)) + { + if (state->title) + { + if ( fputs ("-----BEGIN ", fp) == EOF + || fputs (state->title, fp) == EOF + || fputs ("-----\n", fp) == EOF) + goto write_error; + } + state->flags |= B64ENC_DID_HEADER; + } + + idx = state->idx; + quad_count = state->quad_count; + assert (idx < 4); + memcpy (radbuf, state->radbuf, idx); + + for (p=buffer; nbytes; p++, nbytes--) + { + radbuf[idx++] = *p; + if (idx > 2) + { + char tmp[4]; + + tmp[0] = bintoasc[(*radbuf >> 2) & 077]; + tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077]; + tmp[2] = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077]; + tmp[3] = bintoasc[radbuf[2]&077]; + for (idx=0; idx < 4; idx++) + putc (tmp[idx], fp); + idx = 0; + if (ferror (fp)) + goto write_error; + if (++quad_count >= (64/4)) + { + quad_count = 0; + if (!(state->flags & B64ENC_NO_LINEFEEDS) + && fputs ("\n", fp) == EOF) + goto write_error; + } + } + } + memcpy (state->radbuf, radbuf, idx); + state->idx = idx; + state->quad_count = quad_count; + return 0; + + write_error: + return gpg_error_from_errno (errno); +} + +gpg_error_t +b64enc_finish (struct b64state *state) +{ + gpg_error_t err = 0; + unsigned char radbuf[4]; + int idx, quad_count; + FILE *fp; + + if (!(state->flags & B64ENC_DID_HEADER)) + goto cleanup; + + /* Flush the base64 encoding */ + fp = state->fp; + idx = state->idx; + quad_count = state->quad_count; + assert (idx < 4); + memcpy (radbuf, state->radbuf, idx); + + if (idx) + { + char tmp[4]; + + tmp[0] = bintoasc[(*radbuf>>2)&077]; + if (idx == 1) + { + tmp[1] = bintoasc[((*radbuf << 4) & 060) & 077]; + tmp[2] = '='; + tmp[3] = '='; + } + else + { + tmp[1] = bintoasc[(((*radbuf<<4)&060)|((radbuf[1]>>4)&017))&077]; + tmp[2] = bintoasc[((radbuf[1] << 2) & 074) & 077]; + tmp[3] = '='; + } + for (idx=0; idx < 4; idx++) + putc (tmp[idx], fp); + idx = 0; + if (ferror (fp)) + goto write_error; + + if (++quad_count >= (64/4)) + { + quad_count = 0; + if (!(state->flags & B64ENC_NO_LINEFEEDS) + && fputs ("\n", fp) == EOF) + goto write_error; + } + } + + /* Finish the last line and write the trailer. */ + if (quad_count + && !(state->flags & B64ENC_NO_LINEFEEDS) + && fputs ("\n", fp) == EOF) + goto write_error; + + if (state->title) + { + if ( fputs ("-----END ", fp) == EOF + || fputs (state->title, fp) == EOF + || fputs ("-----\n", fp) == EOF) + goto write_error; + } + + goto cleanup; + + write_error: + err = gpg_error_from_errno (errno); + + cleanup: + if (state->title) + { + xfree (state->title); + state->title = NULL; + } + state->fp = NULL; + return err; +} + Index: dirmngr/src/certcache.c diff -u dirmngr/src/certcache.c:1.5 dirmngr/src/certcache.c:1.6 --- dirmngr/src/certcache.c:1.5 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/certcache.c Tue Nov 23 14:20:44 2004 @@ -709,9 +709,3 @@ return err; } - - - - - - Index: dirmngr/src/crlfetch.c diff -u dirmngr/src/crlfetch.c:1.21 dirmngr/src/crlfetch.c:1.22 --- dirmngr/src/crlfetch.c:1.21 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/crlfetch.c Tue Nov 23 14:20:44 2004 @@ -111,8 +111,6 @@ } else /* Let the LDAP code try other schemes. */ { - const char *s; - if (opt.disable_ldap) { log_error (_("CRL access not possible due to disabled %s\n"), @@ -121,35 +119,6 @@ } else err = url_fetch_ldap (ctrl, url, NULL, 0, reader); - -/* if (err) */ -/* { */ -/* /\* If the function failed we try again using our default */ -/* host. *\/ */ -/* ldap_server_t server; */ -/* char *savehost; */ -/* int saveport; */ - -/* if (DBG_LOOKUP) */ -/* log_debug ("no hostname in URL or query failed; " */ -/* "trying all default hostnames\n"); */ -/* savehost = ludp->lud_host; */ -/* saveport = ludp->lud_port; */ -/* for (server = opt.ldapservers; server; server = server->next) */ -/* { */ -/* ludp->lud_host = server->host; */ -/* ludp->lud_port = server->port; */ -/* err = url_fetch_ldap_internal (ludp, attr, value, valuelen); */ -/* if (!err) */ -/* break; */ -/* } */ -/* ludp->lud_host = savehost; */ -/* ludp->lud_port = saveport; */ -/* if (opt.add_new_ldapservers) */ -/* add_server_to_servers (ludp->lud_host, ludp->lud_port); */ - -/* } */ - } if (free_this) xfree (free_this); Index: dirmngr/src/dirmngr-client.c diff -u dirmngr/src/dirmngr-client.c:1.3 dirmngr/src/dirmngr-client.c:1.4 --- dirmngr/src/dirmngr-client.c:1.3 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/dirmngr-client.c Tue Nov 23 14:20:44 2004 @@ -54,6 +54,7 @@ oPing, oCacheCert, oValidate, + oLookup, oUseDaemon, oDummy }; @@ -68,6 +69,7 @@ { oPing, "ping", 0, N_("check whether a dirmngr is running")}, { oCacheCert,"cache-cert",0, N_("add a certificate to the cache")}, { oValidate, "validate", 0, N_("validate a certificate")}, + { oLookup, "lookup", 0, N_("lookup a certificate")}, {0} }; @@ -105,6 +107,7 @@ const unsigned char *cert, size_t certlen); static gpg_error_t do_validate (assuan_context_t ctx, const unsigned char *cert, size_t certlen); +static gpg_error_t do_lookup (assuan_context_t ctx, const char *pattern); @@ -116,7 +119,7 @@ switch(level) { - case 11: p = "dirmngr-client"; + case 11: p = "dirmngr-client (dirmngr)"; break; case 13: p = VERSION; break; case 14: p = "Copyright (C) 2004 g10 Code GmbH"; break; @@ -126,10 +129,11 @@ break; case 1: case 40: p = - _("Usage: dirmngr-client [options] [certfile] (-h for help)\n"); + _("Usage: dirmngr-client [options] " + "[certfile|pattern] (-h for help)\n"); break; case 41: p = - _("Syntax: dirmngr-client [options] [certfile]\n" + _("Syntax: dirmngr-client [options] [certfile|pattern]\n" "Test an X.509 certificate against a CRL or do an OCSP check\n" "The process returns 0 if the certificate is valid, 1 if it is\n" "not valid and other error codes for general failures\n"); @@ -163,11 +167,11 @@ assuan_context_t ctx; gpg_error_t err; unsigned char *certbuf; - size_t certbuflen; + size_t certbuflen = 0; int cmd_ping = 0; - int use_daemon = 0; int cmd_cache_cert = 0; int cmd_validate = 0; + int cmd_lookup = 0; set_strusage (my_strusage); log_set_prefix ("dirmngr-client", @@ -190,12 +194,12 @@ { case oVerbose: opt.verbose++; break; case oQuiet: opt.quiet++; break; - case oUseDaemon: use_daemon = 1; break; case oOCSP: opt.use_ocsp++; break; case oPing: cmd_ping = 1; break; case oCacheCert: cmd_cache_cert = 1; break; case oValidate: cmd_validate = 1; break; + case oLookup: cmd_lookup = 1; break; default : pargs.err = 2; break; } @@ -205,6 +209,12 @@ if (cmd_ping) err = 0; + else if (cmd_lookup) + { + if (!argc) + usage (1); + err = 0; + } else if (!argc) { err = read_certificate (NULL, &certbuf, &certbuflen); @@ -234,12 +244,27 @@ exit (2); } - ctx = start_dirmngr (cmd_ping || use_daemon); + ctx = start_dirmngr (1); if (!ctx) exit (2); if (cmd_ping) ; + else if (cmd_lookup) + { + int last_err = 0; + + for (; argc; argc--, argv++) + { + err = do_lookup (ctx, *argv); + if (err) + { + log_error (_("lookup failed: %s\n"), gpg_strerror (err)); + last_err = err; + } + } + err = last_err; + } else if (cmd_cache_cert) { err = do_cache (ctx, certbuf, certbuflen); @@ -264,6 +289,8 @@ log_info (_("a dirmngr daemon is up and running\n")); return 0; } + else if (cmd_lookup) + return err? 1:0; else if (cmd_cache_cert) { if (err && gpg_err_code (err) == GPG_ERR_DUP_VALUE ) @@ -314,6 +341,24 @@ return 0; } +/* Print data as retrieved by the lookup function. */ +static assuan_error_t +data_cb (void *opaque, const void *buffer, size_t length) +{ + gpg_error_t err; + struct b64state *state = opaque; + + if (buffer) + { + err = b64enc_write (state, buffer, length); + if (err) + log_error (_("error writing base64 encoding: %s\n"), + gpg_strerror (err)); + } + return 0; +} + + /* Try to connect to the dirmngr via socket or fork it off and work by pipes. Handle the server's initial greeting */ static assuan_context_t @@ -569,3 +614,50 @@ log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay"); return map_assuan_err (ae); } + +static gpg_error_t +do_lookup (assuan_context_t ctx, const char *pattern) +{ + gpg_error_t err; + assuan_error_t ae; + const unsigned char *s; + char *line, *p; + struct b64state state; + + if (opt.verbose) + log_info (_("looking up `%s'\n"), pattern); + + err = b64enc_start (&state, stdout, NULL); + if (err) + return err; + + line = xmalloc (10 + strlen (pattern)*3 + 1); + + p = stpcpy (line, "LOOKUP "); + for (s=pattern; *s; s++) + { + if (*s < ' ' || *s == '+') + { + sprintf (p, "%%%02X", *s); + p += 3; + } + else if (*s == ' ') + *p++ = '+'; + else + *p++ = *s; + } + *p = 0; + + + ae = assuan_transact (ctx, line, + data_cb, &state, + NULL, NULL, + status_cb, NULL); + if (opt.verbose > 1) + log_info ("response of dirmngr: %s\n", ae? assuan_strerror (ae): "okay"); + + err = b64enc_finish (&state); + + xfree (line); + return ae? map_assuan_err (ae) : err; +} Index: dirmngr/src/dirmngr_ldap.c diff -u dirmngr/src/dirmngr_ldap.c:1.3 dirmngr/src/dirmngr_ldap.c:1.4 --- dirmngr/src/dirmngr_ldap.c:1.3 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/dirmngr_ldap.c Tue Nov 23 14:20:44 2004 @@ -125,7 +125,7 @@ switch(level) { - case 11: p = "dirmngr_ldap"; + case 11: p = "dirmngr_ldap (dirmngr)"; break; case 13: p = VERSION; break; case 14: p = "Copyright (C) 2004 g10 Code GmbH"; break; @@ -466,7 +466,16 @@ ludp->lud_attrs:attrs, 0, &opt.timeout, &msg); - if (rc) + if (rc == LDAP_SIZELIMIT_EXCEEDED && opt.multi) + { + if (fwrite ("E\0\0\0\x09truncated", 14, 1, stdout) != 1) + { + log_error (_("error writing to stdout: %s\n"), + strerror (errno)); + return -1; + } + } + else if (rc) { log_error (_("searching `%s' failed: %s\n"), url, ldap_err2string (rc)); Index: dirmngr/src/ldap.c diff -u dirmngr/src/ldap.c:1.36 dirmngr/src/ldap.c:1.37 --- dirmngr/src/ldap.c:1.36 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/ldap.c Tue Nov 23 14:20:44 2004 @@ -58,6 +58,7 @@ ksba_reader_t reader; /* The reader used (shallow copy). */ unsigned char *tmpbuf; /* Helper buffer. */ size_t tmpbufsize; /* Allocated size of tmpbuf. */ + int truncated; /* Flag to indicate a truncated output. */ }; @@ -91,7 +92,7 @@ static struct wrapper_context_s *wrapper_list; -#if 0 + /* Add HOST and PORT to our list of LDAP servers. Fixme: We should better use an extra list of servers. */ static void @@ -101,6 +102,9 @@ ldap_server_t last = NULL; const char *s; + if (!port) + port = 389; + for (server=opt.ldapservers; server; server = server->next) { if (!strcmp (server->host, host) && server->port == port) @@ -116,21 +120,25 @@ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "01234567890.-", *s)) { - log_error (_("invalid char 0x%02x in host name" - " - not added\n"), *s); + log_error (_("invalid char 0x%02x in host name - not added\n"), *s); return; } log_info (_("adding `%s:%d' to the ldap server list\n"), host, port); - server = xcalloc (1, sizeof *s); - server->host = xstrdup (host); - server->port = port; - if (last) - last->next = server; + server = xtrycalloc (1, sizeof *s); + if (!server) + log_error (_("malloc failed: %s\n"), strerror (errno)); else - opt.ldapservers = server; + { + server->host = xstrdup (host); + server->port = port; + if (last) + last->next = server; + else + opt.ldapservers = server; + } } -#endif + /* Release the wrapper context and kill a running wrapper process. */ static void @@ -745,13 +753,46 @@ NULL, NULL, NULL, url, reader); - return err; /* FIXME: This option might be used for DoS attacks. Becuase it will enlarge the list of servers to consult without a limit and all LDAP queries w/o a host are will then try each host in - turn. */ -/* if (opt.add_new_ldapservers) */ -/* add_server_to_servers (ludp->lud_host, ludp->lud_port); */ + turn. */ + if (!err && opt.add_new_ldapservers && !opt.ldap_proxy) + { + if (host) + add_server_to_servers (host, port); + else if (url) + { + char *tmp = host_and_port_from_url (url, &port); + add_server_to_servers (host, port); + xfree (tmp); + } + } + + /* If the lookup failed and we are not only using the proxy, we try + again using our default list of servers. */ + if (err && !(opt.ldap_proxy && opt.only_ldap_proxy)) + { + ldap_server_t server; + + if (DBG_LOOKUP) + log_debug ("no hostname in URL or query failed; " + "trying all default hostnames\n"); + + for (server = opt.ldapservers; err && server; server = server->next) + { + err = run_ldap_wrapper (ctrl, + NULL, + server->host, server->port, + NULL, NULL, + NULL, NULL, NULL, url, + reader); + if (!err) + break; + } + } + + return err; } @@ -766,6 +807,9 @@ gpg_error_t err = gpg_error (GPG_ERR_CONFIGURATION); *reader = NULL; + + /* FIXME; we might want to look at the Base SN to try matching + servers first. */ for (server = opt.ldapservers; server; server = server->next) { err = run_ldap_wrapper (ctrl, @@ -1087,9 +1131,10 @@ } -/* Fetch the next certificate. Return 0 on success, GPG_ERR_EOF - if no (more) certificates are available or any other error - code. */ +/* Fetch the next certificate. Return 0 on success, GPG_ERR_EOF if no + (more) certificates are available or any other error + code. GPG_ERR_TRUNCATED may be returned to indicate tha the result + has been truncated. */ gpg_error_t fetch_next_cert_ldap (cert_fetch_context_t context, unsigned char **value, size_t *valuelen) @@ -1099,7 +1144,6 @@ char *p, *pend; int n; int okay = 0; - int truncated = 0; *value = NULL; *valuelen = 0; @@ -1164,23 +1208,33 @@ okay = 0; } } + else if (*hdr == 'E') + { + p = context->tmpbuf; + p[n] = 0; /*(we allocated one extra byte for this.)*/ + if (!strcmp (p, "truncated")) + { + context->truncated = 1; + log_info (_("ldap_search hit the size limit of" + " the server\n")); + } + } } } - + if (err) { xfree (*value); *value = NULL; *valuelen = 0; + if (gpg_err_code (err) == GPG_ERR_EOF && context->truncated) + { + context->truncated = 0; /* So that the next call would return EOF. */ + err = gpg_error (GPG_ERR_TRUNCATED); + } } return err; - - -/* if (rc == LDAP_SIZELIMIT_EXCEEDED) */ -/* { */ - /* truncated = 1; */ -/* log_info (_("ldap_search hit the size limit of the server\n")); */ } Index: dirmngr/src/misc.c diff -u dirmngr/src/misc.c:1.8 dirmngr/src/misc.c:1.9 --- dirmngr/src/misc.c:1.8 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/misc.c Tue Nov 23 14:20:44 2004 @@ -24,7 +24,9 @@ #include #include #include +#include +#include "util.h" #include "misc.h" #include "dirmngr.h" @@ -569,3 +571,105 @@ } log_debug ("END Certificate\n"); } + + +/**************** + * Remove all %xx escapes; this is done inplace. + * Returns: New length of the string. + */ +static int +remove_percent_escapes (unsigned char *string) +{ + int n = 0; + unsigned char *p, *s; + + for (p = s = string; *s; s++) + { + if (*s == '%') + { + if (s[1] && s[2] && hexdigitp (s+1) && hexdigitp (s+2)) + { + s++; + *p = xtoi_2 (s); + s++; + p++; + n++; + } + else + { + *p++ = *s++; + if (*s) + *p++ = *s++; + if (*s) + *p++ = *s++; + if (*s) + *p = 0; + return -1; /* Bad URI. */ + } + } + else + { + *p++ = *s; + n++; + } + } + *p = 0; /* Always keep a string terminator. */ + return n; +} + + +/* Return the host name and the port (0 if none was given) from the + URL. Return NULL on error or if host is not included in the + URL. */ +char * +host_and_port_from_url (const char *url, int *port) +{ + const char *s, *s2; + char *buf, *p; + int n; + + s = url; + + *port = 0; + + /* Find the scheme */ + if ( !(s2 = strchr (s, ':')) || s2 == s ) + return NULL; /* No scheme given. */ + s = s2+1; + + /* Find the hostname */ + if (*s != '/') + return NULL; /* Does not start with a slash. */ + + s++; + if (*s != '/') + return NULL; /* No host name. */ + s++; + + buf = xtrystrdup (s); + if (!buf) + { + log_error (_("malloc failed: %s\n"), strerror (errno)); + return NULL; + } + if ((p = strchr (buf, '/'))) + *p++ = 0; + strlwr (buf); + if ((p = strchr (p, ':'))) + { + *p++ = 0; + *port = atoi (p); + } + + /* Remove quotes and make sure that no Nul has been encoded. */ + if ((n = remove_percent_escapes (buf)) < 0 + || n != strlen (p) ) + { + log_error (_("bad URL encoding detected\n")); + xfree (buf); + return NULL; + } + + return buf; +} + Index: dirmngr/src/misc.h diff -u dirmngr/src/misc.h:1.8 dirmngr/src/misc.h:1.9 --- dirmngr/src/misc.h:1.8 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/misc.h Tue Nov 23 14:20:44 2004 @@ -100,7 +100,10 @@ TEXT. This is used for debugging. */ void dump_cert (const char *text, ksba_cert_t cert); - +/* Return the host name and the port (0 if none was given) from the + URL. Return NULL on error or if host is not included in the + URL. */ +char *host_and_port_from_url (const char *url, int *port); #ifdef HAVE_FOPENCOOKIE Index: dirmngr/src/no-libgcrypt.c diff -u dirmngr/src/no-libgcrypt.c:1.1 dirmngr/src/no-libgcrypt.c:1.2 --- dirmngr/src/no-libgcrypt.c:1.1 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/no-libgcrypt.c Tue Nov 23 14:20:44 2004 @@ -90,6 +90,12 @@ char * +gcry_strdup (const char *string) +{ + return strdup (string); +} + +char * gcry_xstrdup (const char *string) { void *p = malloc (strlen (string)+1); Index: dirmngr/src/no-libgcrypt.h diff -u dirmngr/src/no-libgcrypt.h:1.1 dirmngr/src/no-libgcrypt.h:1.2 --- dirmngr/src/no-libgcrypt.h:1.1 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/no-libgcrypt.h Tue Nov 23 14:20:44 2004 @@ -27,6 +27,7 @@ void *gcry_xrealloc (void *a, size_t n); void *gcry_calloc (size_t n, size_t m); void *gcry_xcalloc (size_t n, size_t m); +char *gcry_strdup (const char *string); char *gcry_xstrdup (const char *string); void gcry_free (void *a); Index: dirmngr/src/ocsp.c diff -u dirmngr/src/ocsp.c:1.10 dirmngr/src/ocsp.c:1.11 --- dirmngr/src/ocsp.c:1.10 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/ocsp.c Tue Nov 23 14:20:44 2004 @@ -28,6 +28,7 @@ #include "misc.h" #include "http.h" #include "validate.h" +#include "certcache.h" #include "ocsp.h" @@ -386,12 +387,14 @@ } +/* Check whether the certificate either given by fingerprint CERT_FPR + or directly through a the CERT object is valid by running an OCSP + transaction. */ gpg_error_t -ocsp_isvalid (ctrl_t ctrl, const char *cert_fpr) +ocsp_isvalid (ctrl_t ctrl, ksba_cert_t cert, const char *cert_fpr) { gpg_error_t err; ksba_ocsp_t ocsp = NULL; - ksba_cert_t cert = NULL; ksba_cert_t issuer_cert = NULL; ksba_sexp_t sigval = NULL; gcry_sexp_t s_sig = NULL; @@ -407,6 +410,38 @@ ksba_name_t name; const char *default_signer = NULL; + /* Get the certificate. */ + if (cert) + { + ksba_cert_ref (cert); + + err = find_issuing_cert (ctrl, cert, &issuer_cert); + if (err) + { + log_error (_("issuer certificate not found: %s\n"), + gpg_strerror (err)); + goto leave; + } + } + else + { + cert = get_cert_local (ctrl, cert_fpr); + if (!cert) + { + log_error (_("caller did not return the target certificate\n")); + err = gpg_error (GPG_ERR_GENERAL); + goto leave; + } + issuer_cert = get_issuing_cert_local (ctrl, NULL); + if (!issuer_cert) + { + log_error (_("caller did not return the issuing certificate\n")); + err = gpg_error (GPG_ERR_GENERAL); + goto leave; + } + } + + /* Create an OCSP instance. */ err = ksba_ocsp_new (&ocsp); if (err) { @@ -415,22 +450,7 @@ goto leave; } - /* We don't have any caching yet implemented thus we need to get the - certificate right now. */ - cert = get_cert_local (ctrl, cert_fpr); - if (!cert) - { - log_error (_("caller did not return the target certificate\n")); - err = gpg_error (GPG_ERR_GENERAL); - goto leave; - } - issuer_cert = get_issuing_cert_local (ctrl, NULL); - if (!issuer_cert) - { - log_error (_("caller did not return the issuing certificate\n")); - err = gpg_error (GPG_ERR_GENERAL); - goto leave; - } + /* Figure out the OCSP responder to use. 1. Try to get the reponder from the certificate. Index: dirmngr/src/ocsp.h diff -u dirmngr/src/ocsp.h:1.1 dirmngr/src/ocsp.h:1.2 --- dirmngr/src/ocsp.h:1.1 Thu Dec 11 12:25:25 2003 +++ dirmngr/src/ocsp.h Tue Nov 23 14:20:44 2004 @@ -21,7 +21,6 @@ #ifndef OCSP_H #define OCSP_H -gpg_error_t ocsp_isvalid (ctrl_t ctrl, const char *cert_fpr); - +gpg_error_t ocsp_isvalid (ctrl_t ctrl, ksba_cert_t cert, const char *cert_fpr); #endif /*OCSP_H*/ Index: dirmngr/src/server.c diff -u dirmngr/src/server.c:1.46 dirmngr/src/server.c:1.47 --- dirmngr/src/server.c:1.46 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/server.c Tue Nov 23 14:20:44 2004 @@ -313,7 +313,7 @@ if (!opt.allow_ocsp) err = gpg_error (GPG_ERR_NOT_SUPPORTED); else - err = ocsp_isvalid (ctrl, NULL); + err = ocsp_isvalid (ctrl, NULL, NULL); /* Fixme: If we got no ocsp response we should fall back to CRL mode. Thus we need to clear OCSP_MODE, get the issuerhash and the serialno from the current certificate and jump to @@ -497,13 +497,55 @@ static int cmd_checkocsp (assuan_context_t ctx, char *line) { -/* ctrl_t ctrl = assuan_get_pointer (ctx); */ + ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err; + unsigned char fprbuffer[20], *fpr; + ksba_cert_t cert; - err = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + fpr = get_fingerprint_from_line (line, fprbuffer); + cert = fpr? get_cert_byfpr (fpr) : NULL; + + if (!cert) + { + /* We do not have this certificate yet or the fingerprint has + not been given. Inquire it from the client. */ + assuan_error_t ae; + unsigned char *value = NULL; + size_t valuelen; + + ae = assuan_inquire (ctrl->server_local->assuan_ctx, "TARGETCERT", + &value, &valuelen, MAX_CERT_LENGTH); + if (ae) + { + log_error (_("assuan_inquire failed: %s\n"), assuan_strerror (ae)); + err = map_assuan_err (ae); + goto leave; + } + + if (!valuelen) /* No data returned; return a comprehensible error. */ + err = gpg_error (GPG_ERR_MISSING_CERT); + else + { + err = ksba_cert_new (&cert); + if (!err) + err = ksba_cert_init_from_mem (cert, value, valuelen); + } + xfree (value); + if(err) + goto leave; + } + + assert (cert); + + if (!opt.allow_ocsp) + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + else + err = ocsp_isvalid (ctrl, cert, NULL); + leave: if (err) log_error (_("command %s failed: %s\n"), "CHECKOCSP", gpg_strerror (err)); + ksba_cert_release (cert); return map_to_assuan_status (err); } @@ -583,6 +625,7 @@ { truncated = 1; err = 0; + break; /* Ready. */ } if (gpg_err_code (err) == GPG_ERR_EOF) { Index: dirmngr/src/util.h diff -u dirmngr/src/util.h:1.1 dirmngr/src/util.h:1.2 --- dirmngr/src/util.h:1.1 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/util.h Tue Nov 23 14:20:44 2004 @@ -23,6 +23,23 @@ #include +/*-- b64enc.c --*/ +struct b64state +{ + unsigned int flags; + int idx; + int quad_count; + FILE *fp; + char *title; + unsigned char radbuf[4]; +}; +gpg_error_t b64enc_start (struct b64state *state, FILE *fp, const char *title); +gpg_error_t b64enc_write (struct b64state *state, + const void *buffer, size_t nbytes); +gpg_error_t b64enc_finish (struct b64state *state); + + + /*-- maperror.c --*/ gpg_error_t map_assuan_err (int err); From cvs at cvs.gnupg.org Tue Nov 23 18:03:12 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Tue Nov 23 18:03:16 2004 Subject: GNUPG-1-9-BRANCH gnupg (16 files) Message-ID: Date: Tuesday, November 23, 2004 @ 18:09:52 Author: wk Path: /cvs/gnupg/gnupg Tag: GNUPG-1-9-BRANCH Modified: TODO common/ChangeLog common/b64enc.c doc/ChangeLog doc/debugging.texi doc/gpg-agent.texi doc/gpgsm.texi jnlib/ChangeLog jnlib/logging.c sm/ChangeLog sm/call-dirmngr.c sm/gpgsm.c sm/gpgsm.h tools/ChangeLog tools/gpgconf-comp.c tools/watchgnupg.c * b64enc.c: Include stdio.h and string.h * gpgsm.c: New option --prefer-system-dirmngr. * call-dirmngr.c (start_dirmngr): Implement this option. * gpgconf-comp.c : Add the proxy options. : Add --prefer-system-daemon. ----------------------+ TODO | 11 +--------- common/ChangeLog | 4 +++ common/b64enc.c | 2 + doc/ChangeLog | 4 +++ doc/debugging.texi | 23 ++++++++++++++++++---- doc/gpg-agent.texi | 2 - doc/gpgsm.texi | 6 +++++ jnlib/ChangeLog | 9 ++++++++ jnlib/logging.c | 10 ++++++--- sm/ChangeLog | 5 ++++ sm/call-dirmngr.c | 50 +++++++++++++++++++++++++++++++------------------ sm/gpgsm.c | 7 +++++- sm/gpgsm.h | 1 tools/ChangeLog | 9 ++++++++ tools/gpgconf-comp.c | 24 ++++++++++++++++++++++- tools/watchgnupg.c | 2 - 16 files changed, 131 insertions(+), 38 deletions(-) Index: gnupg/TODO diff -u gnupg/TODO:1.165.2.32 gnupg/TODO:1.165.2.33 --- gnupg/TODO:1.165.2.32 Fri Oct 22 14:31:26 2004 +++ gnupg/TODO Tue Nov 23 18:09:51 2004 @@ -25,6 +25,8 @@ * sm/certlist.c ** ocspSigning usage is not fully implemented We should review the entire CRL and OCSP validation system. + Okay. This has been fixed in dirmngr when running it in system + daemon mode. * sm/decrypt.c ** replace leading zero in integer hack by a cleaner solution @@ -93,12 +95,3 @@ This needs support in libksba/src/cert.c as well as in sm/*.c. Need test certs as well. Same goes for CRL authorityKeyIdentifier. -** Dirmngr: name subordination (nameRelativeToCRLIssuer) - is not yet supported by Dirmngr. - -** Dirmngr: CRL DP URI - The CRL DP shall use an URI for LDAP without a host name. The host - name shall be looked by using the DN in the URI. We don't implement - this yet. Solution is to have a mapping DN->host in our ldapservers - configuration file. - Index: gnupg/common/ChangeLog diff -u gnupg/common/ChangeLog:1.30.2.28 gnupg/common/ChangeLog:1.30.2.29 --- gnupg/common/ChangeLog:1.30.2.28 Wed Aug 18 16:37:22 2004 +++ gnupg/common/ChangeLog Tue Nov 23 18:09:51 2004 @@ -1,3 +1,7 @@ +2004-11-23 Werner Koch + + * b64enc.c: Include stdio.h and string.h + 2004-08-18 Werner Koch * simple-pwquery.c (simple_pwquery): Handle gpg-error style return Index: gnupg/common/b64enc.c diff -u gnupg/common/b64enc.c:1.1.2.1 gnupg/common/b64enc.c:1.1.2.2 --- gnupg/common/b64enc.c:1.1.2.1 Tue Feb 10 20:27:54 2004 +++ gnupg/common/b64enc.c Tue Nov 23 18:09:51 2004 @@ -19,7 +19,9 @@ */ #include +#include #include +#include #include #include Index: gnupg/doc/ChangeLog diff -u gnupg/doc/ChangeLog:1.39.2.18 gnupg/doc/ChangeLog:1.39.2.19 --- gnupg/doc/ChangeLog:1.39.2.18 Fri Oct 22 14:30:34 2004 +++ gnupg/doc/ChangeLog Tue Nov 23 18:09:51 2004 @@ -1,3 +1,7 @@ +2004-11-05 Werner Koch + + * debugging.texi (Common Problems): Curses pinentry problem. + 2004-10-22 Werner Koch * tools.texi (Helper Tools): Document gpgsm-gencert.sh. Index: gnupg/doc/debugging.texi diff -u gnupg/doc/debugging.texi:1.1.2.2 gnupg/doc/debugging.texi:1.1.2.3 --- gnupg/doc/debugging.texi:1.1.2.2 Mon Jun 28 09:42:32 2004 +++ gnupg/doc/debugging.texi Tue Nov 23 18:09:51 2004 @@ -5,7 +5,7 @@ @node Debugging @chapter How to solve problems -Everone knows that software often does not do what it should do and thus +Everyone knows that software often does not do what it should do and thus there is a need to track down problems. We call this debugging in a reminiscent to the moth jamming a relay in a Mark II box back in 1947. @@ -87,9 +87,24 @@ @itemize @bullet @item Error code @samp{Not supported} from Dirmngr - Most likely the option @option{enable-ocsp} is active for gpgsm - but Dirmngr's OCSP feature has not been enabled using - @option{allow-ocsp} in @file{dirmngr.conf}. +Most likely the option @option{enable-ocsp} is active for gpgsm +but Dirmngr's OCSP feature has not been enabled using +@option{allow-ocsp} in @file{dirmngr.conf}. + +@item The Curses based Pinentry does not work + +The far most common reason for this is that the environment variable +@code{GPG_TTY} has not been set correctly. Make sure that it has been +set to a real tty devce and not just to @samp{/dev/tty}; +i.e. @samp{GPG_TTY=tty} is plainly wrong; what you want is +@samp{GPG_TTY=`tty`} --- note the back ticks. Also make sure that +this environment variable gets exported, that is you should follow up +the setting with an @samp{export GPG_TTY} (assuming a Bourne style +shell). Even for GUI based Pinentries; you should have set +@code{GPG_TTY}. See the section on installing the @program{gpg-agent} +on how to do it. + + @end itemize Index: gnupg/doc/gpg-agent.texi diff -u gnupg/doc/gpg-agent.texi:1.1.2.11 gnupg/doc/gpg-agent.texi:1.1.2.12 --- gnupg/doc/gpg-agent.texi:1.1.2.11 Wed Oct 20 10:54:45 2004 +++ gnupg/doc/gpg-agent.texi Tue Nov 23 18:09:51 2004 @@ -43,7 +43,7 @@ @end smallexample @noindent -You should aleays add the following lines to your @code{.bashrc} or +You should aleways add the following lines to your @code{.bashrc} or whatever initialization file is used for all shell invocations: @smallexample Index: gnupg/doc/gpgsm.texi diff -u gnupg/doc/gpgsm.texi:1.1.2.17 gnupg/doc/gpgsm.texi:1.1.2.18 --- gnupg/doc/gpgsm.texi:1.1.2.17 Thu Sep 30 10:38:32 2004 +++ gnupg/doc/gpgsm.texi Tue Nov 23 18:09:51 2004 @@ -262,6 +262,12 @@ fallback when the environment variable @code{DIRMNGR_INFO} is not set or a running dirmngr can't be connected. +@item --prefer-system-dirmngr +@opindex prefer-system-dirmngr +If a system wide @command{dirmngr} is running in daemon mode, first try +to connect to this one. Fallback to a pipe based server if this does +not work. + @item --no-secmem-warning @opindex no-secmem-warning Don't print a warning when the so called "secure memory" can't be used. Index: gnupg/jnlib/ChangeLog diff -u gnupg/jnlib/ChangeLog:1.3.2.16 gnupg/jnlib/ChangeLog:1.3.2.17 --- gnupg/jnlib/ChangeLog:1.3.2.16 Fri Oct 22 11:41:24 2004 +++ gnupg/jnlib/ChangeLog Tue Nov 23 18:09:51 2004 @@ -1,3 +1,12 @@ +2004-11-22 Werner Koch + + * logging.c (log_test_fd): Add test on LOGSTREAM. Reported by + Barry Schwartz. + +2004-11-18 Werner Koch + + * logging.c: Explicitly include sys/stat.h for the S_I* constants. + 2004-10-21 Werner Koch * logging.c (do_logv): Use set_log_stream to setup a default. Index: gnupg/jnlib/logging.c diff -u gnupg/jnlib/logging.c:1.2.2.9 gnupg/jnlib/logging.c:1.2.2.10 --- gnupg/jnlib/logging.c:1.2.2.9 Fri Oct 22 11:41:24 2004 +++ gnupg/jnlib/logging.c Tue Nov 23 18:09:51 2004 @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -411,9 +412,12 @@ int log_test_fd (int fd) { - int tmp = fileno (logstream); - if ( tmp != -1 && tmp == fd) - return 1; + if (logstream) + { + int tmp = fileno (logstream); + if ( tmp != -1 && tmp == fd) + return 1; + } if (log_socket != -1 && log_socket == fd) return 1; return 0; Index: gnupg/sm/ChangeLog diff -u gnupg/sm/ChangeLog:1.101.2.73 gnupg/sm/ChangeLog:1.101.2.74 --- gnupg/sm/ChangeLog:1.101.2.73 Fri Oct 22 14:30:52 2004 +++ gnupg/sm/ChangeLog Tue Nov 23 18:09:51 2004 @@ -1,3 +1,8 @@ +2004-11-23 Werner Koch + + * gpgsm.c: New option --prefer-system-dirmngr. + * call-dirmngr.c (start_dirmngr): Implement this option. + 2004-10-22 Werner Koch * certreqgen.c (gpgsm_genkey): Remove the NEW from the certificate Index: gnupg/sm/call-dirmngr.c diff -u gnupg/sm/call-dirmngr.c:1.16.2.8 gnupg/sm/call-dirmngr.c:1.16.2.9 --- gnupg/sm/call-dirmngr.c:1.16.2.8 Wed Aug 18 16:38:46 2004 +++ gnupg/sm/call-dirmngr.c Tue Nov 23 18:09:51 2004 @@ -35,6 +35,8 @@ #include "i18n.h" #include "keydb.h" +/* The name of the socket for a system daemon. */ +#define DEFAULT_SOCKET_NAME "/var/run/dirmngr/socket" struct membuf { size_t len; @@ -145,6 +147,7 @@ int rc; char *infostr, *p; ASSUAN_CONTEXT ctx; + int try_default = 0; if (dirmngr_ctx) return 0; /* fixme: We need a context for each thread or serialize @@ -153,6 +156,12 @@ to take care of the implicit option sending caching. */ infostr = force_pipe_server? NULL : getenv ("DIRMNGR_INFO"); + if (opt.prefer_system_dirmngr && !force_pipe_server + &&(!infostr || !*infostr)) + { + infostr = DEFAULT_SOCKET_NAME; + try_default = 1; + } if (!infostr || !*infostr) { const char *pgmname; @@ -197,26 +206,31 @@ int pid; infostr = xstrdup (infostr); - if ( !(p = strchr (infostr, ':')) || p == infostr) + if (!try_default && *infostr) { - log_error (_("malformed DIRMNGR_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_dirmngr (); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != ':') - 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 (); + if ( !(p = strchr (infostr, ':')) || p == infostr) + { + log_error (_("malformed DIRMNGR_INFO environment variable\n")); + xfree (infostr); + force_pipe_server = 1; + return start_dirmngr (); + } + *p++ = 0; + pid = atoi (p); + while (*p && *p != ':') + 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 (); + } } + else + pid = -1; rc = assuan_socket_connect (&ctx, infostr, pid); xfree (infostr); Index: gnupg/sm/gpgsm.c diff -u gnupg/sm/gpgsm.c:1.67.2.30 gnupg/sm/gpgsm.c:1.67.2.31 --- gnupg/sm/gpgsm.c:1.67.2.30 Fri Oct 1 14:53:08 2004 +++ gnupg/sm/gpgsm.c Tue Nov 23 18:09:51 2004 @@ -107,6 +107,7 @@ oLCctype, oLCmessages, + oPreferSystemDirmngr, oDirmngrProgram, oProtectToolProgram, oFakedSystemTime, @@ -272,7 +273,8 @@ { oRecipient, "recipient", 2, N_("|NAME|encrypt for NAME")}, - + { oPreferSystemDirmngr,"prefer-system-dirmngr", 0, + N_("use system's dirmngr if available")}, { oDisableCRLChecks, "disable-crl-checks", 0, N_("never consult a CRL")}, { oEnableCRLChecks, "enable-crl-checks", 0, "@"}, { oForceCRLRefresh, "force-crl-refresh", 0, "@"}, @@ -1047,6 +1049,7 @@ case oLCctype: opt.lc_ctype = xstrdup (pargs.r.ret_str); break; case oLCmessages: opt.lc_messages = xstrdup (pargs.r.ret_str); break; case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break; + case oPreferSystemDirmngr: opt.prefer_system_dirmngr = 1; break; case oProtectToolProgram: opt.protect_tool_program = pargs.r.ret_str; break; @@ -1333,6 +1336,8 @@ GC_OPT_FLAG_NONE ); printf ("auto-issuer-key-retrieve:%lu:\n", GC_OPT_FLAG_NONE ); + printf ("prefer-system-dirmngr:%lu:\n", + GC_OPT_FLAG_NONE ); } break; Index: gnupg/sm/gpgsm.h diff -u gnupg/sm/gpgsm.h:1.54.2.21 gnupg/sm/gpgsm.h:1.54.2.22 --- gnupg/sm/gpgsm.h:1.54.2.21 Thu Sep 30 23:37:06 2004 +++ gnupg/sm/gpgsm.h Tue Nov 23 18:09:51 2004 @@ -55,6 +55,7 @@ char *lc_messages; const char *dirmngr_program; + int prefer_system_dirmngr; /* Prefer using a system wide drimngr. */ const char *protect_tool_program; char *outfile; /* name of output file */ Index: gnupg/tools/ChangeLog diff -u gnupg/tools/ChangeLog:1.25.2.55 gnupg/tools/ChangeLog:1.25.2.56 --- gnupg/tools/ChangeLog:1.25.2.55 Fri Oct 22 14:31:04 2004 +++ gnupg/tools/ChangeLog Tue Nov 23 18:09:51 2004 @@ -1,3 +1,12 @@ +2004-11-23 Werner Koch + + * gpgconf-comp.c : Add the proxy options. + : Add --prefer-system-daemon. + +2004-11-11 Werner Koch + + * watchgnupg.c (main): Fixed test for read error. + 2004-10-22 Werner Koch * Makefile.am (bin_SCRIPTS): Add gpgsm-gencert.sh Index: gnupg/tools/gpgconf-comp.c diff -u gnupg/tools/gpgconf-comp.c:1.1.2.43 gnupg/tools/gpgconf-comp.c:1.1.2.44 --- gnupg/tools/gpgconf-comp.c:1.1.2.43 Fri Oct 1 18:51:18 2004 +++ gnupg/tools/gpgconf-comp.c Tue Nov 23 18:09:51 2004 @@ -628,6 +628,9 @@ { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "gnupg", "|FILE|read options from FILE", GC_ARG_TYPE_PATHNAME, GC_BACKEND_GPGSM }, + { "prefer-system-dirmngr", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "gnupg", "use system's dirmngr if available", + GC_ARG_TYPE_NONE, GC_BACKEND_GPGSM }, { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, @@ -731,10 +734,29 @@ "dirmngr", "force loading of outdated CRLs", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "HTTP", + GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, + "gnupg", N_("Configuration for HTTP servers") }, + { "disable-http", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "inhibit the use of HTTP", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "|URL|redirect all HTTP requests to URL", + GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, + { "LDAP", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, "gnupg", N_("Configuration of LDAP servers to use") }, - { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + { "disable-ldap", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "inhibit the use of LDAP", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + "dirmngr", "|HOST|use HOST for LDAP queries", + GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, + { "only-ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "do not use fallback hosts with --ldap-proxy", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "add-servers", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "add new servers discovered in CRL distribution points" " to serverlist", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "ldaptimeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, Index: gnupg/tools/watchgnupg.c diff -u gnupg/tools/watchgnupg.c:1.1.2.5 gnupg/tools/watchgnupg.c:1.1.2.6 --- gnupg/tools/watchgnupg.c:1.1.2.5 Thu Feb 12 11:02:22 2004 +++ gnupg/tools/watchgnupg.c Tue Nov 23 18:09:51 2004 @@ -354,7 +354,7 @@ int n; n = read (client->fd, line, sizeof line - 1); - if (n == 1) + if (n < 0) { int save_errno = errno; print_line (client, NULL); /* flush */ From cvs at cvs.gnupg.org Wed Nov 24 06:18:23 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Wed Nov 24 06:18:30 2004 Subject: gnupg/g10 (ChangeLog gpgv.c keyedit.c keylist.c trustdb.c trustdb.h) Message-ID: Date: Wednesday, November 24, 2004 @ 06:25:03 Author: dshaw Path: /cvs/gnupg/gnupg/g10 Modified: ChangeLog gpgv.c keyedit.c keylist.c trustdb.c trustdb.h * trustdb.h, trustdb.c (uid_trust_string_fixed): New. Return a fixed-size translatable string similar to trust_value_to_string. This allows for easier lining up of displays. * keyedit.c (show_key_with_all_names), keylist.c (list_keyblock_print): Use it here to print validity strings. * gpgv.c: Stub. -----------+ ChangeLog | 11 +++++++++++ gpgv.c | 7 ++++++- keyedit.c | 21 ++++++--------------- keylist.c | 14 ++++---------- trustdb.c | 28 ++++++++++++++++++++++++++++ trustdb.h | 6 +++--- 6 files changed, 58 insertions(+), 29 deletions(-) Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.640 gnupg/g10/ChangeLog:1.641 --- gnupg/g10/ChangeLog:1.640 Thu Nov 18 17:01:08 2004 +++ gnupg/g10/ChangeLog Wed Nov 24 06:25:02 2004 @@ -1,3 +1,14 @@ +2004-11-24 David Shaw + + * trustdb.h, trustdb.c (uid_trust_string_fixed): New. Return a + fixed-size translatable string similar to trust_value_to_string. + This allows for easier lining up of displays. + + * keyedit.c (show_key_with_all_names), keylist.c + (list_keyblock_print): Use it here to print validity strings. + + * gpgv.c: Stub. + 2004-11-18 Werner Koch * g10.c (S_IRGRP) [HAVE_DOSISH_SYSTEM]: Define to 0. Index: gnupg/g10/gpgv.c diff -u gnupg/g10/gpgv.c:1.24 gnupg/g10/gpgv.c:1.25 --- gnupg/g10/gpgv.c:1.24 Fri Oct 1 12:18:30 2004 +++ gnupg/g10/gpgv.c Wed Nov 24 06:25:03 2004 @@ -251,7 +251,12 @@ return "err"; } -/* Stub: */ +const char * +uid_trust_string_fixed(PKT_public_key *key,PKT_user_id *uid) +{ + return "err"; +} + int get_ownertrust_info (PKT_public_key *pk) { Index: gnupg/g10/keyedit.c diff -u gnupg/g10/keyedit.c:1.156 gnupg/g10/keyedit.c:1.157 --- gnupg/g10/keyedit.c:1.156 Fri Oct 29 00:09:09 2004 +++ gnupg/g10/keyedit.c Wed Nov 24 06:25:03 2004 @@ -892,7 +892,7 @@ while(class==0) { answer = cpr_get("sign_uid.class",_("Your selection? " - "(enter '?' for more information): ")); + "(enter `?' for more information): ")); if(answer[0]=='\0') class=0x10+opt.def_cert_level; /* Default */ else if(ascii_strcasecmp(answer,"0")==0) @@ -2360,16 +2360,7 @@ if( !only_marked || (only_marked && (node->flag & NODFLG_MARK_A))) { if(!only_marked) - { - if(uid->is_revoked) - tty_printf(_("[%8.8s] "),_("revoked")); - else if(uid->is_expired) - tty_printf(_("[%8.8s] "),_("expired")); - else if(primary) - tty_printf(_("[%8.8s] "), - trust_value_to_string(get_validity(primary, - uid))); - } + tty_printf("%s ",uid_trust_string_fixed(primary,uid)); if( only_marked ) tty_printf(" "); @@ -2403,16 +2394,16 @@ show_prefs (uid, selfsig, with_prefs == 2); } else - tty_printf(_("There are no preferences on a " - "PGP 2.x-style user ID.\n")); + tty_printf(_("There are no preferences on a" + " PGP 2.x-style user ID.\n")); } } } } if (do_warn) - tty_printf (_("Please note that the shown key validity " - "is not necessarily correct\n" + tty_printf (_("Please note that the shown key validity" + " is not necessarily correct\n" "unless you restart the program.\n")); } Index: gnupg/g10/keylist.c diff -u gnupg/g10/keylist.c:1.89 gnupg/g10/keylist.c:1.90 --- gnupg/g10/keylist.c:1.89 Thu Oct 28 05:14:55 2004 +++ gnupg/g10/keylist.c Wed Nov 24 06:25:03 2004 @@ -778,19 +778,13 @@ const char *validity; int indent; - if(uid->is_revoked) - validity=_("revoked"); - else if(uid->is_expired) - validity=_("expired"); - else - validity=trust_value_to_string(get_validity(pk,uid)); + validity=uid_trust_string_fixed(pk,uid); + indent=(keystrlen()+9)-atoi(uid_trust_string_fixed(NULL,NULL)); - indent=(keystrlen()+7)-strlen(validity); - - if(indent<0) + if(indent<0 || indent>40) indent=0; - printf("uid%*s[%s] ",indent,"",validity); + printf("uid%*s%s ",indent,"",validity); } else printf("uid%*s",keystrlen()+10,""); Index: gnupg/g10/trustdb.c diff -u gnupg/g10/trustdb.c:1.131 gnupg/g10/trustdb.c:1.132 --- gnupg/g10/trustdb.c:1.131 Wed Oct 13 17:34:52 2004 +++ gnupg/g10/trustdb.c Wed Nov 24 06:25:03 2004 @@ -489,6 +489,34 @@ } } +/* NOTE TO TRANSLATOR: these strings are similar to those in + trust_value_to_string(), but are a fixed length. This is needed to + make attractive information listings where columns line up + properly. The value "10" should be the length of the strings you + choose to translate to. This is the length in printable + columns. */ +const char * +uid_trust_string_fixed(PKT_public_key *key,PKT_user_id *uid) +{ + if(!key && !uid) + return _("10"); + else if(uid->is_revoked) + return _("[ revoked]"); + else if(uid->is_expired) + return _("[ expired]"); + else if(key) + switch(get_validity(key,uid)&TRUST_MASK) + { + case TRUST_UNKNOWN: return _("[ unknown]"); + case TRUST_UNDEFINED: return _("[ undef ]"); + case TRUST_MARGINAL: return _("[marginal]"); + case TRUST_FULLY: return _("[ full ]"); + case TRUST_ULTIMATE: return _("[ultimate]"); + } + + return "err"; +} + /* The strings here are similar to those in pkclist.c:do_edit_ownertrust() */ const char * Index: gnupg/g10/trustdb.h diff -u gnupg/g10/trustdb.h:1.48 gnupg/g10/trustdb.h:1.49 --- gnupg/g10/trustdb.h:1.48 Sat Nov 1 02:13:16 2003 +++ gnupg/g10/trustdb.h Wed Nov 24 06:25:03 2004 @@ -1,6 +1,6 @@ /* trustdb.h - Trust database - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 - * Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, + * 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -22,7 +22,6 @@ #ifndef G10_TRUSTDB_H #define G10_TRUSTDB_H - /* Trust values must be sorted in ascending order */ #define TRUST_MASK 15 #define TRUST_UNKNOWN 0 /* o: not yet calculated/assigned */ @@ -48,6 +47,7 @@ void check_trustdb_stale(void); void sync_trustdb( void ); +const char *uid_trust_string_fixed(PKT_public_key *key,PKT_user_id *uid); const char *trust_value_to_string (unsigned int value); int string_to_trust_value (const char *str); From cvs at cvs.gnupg.org Wed Nov 24 08:30:08 2004 From: cvs at cvs.gnupg.org (cvs user twoaday) Date: Wed Nov 24 08:30:29 2004 Subject: libassuan/src (18 files) Message-ID: Date: Wednesday, November 24, 2004 @ 08:30:08 Author: twoaday Path: /cvs/gnupg/libassuan/src Added: assuan-socket.c stpcpy.c Modified: ChangeLog Makefile.am assuan-buffer.c assuan-client.c assuan-connect.c assuan-defs.h assuan-domain-connect.c assuan-domain-server.c assuan-handler.c assuan-inquire.c assuan-io.c assuan-listen.c assuan-pipe-connect.c assuan-socket-connect.c assuan-socket-server.c assuan-util.c 2004-11-23 Timo Schulz * assuan-socket.c (_assuan_sock_connect): Get local port from the sun_path[] file. (_assuan_sock_bind): Write local port to the sun_path[] file. * assuan-socket-connect.c (assuan_socket_connect): Use DIRSEP_C for a better portability. (assuan-defs.h): Define DIRSEP_C. 2004-11-22 Timo Schulz * assuan-io.c (_assuan_simple_read, _assuan_simple_write): W32 support. * assuan-socket.c (_assuan_close): New. (_assuan_sock_new): New. (_assuan_sock_bind): New. -------------------------+ ChangeLog | 17 +++++ Makefile.am | 3 - assuan-buffer.c | 21 ++++--- assuan-client.c | 12 ++-- assuan-connect.c | 7 +- assuan-defs.h | 48 ++++++++++++++-- assuan-domain-connect.c | 75 +++++++++++++++++-------- assuan-domain-server.c | 4 - assuan-handler.c | 4 - assuan-inquire.c | 4 - assuan-io.c | 23 ++++++- assuan-listen.c | 24 ++++---- assuan-pipe-connect.c | 25 +++++--- assuan-socket-connect.c | 28 ++++++--- assuan-socket-server.c | 24 ++++---- assuan-socket.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++ assuan-util.c | 12 ++-- stpcpy.c | 33 +++++++++++ 18 files changed, 391 insertions(+), 106 deletions(-) From cvs at cvs.gnupg.org Wed Nov 24 11:37:08 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Wed Nov 24 11:37:11 2004 Subject: GNUPG-1-9-BRANCH gnupg/tools (ChangeLog gpgconf-comp.c) Message-ID: Date: Wednesday, November 24, 2004 @ 11:43:53 Author: wk Path: /cvs/gnupg/gnupg/tools Tag: GNUPG-1-9-BRANCH Modified: ChangeLog gpgconf-comp.c Add --ignore-http-dp and --ignore-ldap-dp. ----------------+ ChangeLog | 5 +++++ gpgconf-comp.c | 6 ++++++ 2 files changed, 11 insertions(+) Index: gnupg/tools/ChangeLog diff -u gnupg/tools/ChangeLog:1.25.2.56 gnupg/tools/ChangeLog:1.25.2.57 --- gnupg/tools/ChangeLog:1.25.2.56 Tue Nov 23 18:09:51 2004 +++ gnupg/tools/ChangeLog Wed Nov 24 11:43:53 2004 @@ -1,3 +1,8 @@ +2004-11-24 Werner Koch + + * gpgconf-comp.c : Add --ignore-http-dp and + --ignore-ldap-dp. + 2004-11-23 Werner Koch * gpgconf-comp.c : Add the proxy options. Index: gnupg/tools/gpgconf-comp.c diff -u gnupg/tools/gpgconf-comp.c:1.1.2.44 gnupg/tools/gpgconf-comp.c:1.1.2.45 --- gnupg/tools/gpgconf-comp.c:1.1.2.44 Tue Nov 23 18:09:51 2004 +++ gnupg/tools/gpgconf-comp.c Wed Nov 24 11:43:53 2004 @@ -740,6 +740,9 @@ { "disable-http", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "inhibit the use of HTTP", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "ignore-http-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "ignore HTTP CRL distribution points", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "http-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "|URL|redirect all HTTP requests to URL", GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, @@ -750,6 +753,9 @@ { "disable-ldap", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "inhibit the use of LDAP", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "ignore-ldap-dp", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "ignore LDAP CRL distribution points", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "ldap-proxy", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "dirmngr", "|HOST|use HOST for LDAP queries", GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, From cvs at cvs.gnupg.org Wed Nov 24 15:37:15 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Wed Nov 24 15:37:19 2004 Subject: dirmngr (6 files) Message-ID: Date: Wednesday, November 24, 2004 @ 15:44:01 Author: wk Path: /cvs/dirmngr/dirmngr Modified: po/de.po po/dirmngr.pot src/ChangeLog src/dirmngr.c src/dirmngr.h src/ocsp.c Add option --ignore-ocsp-service-url ----------------+ po/de.po | 158 ++++++++++++++++++++++++++++--------------------------- po/dirmngr.pot | 156 +++++++++++++++++++++++++++--------------------------- src/ChangeLog | 4 + src/dirmngr.c | 9 ++- src/dirmngr.h | 2 src/ocsp.c | 2 6 files changed, 174 insertions(+), 157 deletions(-) Index: dirmngr/po/de.po diff -u dirmngr/po/de.po:1.7 dirmngr/po/de.po:1.8 --- dirmngr/po/de.po:1.7 Wed Nov 24 13:25:53 2004 +++ dirmngr/po/de.po Wed Nov 24 15:44:01 2004 @@ -7,8 +7,8 @@ msgstr "" "Project-Id-Version: dirmngr 0.9.0\n" "Report-Msgid-Bugs-To: gpa-dev@gnupg.org\n" -"POT-Creation-Date: 2004-11-24 13:16+0100\n" -"PO-Revision-Date: 2004-11-24 13:16+0100\n" +"POT-Creation-Date: 2004-11-24 15:35+0100\n" +"PO-Revision-Date: 2004-11-24 15:37+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: de\n" "MIME-Version: 1.0\n" @@ -205,7 +205,7 @@ msgid "unsupported record type in `%s' line %u skipped\n" msgstr "Nicht unterstützter Datensatztyp in `%s', Zeile %u übergangen\n" -#: src/crlcache.c:574 src/crlcache.c:803 src/dirmngr.c:1191 +#: src/crlcache.c:574 src/crlcache.c:803 src/dirmngr.c:1196 #, c-format msgid "error reading `%s': %s\n" msgstr "Fehler beim Lesen von `%s': %s\n" @@ -627,7 +627,7 @@ msgid "Certificate search not possible due to disabled %s\n" msgstr "Zertifikatsuche ist nicht möglich da %s abgeschaltet ist\n" -#: src/dirmngr.c:105 +#: src/dirmngr.c:106 msgid "" "@Commands:\n" " " @@ -635,35 +635,35 @@ "@Kommandos:\n" " " -#: src/dirmngr.c:107 +#: src/dirmngr.c:108 msgid "run in server mode (foreground)" msgstr "Im Servermodus ausführen (Vordergrund)" -#: src/dirmngr.c:108 +#: src/dirmngr.c:109 msgid "run in daemon mode (background)" msgstr "Im Daemonmodus ausführen (Hintergrund)" -#: src/dirmngr.c:109 +#: src/dirmngr.c:110 msgid "list the contents of the CRL cache" msgstr "Den Inhalt des CRL Caches anzeigen" -#: src/dirmngr.c:110 +#: src/dirmngr.c:111 msgid "|FILE|load CRL from FILE into cache" msgstr "|DATEI|Lade die CRL aus der DATEI in den Cache" -#: src/dirmngr.c:111 +#: src/dirmngr.c:112 msgid "|URL|fetch a CRL from URL" msgstr "|URL|Hole eine CRL von dieser URL" -#: src/dirmngr.c:112 +#: src/dirmngr.c:113 msgid "shutdown the dirmngr" msgstr "Den Dirmngr herunterfahren" -#: src/dirmngr.c:113 +#: src/dirmngr.c:114 msgid "flush the cache" msgstr "Den Cache löschen" -#: src/dirmngr.c:116 +#: src/dirmngr.c:117 msgid "" "@\n" "Options:\n" @@ -673,115 +673,119 @@ "Optionen:\n" " " -#: src/dirmngr.c:118 src/dirmngr-client.c:64 src/dirmngr_ldap.c:73 +#: src/dirmngr.c:119 src/dirmngr-client.c:64 src/dirmngr_ldap.c:73 msgid "verbose" msgstr "ausführlich" -#: src/dirmngr.c:119 src/dirmngr-client.c:65 src/dirmngr_ldap.c:74 +#: src/dirmngr.c:120 src/dirmngr-client.c:65 src/dirmngr_ldap.c:74 msgid "be somewhat more quiet" msgstr "etwas weniger Ausgaben erzeugen" -#: src/dirmngr.c:120 +#: src/dirmngr.c:121 msgid "sh-style command output" msgstr "Kommandausgabe für /bin/sh" -#: src/dirmngr.c:121 +#: src/dirmngr.c:122 msgid "csh-style command output" msgstr "Kommandausgabe für /bin/csh" -#: src/dirmngr.c:122 +#: src/dirmngr.c:123 msgid "|FILE|read options from FILE" msgstr "|DATEI|Lese Optionen aus DATEI" -#: src/dirmngr.c:124 +#: src/dirmngr.c:125 msgid "|LEVEL|set the debugging level to LEVEL" msgstr "|NAME|Setze die Debugebene auf NAME" -#: src/dirmngr.c:125 +#: src/dirmngr.c:126 msgid "do not detach from the console" msgstr "Nicht von der Konsole loslösen" -#: src/dirmngr.c:126 +#: src/dirmngr.c:127 msgid "|FILE|write logs to FILE" msgstr "|DATEI|Schreibe Logs in DATEI" -#: src/dirmngr.c:127 +#: src/dirmngr.c:128 msgid "run without asking a user" msgstr "Ausführung ohne Benutzernachfrage" -#: src/dirmngr.c:128 +#: src/dirmngr.c:129 msgid "force loading of outdated CRLs" msgstr "Laden von abgelaufenen CRLs erzwingen" -#: src/dirmngr.c:129 +#: src/dirmngr.c:130 msgid "allow sending OCSP requests" msgstr "OCSP Anfragen erlauben" -#: src/dirmngr.c:130 +#: src/dirmngr.c:131 msgid "inhibit the use of HTTP" msgstr "Sperre die Benutzung von HTTP" -#: src/dirmngr.c:131 +#: src/dirmngr.c:132 msgid "inhibit the use of LDAP" msgstr "Sperre die Benutzung von LDAP" -#: src/dirmngr.c:133 +#: src/dirmngr.c:134 msgid "ignore HTTP CRL distribution points" msgstr "Ãœbergehe HTTP CRL Distribution Points" -#: src/dirmngr.c:135 +#: src/dirmngr.c:136 msgid "ignore LDAP CRL distribution points" msgstr "Ãœbergehe LDAP CRL Distribution Points" -#: src/dirmngr.c:137 +#: src/dirmngr.c:138 +msgid "ignore certificate contained OCSP service URLs" +msgstr "Ãœbergehe im Zertifikat enthaltene OCSP Service URLs" + +#: src/dirmngr.c:140 msgid "|URL|redirect all HTTP requests to URL" msgstr "|URL|Leite alle HTTP Anfragen über URL" -#: src/dirmngr.c:139 +#: src/dirmngr.c:142 msgid "|HOST|use HOST for LDAP queries" msgstr "|HOST|Benutze HOST für LDAP Anfragen" -#: src/dirmngr.c:141 +#: src/dirmngr.c:144 msgid "do not use fallback hosts with --ldap-proxy" msgstr "Keine Benuztung der Rückgriffshosts mit --ldap-proxy" -#: src/dirmngr.c:144 +#: src/dirmngr.c:147 msgid "|FILE|read LDAP server list from FILE" msgstr "|DATEI|Lese die LDAP Serverliste aus DATEI" -#: src/dirmngr.c:146 +#: src/dirmngr.c:149 msgid "add new servers discovered in CRL distribution points to serverlist" msgstr "Füge neue Server aus den CRL Distribution Points der Serverliste hinzu" -#: src/dirmngr.c:148 src/dirmngr_ldap.c:75 +#: src/dirmngr.c:151 src/dirmngr_ldap.c:75 msgid "|N|set LDAP timeout to N seconds" msgstr "|N|Setze das LDAP Timeout auf N Sekunden" -#: src/dirmngr.c:150 +#: src/dirmngr.c:153 msgid "|URL|use OCSP responder at URL" msgstr "|URL|Benutze den OCSP Reponder mit dieser URL" -#: src/dirmngr.c:151 +#: src/dirmngr.c:154 msgid "|FPR|OCSP response signed by FPR" msgstr "|FPR|OCSP Antwort ist durch FPR signiert" -#: src/dirmngr.c:154 +#: src/dirmngr.c:157 msgid "|N|do not return more than N items in one query" msgstr "|N|Nicht mehr als N Angaben in einer Anfrage zurückgeben" -#: src/dirmngr.c:156 +#: src/dirmngr.c:159 msgid "|FILE|listen on socket FILE" msgstr "|DATEI|Anfragen auf Socket DATEI annehmen" -#: src/dirmngr.c:211 src/dirmngr-client.c:126 src/dirmngr_ldap.c:134 +#: src/dirmngr.c:214 src/dirmngr-client.c:126 src/dirmngr_ldap.c:134 msgid "Please report bugs to .\n" msgstr "Berichte über Bugs (Programmfehler) bitte an .\n" -#: src/dirmngr.c:215 +#: src/dirmngr.c:218 msgid "Usage: dirmngr [options] (-h for help)" msgstr "Gebrauch: dirmnr [Optionen] [Kommando [Argumente]]" -#: src/dirmngr.c:218 +#: src/dirmngr.c:221 msgid "" "Syntax: dirmngr [options] [command [args]]\n" "LDAP and OCSP access for GnuPG\n" @@ -789,179 +793,179 @@ "Syntax: dirmngr [Optionen] [Kommando [Argumente]]\n" "LDAP und OCSP Zugriff für GnuPG\n" -#: src/dirmngr.c:289 +#: src/dirmngr.c:292 #, c-format msgid "invalid debug-level `%s' given\n" msgstr "Ungültige Debugebene '%s' angegeben\n" -#: src/dirmngr.c:290 +#: src/dirmngr.c:293 #, c-format msgid "valid debug levels are: %s\n" msgstr "Gültige Debugebenen sind: %s\n" -#: src/dirmngr.c:328 +#: src/dirmngr.c:331 msgid "usage: dirmngr [options] " msgstr "Gebrauch: dirmngr [Optionen] " -#: src/dirmngr.c:353 +#: src/dirmngr.c:356 #, c-format msgid "error spawning ldap wrapper ripper thread: %s\n" msgstr "Fehler beim Starten des LDAP Wrapper Thread: %s\n" -#: src/dirmngr.c:471 src/dirmngr.c:481 +#: src/dirmngr.c:476 src/dirmngr.c:486 #, c-format msgid "%s is too old (need %s, have %s)\n" msgstr "%s ist zu alt (benötige %s, habe %s)\n" -#: src/dirmngr.c:582 +#: src/dirmngr.c:587 #, c-format msgid "NOTE: no default option file `%s'\n" msgstr "Hinweis: Voreingestellte Optionendatei `%s' nicht vorhanden\n" -#: src/dirmngr.c:587 src/dirmngr.c:1248 +#: src/dirmngr.c:592 src/dirmngr.c:1253 #, c-format msgid "option file `%s': %s\n" msgstr "Optionendatei `%s': %s\n" -#: src/dirmngr.c:595 +#: src/dirmngr.c:600 #, c-format msgid "reading options from `%s'\n" msgstr "Optionen werden von `%s' gelesen\n" -#: src/dirmngr.c:701 +#: src/dirmngr.c:706 #, c-format msgid "WARNING: running with faked system time %s\n" msgstr "WARNUNG: Prozess läuft mit getürkter Systemzeit %s\n" -#: src/dirmngr.c:777 +#: src/dirmngr.c:782 msgid "colons are not allowed in the socket name\n" msgstr "Doppelpunkte sind im Namen des Sockets nicht erlaubt\n" -#: src/dirmngr.c:782 +#: src/dirmngr.c:787 msgid "name of socket too long\n" msgstr "Name des Sockets ist zu lang\n" -#: src/dirmngr.c:789 +#: src/dirmngr.c:794 #, c-format msgid "can't create socket: %s\n" msgstr "Fehler beim Erzeugen des Sockets: %s\n" -#: src/dirmngr.c:808 +#: src/dirmngr.c:813 #, c-format msgid "error binding socket to `%s': %s\n" msgstr "Fehler beim Binden des Sockets an `%s': %s\n" -#: src/dirmngr.c:817 +#: src/dirmngr.c:822 #, c-format msgid "listen() failed: %s\n" msgstr "listen() fehlgeschlagen: %s\n" -#: src/dirmngr.c:823 +#: src/dirmngr.c:828 #, c-format msgid "listening on socket `%s'\n" msgstr "Anfragen werden auf Socket `%s' engegengenommen\n" -#: src/dirmngr.c:829 +#: src/dirmngr.c:834 #, c-format msgid "fork failed: %s\n" msgstr "fork() fehlgeschlagen: %s\n" -#: src/dirmngr.c:847 +#: src/dirmngr.c:852 msgid "out of core\n" msgstr "Nicht genügend Hauptspeicher vorhanden\n" -#: src/dirmngr.c:886 +#: src/dirmngr.c:891 #, c-format msgid "setsid() failed: %s\n" msgstr "setsid() fehlgeschlagen: %s\n" -#: src/dirmngr.c:896 +#: src/dirmngr.c:901 #, c-format msgid "chdir to / failed: %s\n" msgstr "chdir nach / fehlgeschlagen: %s\n" -#: src/dirmngr.c:945 +#: src/dirmngr.c:950 #, c-format msgid "fetching CRL from `%s' failed: %s\n" msgstr "Holen der CRL von `%s' fehlgeschlagen: %s\n" -#: src/dirmngr.c:951 +#: src/dirmngr.c:956 #, c-format msgid "processing CRL from `%s' failed: %s\n" msgstr "Verarbeitung der CRL von `%s' fehlgeschlagen: %s\n" -#: src/dirmngr.c:1095 +#: src/dirmngr.c:1100 #, c-format msgid "error opening `%s': %s\n" msgstr "Fehler beim Öffnen von `%s': %s\n" -#: src/dirmngr.c:1112 +#: src/dirmngr.c:1117 #, c-format msgid "%s:%u: line too long - skipped\n" msgstr "%s:%u: Zeile ist zu lang - übergangen\n" -#: src/dirmngr.c:1140 +#: src/dirmngr.c:1145 #, c-format msgid "%s:%u: no hostname given\n" msgstr "%s:%u: Kein Hostname angegeben\n" -#: src/dirmngr.c:1159 +#: src/dirmngr.c:1164 #, c-format msgid "%s:%u: password given without user\n" msgstr "%s:%u: Passwort angegeben ohne Username\n" -#: src/dirmngr.c:1180 +#: src/dirmngr.c:1185 #, c-format msgid "%s:%u: skipping this line\n" msgstr "%s:%u: Diese Zeile wird übersprungen\n" -#: src/dirmngr.c:1280 +#: src/dirmngr.c:1285 msgid "SIGHUP received - re-reading configuration and flushing caches\n" msgstr "" "SIGHUP empfangen - lese die Konfiguration erneut und lösche die Caches\n" -#: src/dirmngr.c:1294 +#: src/dirmngr.c:1299 msgid "SIGUSR2 received - no action defined\n" msgstr "SIGUSR2 empfangen - keine Aktion definiert\n" -#: src/dirmngr.c:1299 +#: src/dirmngr.c:1304 msgid "SIGTERM received - shutting down ...\n" msgstr "SIGTERM empfangen - wird heruntergefahren ...\n" -#: src/dirmngr.c:1301 +#: src/dirmngr.c:1306 #, c-format msgid "SIGTERM received - still %d active connections\n" msgstr "SIGTERM empfangen - immer noch %d Verbindungen aktiv\n" -#: src/dirmngr.c:1306 +#: src/dirmngr.c:1311 msgid "shutdown forced\n" msgstr "Herunterfahren wurde erzwungen\n" -#: src/dirmngr.c:1314 +#: src/dirmngr.c:1319 msgid "SIGINT received - immediate shutdown\n" msgstr "SIGINT empfangen - wird sofort heruntergefahren\n" -#: src/dirmngr.c:1321 +#: src/dirmngr.c:1326 #, c-format msgid "signal %d received - no action defined\n" msgstr "Signal %d empfangen - keine Aktion definiert\n" -#: src/dirmngr.c:1335 +#: src/dirmngr.c:1340 #, c-format msgid "handler for fd %d started\n" msgstr "Routine für fd %d gestartet\n" -#: src/dirmngr.c:1340 +#: src/dirmngr.c:1345 #, c-format msgid "handler for fd %d terminated\n" msgstr "Routine für fd %d beendet\n" -#: src/dirmngr.c:1396 +#: src/dirmngr.c:1401 #, c-format msgid "accept failed: %s - waiting 1s\n" msgstr "accept() fehlgeschlagen: %s - warte 1s\n" -#: src/dirmngr.c:1403 +#: src/dirmngr.c:1408 #, c-format msgid "error spawning connection handler: %s\n" msgstr "Fehler beim Starten des Verbindungshandler: %s\n" Index: dirmngr/po/dirmngr.pot diff -u dirmngr/po/dirmngr.pot:1.6 dirmngr/po/dirmngr.pot:1.7 --- dirmngr/po/dirmngr.pot:1.6 Wed Nov 24 13:25:53 2004 +++ dirmngr/po/dirmngr.pot Wed Nov 24 15:44:01 2004 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: gpa-dev@gnupg.org\n" -"POT-Creation-Date: 2004-11-24 13:16+0100\n" +"POT-Creation-Date: 2004-11-24 15:35+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -206,7 +206,7 @@ msgid "unsupported record type in `%s' line %u skipped\n" msgstr "" -#: src/crlcache.c:574 src/crlcache.c:803 src/dirmngr.c:1191 +#: src/crlcache.c:574 src/crlcache.c:803 src/dirmngr.c:1196 #, c-format msgid "error reading `%s': %s\n" msgstr "" @@ -608,333 +608,337 @@ msgid "Certificate search not possible due to disabled %s\n" msgstr "" -#: src/dirmngr.c:105 +#: src/dirmngr.c:106 msgid "" "@Commands:\n" " " msgstr "" -#: src/dirmngr.c:107 +#: src/dirmngr.c:108 msgid "run in server mode (foreground)" msgstr "" -#: src/dirmngr.c:108 +#: src/dirmngr.c:109 msgid "run in daemon mode (background)" msgstr "" -#: src/dirmngr.c:109 +#: src/dirmngr.c:110 msgid "list the contents of the CRL cache" msgstr "" -#: src/dirmngr.c:110 +#: src/dirmngr.c:111 msgid "|FILE|load CRL from FILE into cache" msgstr "" -#: src/dirmngr.c:111 +#: src/dirmngr.c:112 msgid "|URL|fetch a CRL from URL" msgstr "" -#: src/dirmngr.c:112 +#: src/dirmngr.c:113 msgid "shutdown the dirmngr" msgstr "" -#: src/dirmngr.c:113 +#: src/dirmngr.c:114 msgid "flush the cache" msgstr "" -#: src/dirmngr.c:116 +#: src/dirmngr.c:117 msgid "" "@\n" "Options:\n" " " msgstr "" -#: src/dirmngr.c:118 src/dirmngr-client.c:64 src/dirmngr_ldap.c:73 +#: src/dirmngr.c:119 src/dirmngr-client.c:64 src/dirmngr_ldap.c:73 msgid "verbose" msgstr "" -#: src/dirmngr.c:119 src/dirmngr-client.c:65 src/dirmngr_ldap.c:74 +#: src/dirmngr.c:120 src/dirmngr-client.c:65 src/dirmngr_ldap.c:74 msgid "be somewhat more quiet" msgstr "" -#: src/dirmngr.c:120 +#: src/dirmngr.c:121 msgid "sh-style command output" msgstr "" -#: src/dirmngr.c:121 +#: src/dirmngr.c:122 msgid "csh-style command output" msgstr "" -#: src/dirmngr.c:122 +#: src/dirmngr.c:123 msgid "|FILE|read options from FILE" msgstr "" -#: src/dirmngr.c:124 +#: src/dirmngr.c:125 msgid "|LEVEL|set the debugging level to LEVEL" msgstr "" -#: src/dirmngr.c:125 +#: src/dirmngr.c:126 msgid "do not detach from the console" msgstr "" -#: src/dirmngr.c:126 +#: src/dirmngr.c:127 msgid "|FILE|write logs to FILE" msgstr "" -#: src/dirmngr.c:127 +#: src/dirmngr.c:128 msgid "run without asking a user" msgstr "" -#: src/dirmngr.c:128 +#: src/dirmngr.c:129 msgid "force loading of outdated CRLs" msgstr "" -#: src/dirmngr.c:129 +#: src/dirmngr.c:130 msgid "allow sending OCSP requests" msgstr "" -#: src/dirmngr.c:130 +#: src/dirmngr.c:131 msgid "inhibit the use of HTTP" msgstr "" -#: src/dirmngr.c:131 +#: src/dirmngr.c:132 msgid "inhibit the use of LDAP" msgstr "" -#: src/dirmngr.c:133 +#: src/dirmngr.c:134 msgid "ignore HTTP CRL distribution points" msgstr "" -#: src/dirmngr.c:135 +#: src/dirmngr.c:136 msgid "ignore LDAP CRL distribution points" msgstr "" -#: src/dirmngr.c:137 +#: src/dirmngr.c:138 +msgid "ignore certificate contained OCSP service URLs" +msgstr "" + +#: src/dirmngr.c:140 msgid "|URL|redirect all HTTP requests to URL" msgstr "" -#: src/dirmngr.c:139 +#: src/dirmngr.c:142 msgid "|HOST|use HOST for LDAP queries" msgstr "" -#: src/dirmngr.c:141 +#: src/dirmngr.c:144 msgid "do not use fallback hosts with --ldap-proxy" msgstr "" -#: src/dirmngr.c:144 +#: src/dirmngr.c:147 msgid "|FILE|read LDAP server list from FILE" msgstr "" -#: src/dirmngr.c:146 +#: src/dirmngr.c:149 msgid "add new servers discovered in CRL distribution points to serverlist" msgstr "" -#: src/dirmngr.c:148 src/dirmngr_ldap.c:75 +#: src/dirmngr.c:151 src/dirmngr_ldap.c:75 msgid "|N|set LDAP timeout to N seconds" msgstr "" -#: src/dirmngr.c:150 +#: src/dirmngr.c:153 msgid "|URL|use OCSP responder at URL" msgstr "" -#: src/dirmngr.c:151 +#: src/dirmngr.c:154 msgid "|FPR|OCSP response signed by FPR" msgstr "" -#: src/dirmngr.c:154 +#: src/dirmngr.c:157 msgid "|N|do not return more than N items in one query" msgstr "" -#: src/dirmngr.c:156 +#: src/dirmngr.c:159 msgid "|FILE|listen on socket FILE" msgstr "" -#: src/dirmngr.c:211 src/dirmngr-client.c:126 src/dirmngr_ldap.c:134 +#: src/dirmngr.c:214 src/dirmngr-client.c:126 src/dirmngr_ldap.c:134 msgid "Please report bugs to .\n" msgstr "" -#: src/dirmngr.c:215 +#: src/dirmngr.c:218 msgid "Usage: dirmngr [options] (-h for help)" msgstr "" -#: src/dirmngr.c:218 +#: src/dirmngr.c:221 msgid "" "Syntax: dirmngr [options] [command [args]]\n" "LDAP and OCSP access for GnuPG\n" msgstr "" -#: src/dirmngr.c:289 +#: src/dirmngr.c:292 #, c-format msgid "invalid debug-level `%s' given\n" msgstr "" -#: src/dirmngr.c:290 +#: src/dirmngr.c:293 #, c-format msgid "valid debug levels are: %s\n" msgstr "" -#: src/dirmngr.c:328 +#: src/dirmngr.c:331 msgid "usage: dirmngr [options] " msgstr "" -#: src/dirmngr.c:353 +#: src/dirmngr.c:356 #, c-format msgid "error spawning ldap wrapper ripper thread: %s\n" msgstr "" -#: src/dirmngr.c:471 src/dirmngr.c:481 +#: src/dirmngr.c:476 src/dirmngr.c:486 #, c-format msgid "%s is too old (need %s, have %s)\n" msgstr "" -#: src/dirmngr.c:582 +#: src/dirmngr.c:587 #, c-format msgid "NOTE: no default option file `%s'\n" msgstr "" -#: src/dirmngr.c:587 src/dirmngr.c:1248 +#: src/dirmngr.c:592 src/dirmngr.c:1253 #, c-format msgid "option file `%s': %s\n" msgstr "" -#: src/dirmngr.c:595 +#: src/dirmngr.c:600 #, c-format msgid "reading options from `%s'\n" msgstr "" -#: src/dirmngr.c:701 +#: src/dirmngr.c:706 #, c-format msgid "WARNING: running with faked system time %s\n" msgstr "" -#: src/dirmngr.c:777 +#: src/dirmngr.c:782 msgid "colons are not allowed in the socket name\n" msgstr "" -#: src/dirmngr.c:782 +#: src/dirmngr.c:787 msgid "name of socket too long\n" msgstr "" -#: src/dirmngr.c:789 +#: src/dirmngr.c:794 #, c-format msgid "can't create socket: %s\n" msgstr "" -#: src/dirmngr.c:808 +#: src/dirmngr.c:813 #, c-format msgid "error binding socket to `%s': %s\n" msgstr "" -#: src/dirmngr.c:817 +#: src/dirmngr.c:822 #, c-format msgid "listen() failed: %s\n" msgstr "" -#: src/dirmngr.c:823 +#: src/dirmngr.c:828 #, c-format msgid "listening on socket `%s'\n" msgstr "" -#: src/dirmngr.c:829 +#: src/dirmngr.c:834 #, c-format msgid "fork failed: %s\n" msgstr "" -#: src/dirmngr.c:847 +#: src/dirmngr.c:852 msgid "out of core\n" msgstr "" -#: src/dirmngr.c:886 +#: src/dirmngr.c:891 #, c-format msgid "setsid() failed: %s\n" msgstr "" -#: src/dirmngr.c:896 +#: src/dirmngr.c:901 #, c-format msgid "chdir to / failed: %s\n" msgstr "" -#: src/dirmngr.c:945 +#: src/dirmngr.c:950 #, c-format msgid "fetching CRL from `%s' failed: %s\n" msgstr "" -#: src/dirmngr.c:951 +#: src/dirmngr.c:956 #, c-format msgid "processing CRL from `%s' failed: %s\n" msgstr "" -#: src/dirmngr.c:1095 +#: src/dirmngr.c:1100 #, c-format msgid "error opening `%s': %s\n" msgstr "" -#: src/dirmngr.c:1112 +#: src/dirmngr.c:1117 #, c-format msgid "%s:%u: line too long - skipped\n" msgstr "" -#: src/dirmngr.c:1140 +#: src/dirmngr.c:1145 #, c-format msgid "%s:%u: no hostname given\n" msgstr "" -#: src/dirmngr.c:1159 +#: src/dirmngr.c:1164 #, c-format msgid "%s:%u: password given without user\n" msgstr "" -#: src/dirmngr.c:1180 +#: src/dirmngr.c:1185 #, c-format msgid "%s:%u: skipping this line\n" msgstr "" -#: src/dirmngr.c:1280 +#: src/dirmngr.c:1285 msgid "SIGHUP received - re-reading configuration and flushing caches\n" msgstr "" -#: src/dirmngr.c:1294 +#: src/dirmngr.c:1299 msgid "SIGUSR2 received - no action defined\n" msgstr "" -#: src/dirmngr.c:1299 +#: src/dirmngr.c:1304 msgid "SIGTERM received - shutting down ...\n" msgstr "" -#: src/dirmngr.c:1301 +#: src/dirmngr.c:1306 #, c-format msgid "SIGTERM received - still %d active connections\n" msgstr "" -#: src/dirmngr.c:1306 +#: src/dirmngr.c:1311 msgid "shutdown forced\n" msgstr "" -#: src/dirmngr.c:1314 +#: src/dirmngr.c:1319 msgid "SIGINT received - immediate shutdown\n" msgstr "" -#: src/dirmngr.c:1321 +#: src/dirmngr.c:1326 #, c-format msgid "signal %d received - no action defined\n" msgstr "" -#: src/dirmngr.c:1335 +#: src/dirmngr.c:1340 #, c-format msgid "handler for fd %d started\n" msgstr "" -#: src/dirmngr.c:1340 +#: src/dirmngr.c:1345 #, c-format msgid "handler for fd %d terminated\n" msgstr "" -#: src/dirmngr.c:1396 +#: src/dirmngr.c:1401 #, c-format msgid "accept failed: %s - waiting 1s\n" msgstr "" -#: src/dirmngr.c:1403 +#: src/dirmngr.c:1408 #, c-format msgid "error spawning connection handler: %s\n" msgstr "" Index: dirmngr/src/ChangeLog diff -u dirmngr/src/ChangeLog:1.27 dirmngr/src/ChangeLog:1.28 --- dirmngr/src/ChangeLog:1.27 Wed Nov 24 13:25:53 2004 +++ dirmngr/src/ChangeLog Wed Nov 24 15:44:01 2004 @@ -1,7 +1,9 @@ 2004-11-24 Werner Koch - * dirmngr.c: New options --ignore-http-dp and --ignore-ldap-dp. + * dirmngr.c: New options --ignore-http-dp, --ignore-ldap-dp and + --ignore-ocsp-service-url. * crlcache.c (crl_cache_reload_crl): Implement them. + * ocsp.c (ocsp_isvalid): Ditto. 2004-11-23 Werner Koch Index: dirmngr/src/dirmngr.c diff -u dirmngr/src/dirmngr.c:1.46 dirmngr/src/dirmngr.c:1.47 --- dirmngr/src/dirmngr.c:1.46 Wed Nov 24 13:25:53 2004 +++ dirmngr/src/dirmngr.c Wed Nov 24 15:44:01 2004 @@ -80,6 +80,7 @@ oDisableLDAP, oIgnoreLDAPDP, oIgnoreHTTPDP, + oIgnoreOCSPSvcUrl, oHonorHTTPProxy, oHTTPProxy, oLDAPProxy, @@ -129,10 +130,12 @@ { oAllowOCSP, "allow-ocsp",0,N_("allow sending OCSP requests")}, { oDisableHTTP, "disable-http", 0, N_("inhibit the use of HTTP")}, { oDisableLDAP, "disable-ldap", 0, N_("inhibit the use of LDAP")}, - { oIgnoreHTTPDP,"ignore-http-dp",0, + { oIgnoreHTTPDP,"ignore-http-dp", 0, N_("ignore HTTP CRL distribution points")}, - { oIgnoreLDAPDP,"ignore-ldap-dp",0, + { oIgnoreLDAPDP,"ignore-ldap-dp", 0, N_("ignore LDAP CRL distribution points")}, + { oIgnoreOCSPSvcUrl, "ignore-ocsp-service-url", 0, + N_("ignore certificate contained OCSP service URLs")}, { oHTTPProxy, "http-proxy", 2, N_("|URL|redirect all HTTP requests to URL")}, { oLDAPProxy, "ldap-proxy", 2, @@ -380,6 +383,7 @@ opt.only_ldap_proxy = 0; opt.ignore_http_dp = 0; opt.ignore_ldap_dp = 0; + opt.ignore_ocsp_service_url = 0; return 1; } @@ -418,6 +422,7 @@ case oOnlyLDAPProxy: opt.only_ldap_proxy = 1; break; case oIgnoreHTTPDP: opt.ignore_http_dp = 1; break; case oIgnoreLDAPDP: opt.ignore_ldap_dp = 1; break; + case oIgnoreOCSPSvcUrl: opt.ignore_ocsp_service_url = 1; break; default: return 0; /* Not handled. */ Index: dirmngr/src/dirmngr.h diff -u dirmngr/src/dirmngr.h:1.22 dirmngr/src/dirmngr.h:1.23 --- dirmngr/src/dirmngr.h:1.22 Wed Nov 24 13:25:53 2004 +++ dirmngr/src/dirmngr.h Wed Nov 24 15:44:01 2004 @@ -89,6 +89,8 @@ int only_ldap_proxy; /* Only use the LDAP proxy; no fallback. */ int ignore_http_dp; /* Ignore HTTP CRL distribution points. */ int ignore_ldap_dp; /* Ignore LDAP CRL distribution points. */ + int ignore_ocsp_service_url; /* Ignore OCSP service URLs as given in + the certificate. */ int allow_ocsp; /* Allow using OCSP. */ Index: dirmngr/src/ocsp.c diff -u dirmngr/src/ocsp.c:1.11 dirmngr/src/ocsp.c:1.12 --- dirmngr/src/ocsp.c:1.11 Tue Nov 23 14:20:44 2004 +++ dirmngr/src/ocsp.c Wed Nov 24 15:44:01 2004 @@ -458,7 +458,7 @@ 2. If this fails use the default responder, if any. */ url = NULL; - for (idx=0; !url + for (idx=0; !url && !opt.ignore_ocsp_service_url && !(err=ksba_cert_get_authority_info_access (cert, idx, &oid, &name)); idx++) { From cvs at cvs.gnupg.org Wed Nov 24 15:38:41 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Wed Nov 24 15:38:43 2004 Subject: dirmngr/src (dirmngr.c) Message-ID: Date: Wednesday, November 24, 2004 @ 15:45:28 Author: wk Path: /cvs/dirmngr/dirmngr/src Modified: dirmngr.c And well: add it to the gpgconf list too -----------+ dirmngr.c | 2 +- 1 files changed, 1 insertion(+), 1 deletion(-) Index: dirmngr/src/dirmngr.c diff -u dirmngr/src/dirmngr.c:1.47 dirmngr/src/dirmngr.c:1.48 --- dirmngr/src/dirmngr.c:1.47 Wed Nov 24 15:44:01 2004 +++ dirmngr/src/dirmngr.c Wed Nov 24 15:45:27 2004 @@ -1029,7 +1029,7 @@ printf ("only-ldap-proxy:%lu:\n", GC_OPT_FLAG_NONE); printf ("ignore-ldap-dp:%lu:\n", GC_OPT_FLAG_NONE); printf ("ignore-http-dp:%lu:\n", GC_OPT_FLAG_NONE); - + printf ("ignore-ocsp-service-url:%lu:\n", GC_OPT_FLAG_NONE); } cleanup (); return !!rc; From cvs at cvs.gnupg.org Wed Nov 24 15:43:35 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Wed Nov 24 15:43:38 2004 Subject: GNUPG-1-9-BRANCH gnupg (doc/debugging.texi po/de.po tools/ChangeLog tools/gpgconf-comp.c) Message-ID: Date: Wednesday, November 24, 2004 @ 15:50:20 Author: wk Path: /cvs/gnupg/gnupg Tag: GNUPG-1-9-BRANCH Modified: doc/debugging.texi po/de.po tools/ChangeLog tools/gpgconf-comp.c Add dirmngr options to gpgconf and updated the DE translation ----------------------+ doc/debugging.texi | 2 po/de.po | 216 +++++++++++++++++++++++++------------------------ tools/ChangeLog | 4 tools/gpgconf-comp.c | 3 4 files changed, 118 insertions(+), 107 deletions(-) Index: gnupg/doc/debugging.texi diff -u gnupg/doc/debugging.texi:1.1.2.3 gnupg/doc/debugging.texi:1.1.2.4 --- gnupg/doc/debugging.texi:1.1.2.3 Tue Nov 23 18:09:51 2004 +++ gnupg/doc/debugging.texi Wed Nov 24 15:50:19 2004 @@ -101,7 +101,7 @@ this environment variable gets exported, that is you should follow up the setting with an @samp{export GPG_TTY} (assuming a Bourne style shell). Even for GUI based Pinentries; you should have set -@code{GPG_TTY}. See the section on installing the @program{gpg-agent} +@code{GPG_TTY}. See the section on installing the @command{gpg-agent} on how to do it. Index: gnupg/po/de.po diff -u gnupg/po/de.po:1.84.2.13 gnupg/po/de.po:1.84.2.14 --- gnupg/po/de.po:1.84.2.13 Fri Oct 22 18:03:03 2004 +++ gnupg/po/de.po Wed Nov 24 15:50:19 2004 @@ -10,8 +10,8 @@ msgstr "" "Project-Id-Version: gnupg2 1.9.10\n" "Report-Msgid-Bugs-To: translations@gnupg.org\n" -"POT-Creation-Date: 2004-10-22 15:02+0200\n" -"PO-Revision-Date: 2004-10-22 15:02+0200\n" +"POT-Creation-Date: 2004-11-24 15:41+0100\n" +"PO-Revision-Date: 2004-11-24 15:43+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: de\n" "MIME-Version: 1.0\n" @@ -34,12 +34,12 @@ msgid "run in daemon mode (background)" msgstr "Im Daemon Modus ausführen" -#: agent/gpg-agent.c:101 kbx/kbxutil.c:81 scd/scdaemon.c:97 sm/gpgsm.c:315 +#: agent/gpg-agent.c:101 kbx/kbxutil.c:81 scd/scdaemon.c:97 sm/gpgsm.c:317 #: tools/gpgconf.c:62 msgid "verbose" msgstr "ausführlich" -#: agent/gpg-agent.c:102 kbx/kbxutil.c:82 scd/scdaemon.c:98 sm/gpgsm.c:316 +#: agent/gpg-agent.c:102 kbx/kbxutil.c:82 scd/scdaemon.c:98 sm/gpgsm.c:318 msgid "be somewhat more quiet" msgstr "Etwas weniger Ausgaben erzeugen" @@ -63,7 +63,7 @@ msgid "do not grab keyboard and mouse" msgstr "Tastatur und Maus nicht \"grabben\"" -#: agent/gpg-agent.c:112 scd/scdaemon.c:108 sm/gpgsm.c:318 +#: agent/gpg-agent.c:112 scd/scdaemon.c:108 sm/gpgsm.c:320 msgid "use a log file for the server" msgstr "Logausgaben in eine Datei umlenken" @@ -100,12 +100,12 @@ msgstr "erlaube Aufrufern Schlüssel als \"vertrauenswürdig\" zu markieren" #: agent/gpg-agent.c:195 agent/protect-tool.c:134 scd/scdaemon.c:168 -#: sm/gpgsm.c:485 tools/gpgconf.c:85 +#: sm/gpgsm.c:487 tools/gpgconf.c:85 msgid "Please report bugs to <" msgstr "Fehlerberichte bitte an <" #: agent/gpg-agent.c:195 agent/protect-tool.c:134 scd/scdaemon.c:168 -#: sm/gpgsm.c:485 tools/gpgconf.c:85 +#: sm/gpgsm.c:487 tools/gpgconf.c:85 msgid ">.\n" msgstr ">.\n" @@ -121,30 +121,30 @@ "Syntax: gpg-agent [Optionen] [Kommando [Argumente]]\n" "Verwaltung von geheimen Schlüssel für GnuPG\n" -#: agent/gpg-agent.c:271 scd/scdaemon.c:242 sm/gpgsm.c:603 +#: agent/gpg-agent.c:271 scd/scdaemon.c:242 sm/gpgsm.c:605 #, c-format msgid "invalid debug-level `%s' given\n" msgstr "ungültige Debugebene `%s' angegeben\n" #: agent/gpg-agent.c:448 agent/protect-tool.c:1050 kbx/kbxutil.c:431 -#: scd/scdaemon.c:357 sm/gpgsm.c:726 +#: scd/scdaemon.c:357 sm/gpgsm.c:728 #, c-format msgid "libgcrypt is too old (need %s, have %s)\n" msgstr "" "Die Bibliothek \"libgcrypt\" is zu alt (benötigt wird %s, vorhanden ist %s)\n" -#: agent/gpg-agent.c:521 scd/scdaemon.c:437 sm/gpgsm.c:824 +#: agent/gpg-agent.c:521 scd/scdaemon.c:437 sm/gpgsm.c:826 #, c-format msgid "NOTE: no default option file `%s'\n" msgstr "Notiz: Voreingestellte Konfigurationsdatei `%s' fehlt\n" #: agent/gpg-agent.c:526 agent/gpg-agent.c:1000 scd/scdaemon.c:442 -#: sm/gpgsm.c:828 +#: sm/gpgsm.c:830 #, c-format msgid "option file `%s': %s\n" msgstr "Konfigurationsdatei `%s': %s\n" -#: agent/gpg-agent.c:534 scd/scdaemon.c:450 sm/gpgsm.c:835 +#: agent/gpg-agent.c:534 scd/scdaemon.c:450 sm/gpgsm.c:837 #, c-format msgid "reading options from `%s'\n" msgstr "Optionen werden aus `%s' gelesen\n" @@ -327,12 +327,12 @@ msgid "problem with the agent\n" msgstr "Problem mit dem Agenten\n" -#: jnlib/logging.c:621 +#: jnlib/logging.c:625 #, c-format msgid "you found a bug ... (%s:%d)\n" msgstr "Sie haben einen Bug (Softwarefehler) gefunden ... (%s:%d)\n" -#: kbx/kbxutil.c:68 sm/gpgsm.c:226 tools/gpgconf.c:53 +#: kbx/kbxutil.c:68 sm/gpgsm.c:227 tools/gpgconf.c:53 msgid "" "@Commands:\n" " " @@ -340,7 +340,7 @@ "@Kommandos:\n" " " -#: kbx/kbxutil.c:76 sm/gpgsm.c:261 tools/gpgconf.c:59 +#: kbx/kbxutil.c:76 sm/gpgsm.c:262 tools/gpgconf.c:59 msgid "" "@\n" "Options:\n" @@ -350,7 +350,7 @@ "Optionen:\n" " " -#: kbx/kbxutil.c:83 sm/gpgsm.c:323 tools/gpgconf.c:64 +#: kbx/kbxutil.c:83 sm/gpgsm.c:325 tools/gpgconf.c:64 msgid "do not make any changes" msgstr "Keine Änderungen durchführen" @@ -382,7 +382,7 @@ "Syntax: kbxutil [Optionen] [Dateien]\n" "Anlistem exportieren und Importieren von KeyBox Dateien\n" -#: scd/scdaemon.c:101 sm/gpgsm.c:335 +#: scd/scdaemon.c:101 sm/gpgsm.c:337 msgid "read options from file" msgstr "Konfigurationsoptionen aus Datei lesen" @@ -529,20 +529,20 @@ msgid "can't connect to the agent - trying fall back\n" msgstr "Verbindung zum gpg-agent nicht möglich - Ersatzmethode wird versucht\n" -#: sm/call-dirmngr.c:164 +#: sm/call-dirmngr.c:173 msgid "no running dirmngr - starting one\n" msgstr "Kein aktiver Dirmngr - es wird einer gestartet\n" -#: sm/call-dirmngr.c:202 +#: sm/call-dirmngr.c:213 msgid "malformed DIRMNGR_INFO environment variable\n" msgstr "Die Variable DIRMNGR_INFO ist fehlerhaft\n" -#: sm/call-dirmngr.c:214 +#: sm/call-dirmngr.c:225 #, c-format msgid "dirmngr protocol version %d is not supported\n" msgstr "Die Dirmngr Protokollversion %d wird nicht unterstützt\n" -#: sm/call-dirmngr.c:225 +#: sm/call-dirmngr.c:239 msgid "can't connect to the dirmngr - trying fall back\n" msgstr "" "Verbindung zum Dirmngr kann nicht aufgebaut werden - Ersatzmethode wird " @@ -788,239 +788,243 @@ msgid "no valid recipients given\n" msgstr "Keine gültigen Empfänger angegeben\n" -#: sm/gpgsm.c:228 +#: sm/gpgsm.c:229 msgid "|[FILE]|make a signature" msgstr "|[DATEI]|Erzeuge eine Signatur" -#: sm/gpgsm.c:229 +#: sm/gpgsm.c:230 msgid "|[FILE]|make a clear text signature" msgstr "|[DATEI]|Erzeuge eine Klartextsignatur" -#: sm/gpgsm.c:230 +#: sm/gpgsm.c:231 msgid "make a detached signature" msgstr "Erzeuge eine abgetrennte Signatur" -#: sm/gpgsm.c:231 +#: sm/gpgsm.c:232 msgid "encrypt data" msgstr "Verschlüssele die Daten" -#: sm/gpgsm.c:232 +#: sm/gpgsm.c:233 msgid "encryption only with symmetric cipher" msgstr "Verschlüsselung nur mit symmetrischem Algrithmus" -#: sm/gpgsm.c:233 +#: sm/gpgsm.c:234 msgid "decrypt data (default)" msgstr "Enschlüssele die Daten" -#: sm/gpgsm.c:234 +#: sm/gpgsm.c:235 msgid "verify a signature" msgstr "Überprüfen einer Signatur" -#: sm/gpgsm.c:236 +#: sm/gpgsm.c:237 msgid "list keys" msgstr "Schlüssel anzeigen" -#: sm/gpgsm.c:237 +#: sm/gpgsm.c:238 msgid "list external keys" msgstr "Externe Schlüssel anzeigen" -#: sm/gpgsm.c:238 +#: sm/gpgsm.c:239 msgid "list secret keys" msgstr "Geheime Schlüssel anzeigen" -#: sm/gpgsm.c:239 +#: sm/gpgsm.c:240 msgid "list certificate chain" msgstr "Schlüssel mit Zertifikatekette anzeigen" -#: sm/gpgsm.c:241 +#: sm/gpgsm.c:242 msgid "list keys and fingerprints" msgstr "Schlüssel und Fingerprint anzeigen" -#: sm/gpgsm.c:242 +#: sm/gpgsm.c:243 msgid "generate a new key pair" msgstr "Neues Schlüsselpaar erzeugen" -#: sm/gpgsm.c:243 +#: sm/gpgsm.c:244 msgid "remove key from the public keyring" msgstr "Schlüssel aus dem öffentlichen Schlüsselbund löschen" -#: sm/gpgsm.c:244 +#: sm/gpgsm.c:245 msgid "export keys to a key server" msgstr "Schlüssen an eine Schlüsselserver exportieren" -#: sm/gpgsm.c:245 +#: sm/gpgsm.c:246 msgid "import keys from a key server" msgstr "Schlüssel von einem Schlüsselserver importieren" -#: sm/gpgsm.c:246 +#: sm/gpgsm.c:247 msgid "import certificates" msgstr "Zertifikate importieren" -#: sm/gpgsm.c:247 +#: sm/gpgsm.c:248 msgid "export certificates" msgstr "Zertifikate exportieren" -#: sm/gpgsm.c:248 +#: sm/gpgsm.c:249 msgid "register a smartcard" msgstr "Smartcard registrieren" -#: sm/gpgsm.c:249 +#: sm/gpgsm.c:250 msgid "run in server mode" msgstr "Im Server Modus ausführen" -#: sm/gpgsm.c:250 +#: sm/gpgsm.c:251 msgid "pass a command to the dirmngr" msgstr "Das Kommand an den Dirmngr durchreichen" -#: sm/gpgsm.c:252 +#: sm/gpgsm.c:253 msgid "invoke gpg-protect-tool" msgstr "Rufe das gpg-protect-tool auf" -#: sm/gpgsm.c:253 +#: sm/gpgsm.c:254 msgid "change a passphrase" msgstr "Das Mantra (Passphrase) ändern" -#: sm/gpgsm.c:263 +#: sm/gpgsm.c:264 msgid "create ascii armored output" msgstr "Ausgabe mit ASCII Hülle wird erzeugt" -#: sm/gpgsm.c:265 +#: sm/gpgsm.c:266 msgid "create base-64 encoded output" msgstr "Ausgabe im Basis-64 format erzeugen" -#: sm/gpgsm.c:267 +#: sm/gpgsm.c:268 msgid "assume input is in PEM format" msgstr "Eingabedaten sind im PEM Format" -#: sm/gpgsm.c:269 +#: sm/gpgsm.c:270 msgid "assume input is in base-64 format" msgstr "Eingabedaten sind im Basis-64 Format" -#: sm/gpgsm.c:271 +#: sm/gpgsm.c:272 msgid "assume input is in binary format" msgstr "Eingabedaten sind im Binärformat" -#: sm/gpgsm.c:273 +#: sm/gpgsm.c:274 msgid "|NAME|encrypt for NAME" msgstr "|NAME|Verschlüsseln für NAME" -#: sm/gpgsm.c:276 +#: sm/gpgsm.c:277 +msgid "use system's dirmngr if available" +msgstr "Benutze den System Dirmngr when verfügbar" + +#: sm/gpgsm.c:278 msgid "never consult a CRL" msgstr "Niemals eine CRL konsultieren" -#: sm/gpgsm.c:281 +#: sm/gpgsm.c:283 msgid "check validity using OCSP" msgstr "Die Gültigkeit mittels OCSP prüfen" -#: sm/gpgsm.c:284 +#: sm/gpgsm.c:286 msgid "|N|number of certificates to include" msgstr "|N|Sende N Zertifikate mit" -#: sm/gpgsm.c:287 +#: sm/gpgsm.c:289 msgid "|FILE|take policy information from FILE" msgstr "|DATEI|Richtlinieninformationen DATEI entnehmen" -#: sm/gpgsm.c:290 +#: sm/gpgsm.c:292 msgid "do not check certificate policies" msgstr "Zertikikatrichtlinien nicht überprüfen" -#: sm/gpgsm.c:294 +#: sm/gpgsm.c:296 msgid "fetch missing issuer certificates" msgstr "Fehlende Zertifikate automatisch holen" -#: sm/gpgsm.c:298 +#: sm/gpgsm.c:300 msgid "|NAME|use NAME as default recipient" msgstr "|NAME|Benutze NAME als voreingestellten Empfänger" -#: sm/gpgsm.c:300 +#: sm/gpgsm.c:302 msgid "use the default key as default recipient" msgstr "Benuzte voreingestellten Schlüssel als Standardempfänger" -#: sm/gpgsm.c:306 +#: sm/gpgsm.c:308 msgid "use this user-id to sign or decrypt" msgstr "Benuzte diese Benutzer ID zum Signieren oder Entschlüsseln" -#: sm/gpgsm.c:309 +#: sm/gpgsm.c:311 msgid "|N|set compress level N (0 disables)" msgstr "|N|Benutze Komprimierungsstufe N" -#: sm/gpgsm.c:311 +#: sm/gpgsm.c:313 msgid "use canonical text mode" msgstr "Kanonischen Textmodus benutzen" -#: sm/gpgsm.c:314 tools/gpgconf.c:61 +#: sm/gpgsm.c:316 tools/gpgconf.c:61 msgid "use as output file" msgstr "als Ausgabedatei benutzen" -#: sm/gpgsm.c:317 +#: sm/gpgsm.c:319 msgid "don't use the terminal at all" msgstr "Das Terminal überhaupt nicht benutzen" -#: sm/gpgsm.c:320 +#: sm/gpgsm.c:322 msgid "force v3 signatures" msgstr "Version 3 Signaturen erzwingen" -#: sm/gpgsm.c:321 +#: sm/gpgsm.c:323 msgid "always use a MDC for encryption" msgstr "Immer das MDC Verfahren zum verschlüsseln mitbenutzen" -#: sm/gpgsm.c:326 +#: sm/gpgsm.c:328 msgid "batch mode: never ask" msgstr "Stapelverarbeitungs Modus: Nie nachfragen" -#: sm/gpgsm.c:327 +#: sm/gpgsm.c:329 msgid "assume yes on most questions" msgstr "\"Ja\" auf die meisten Anfragen annehmen" -#: sm/gpgsm.c:328 +#: sm/gpgsm.c:330 msgid "assume no on most questions" msgstr "\"Nein\" auf die meisten Anfragen annehmen" -#: sm/gpgsm.c:330 +#: sm/gpgsm.c:332 msgid "add this keyring to the list of keyrings" msgstr "Diesen Keyring in die Liste der Keyrings aufnehmen" -#: sm/gpgsm.c:331 +#: sm/gpgsm.c:333 msgid "add this secret keyring to the list" msgstr "Diese geheimen Keyring in die Liste aufnehmen" -#: sm/gpgsm.c:332 +#: sm/gpgsm.c:334 msgid "|NAME|use NAME as default secret key" msgstr "|NAME|Benutze NAME als voreingestellten Schlüssel" -#: sm/gpgsm.c:333 +#: sm/gpgsm.c:335 msgid "|HOST|use this keyserver to lookup keys" msgstr "|HOST|Benutze HOST als Schlüsselserver" -#: sm/gpgsm.c:334 +#: sm/gpgsm.c:336 msgid "|NAME|set terminal charset to NAME" msgstr "|NAME|Den Zeichensatz für das Terminal auf NAME setzen" -#: sm/gpgsm.c:338 +#: sm/gpgsm.c:340 msgid "|LEVEL|set the debugging level to LEVEL" msgstr "|NAME|Die Debugstufe auf NAME setzen" -#: sm/gpgsm.c:345 +#: sm/gpgsm.c:347 msgid "|FD|write status info to this FD" msgstr "|FD|Statusinformationen auf Dateidescriptor FD schreiben" -#: sm/gpgsm.c:352 +#: sm/gpgsm.c:354 msgid "|FILE|load extension module FILE" msgstr "|DATEI|Das Erweiterungsmodul DATEI laden" -#: sm/gpgsm.c:358 +#: sm/gpgsm.c:360 msgid "|NAME|use cipher algorithm NAME" msgstr "|NAME|Den Verschlüsselungsalgrithmus NAME benutzen" -#: sm/gpgsm.c:360 +#: sm/gpgsm.c:362 msgid "|NAME|use message digest algorithm NAME" msgstr "|NAME|Den Hashalgorithmus NAME benutzen" -#: sm/gpgsm.c:362 +#: sm/gpgsm.c:364 msgid "|N|use compress algorithm N" msgstr "|N|Den Kompressionsalgorithmus Nummer N benutzen" -#: sm/gpgsm.c:370 +#: sm/gpgsm.c:372 msgid "" "@\n" "(See the man page for a complete listing of all commands and options)\n" @@ -1028,7 +1032,7 @@ "@\n" "(Die \"man\" Seite beschreibt alle Kommands und Optionen)\n" -#: sm/gpgsm.c:373 +#: sm/gpgsm.c:375 msgid "" "@\n" "Examples:\n" @@ -1048,11 +1052,11 @@ " --list-keys [Namen] Schlüssel anzeigenn\n" " --fingerprint [Namen] \"Fingerabdrücke\" anzeigen\\n\n" -#: sm/gpgsm.c:488 +#: sm/gpgsm.c:490 msgid "Usage: gpgsm [options] [files] (-h for help)" msgstr "Gebrauch: gpgsm [Optionen] [Dateien] (-h für Hilfe)" -#: sm/gpgsm.c:491 +#: sm/gpgsm.c:493 msgid "" "Syntax: gpgsm [options] [files]\n" "sign, check, encrypt or decrypt using the S/MIME protocol\n" @@ -1061,7 +1065,7 @@ "Gebrauch: gpgsm [Optionen] [Dateien]\n" "Signieren, prüfen, ver- und entschlüsseln mittels S/MIME protocol\n" -#: sm/gpgsm.c:498 +#: sm/gpgsm.c:500 msgid "" "\n" "Supported algorithms:\n" @@ -1069,50 +1073,50 @@ "\n" "Unterstützte Algorithmen:\n" -#: sm/gpgsm.c:574 +#: sm/gpgsm.c:576 msgid "usage: gpgsm [options] " msgstr "Gebrauch: gpgsm [Optionen] " -#: sm/gpgsm.c:640 +#: sm/gpgsm.c:642 msgid "conflicting commands\n" msgstr "Widersprechende Kommandos\n" -#: sm/gpgsm.c:656 +#: sm/gpgsm.c:658 #, c-format msgid "can't encrypt to `%s': %s\n" msgstr "Verschlüsseln für `%s' nicht möglich: %s\n" -#: sm/gpgsm.c:731 +#: sm/gpgsm.c:733 #, c-format msgid "libksba is too old (need %s, have %s)\n" msgstr "Die Bibliothek Libksba is nicht aktuell (benötige %s, habe %s)\n" -#: sm/gpgsm.c:1178 +#: sm/gpgsm.c:1181 msgid "WARNING: program may create a core file!\n" msgstr "WARNUNG: Programm könnte eine core-dump-Datei schreiben!\n" -#: sm/gpgsm.c:1190 +#: sm/gpgsm.c:1193 msgid "WARNING: running with faked system time: " msgstr "WARNUNG: Ausführung mit gefälschter Systemzeit: " -#: sm/gpgsm.c:1216 +#: sm/gpgsm.c:1219 msgid "selected cipher algorithm is invalid\n" msgstr "Das ausgewählte Verschlüsselungsverfahren ist ungültig\n" -#: sm/gpgsm.c:1224 +#: sm/gpgsm.c:1227 msgid "selected digest algorithm is invalid\n" msgstr "Das ausgewählte Hashverfahren ist ungültig\n" -#: sm/gpgsm.c:1254 +#: sm/gpgsm.c:1257 #, c-format msgid "can't sign using `%s': %s\n" msgstr "Signieren mit `%s' nicht möglich: %s\n" -#: sm/gpgsm.c:1418 +#: sm/gpgsm.c:1423 msgid "this command has not yet been implemented\n" msgstr "Diee Kommando wurde noch nicht implementiert\n" -#: sm/gpgsm.c:1641 sm/gpgsm.c:1674 +#: sm/gpgsm.c:1646 sm/gpgsm.c:1679 #, c-format msgid "can't open `%s': %s\n" msgstr "Datei `%s' kann nicht geöffnet werden: %s\n" @@ -1334,26 +1338,26 @@ msgstr "Komponente nicht gefunden" #: tools/gpgconf-comp.c:435 tools/gpgconf-comp.c:496 tools/gpgconf-comp.c:561 -#: tools/gpgconf-comp.c:614 tools/gpgconf-comp.c:677 +#: tools/gpgconf-comp.c:614 tools/gpgconf-comp.c:680 msgid "Options controlling the diagnostic output" msgstr "Optionen zur Einstellung Diagnoseausgaben" #: tools/gpgconf-comp.c:448 tools/gpgconf-comp.c:509 tools/gpgconf-comp.c:574 -#: tools/gpgconf-comp.c:627 tools/gpgconf-comp.c:700 +#: tools/gpgconf-comp.c:627 tools/gpgconf-comp.c:703 msgid "Options controlling the configuration" msgstr "Optionen zur Einstellung der Konfiguration" #: tools/gpgconf-comp.c:455 tools/gpgconf-comp.c:532 tools/gpgconf-comp.c:581 -#: tools/gpgconf-comp.c:634 tools/gpgconf-comp.c:707 +#: tools/gpgconf-comp.c:637 tools/gpgconf-comp.c:710 msgid "Options useful for debugging" msgstr "Nützliche Optionen zum Debuggen" #: tools/gpgconf-comp.c:460 tools/gpgconf-comp.c:537 tools/gpgconf-comp.c:586 -#: tools/gpgconf-comp.c:639 tools/gpgconf-comp.c:715 +#: tools/gpgconf-comp.c:642 tools/gpgconf-comp.c:718 msgid "|FILE|write server mode logs to FILE" msgstr "|DATEI|Schreibe im Servermodus Logs auf DATEI" -#: tools/gpgconf-comp.c:468 tools/gpgconf-comp.c:542 tools/gpgconf-comp.c:647 +#: tools/gpgconf-comp.c:468 tools/gpgconf-comp.c:542 tools/gpgconf-comp.c:650 msgid "Options controlling the security" msgstr "Optionen zur Einstellung der Sicherheit" @@ -1361,19 +1365,23 @@ msgid "Configuration for Keyservers" msgstr "Konfiguration der Schlüsselserver" -#: tools/gpgconf-comp.c:690 +#: tools/gpgconf-comp.c:693 msgid "Options controlling the format of the output" msgstr "Optionen zum Einstellen der Ausgabeformate" -#: tools/gpgconf-comp.c:726 +#: tools/gpgconf-comp.c:729 msgid "Options controlling the interactivity and enforcement" msgstr "Optionen zur Einstellung der Interaktivität und Geltendmachung" -#: tools/gpgconf-comp.c:736 +#: tools/gpgconf-comp.c:739 +msgid "Configuration for HTTP servers" +msgstr "Konfiguration für HTTP Server" + +#: tools/gpgconf-comp.c:752 msgid "Configuration of LDAP servers to use" msgstr "Konfiguration der zu nutzenden LDAP-Server" -#: tools/gpgconf-comp.c:761 +#: tools/gpgconf-comp.c:789 msgid "Configuration for OCSP" msgstr "Konfiguration zu OCSP" Index: gnupg/tools/ChangeLog diff -u gnupg/tools/ChangeLog:1.25.2.57 gnupg/tools/ChangeLog:1.25.2.58 --- gnupg/tools/ChangeLog:1.25.2.57 Wed Nov 24 11:43:53 2004 +++ gnupg/tools/ChangeLog Wed Nov 24 15:50:20 2004 @@ -1,7 +1,7 @@ 2004-11-24 Werner Koch - * gpgconf-comp.c : Add --ignore-http-dp and - --ignore-ldap-dp. + * gpgconf-comp.c : Add --ignore-http-dp, --ignore-ldap-dp + and --ignore-ocsp-service-url. 2004-11-23 Werner Koch Index: gnupg/tools/gpgconf-comp.c diff -u gnupg/tools/gpgconf-comp.c:1.1.2.45 gnupg/tools/gpgconf-comp.c:1.1.2.46 --- gnupg/tools/gpgconf-comp.c:1.1.2.45 Wed Nov 24 11:43:53 2004 +++ gnupg/tools/gpgconf-comp.c Wed Nov 24 15:50:20 2004 @@ -790,6 +790,9 @@ { "allow-ocsp", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, "dirmngr", "allow sending OCSP requests", GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, + { "ignore-ocsp-servic-url", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + "dirmngr", "ignore certificate contained OCSP service URLs", + GC_ARG_TYPE_NONE, GC_BACKEND_DIRMNGR }, { "ocsp-responder", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, "dirmngr", "|URL|use OCSP responder at URL", GC_ARG_TYPE_STRING, GC_BACKEND_DIRMNGR }, From cvs at cvs.gnupg.org Wed Nov 24 17:13:59 2004 From: cvs at cvs.gnupg.org (cvs user werner) Date: Wed Nov 24 17:14:05 2004 Subject: libassuan (NEWS) Message-ID: Date: Wednesday, November 24, 2004 @ 17:13:59 Author: werner Path: /cvs/gnupg/libassuan Modified: NEWS Small API update and Windows fixes ------+ NEWS | 1 + 1 files changed, 1 insertion(+) From cvs at cvs.gnupg.org Wed Nov 24 17:13:59 2004 From: cvs at cvs.gnupg.org (cvs user werner) Date: Wed Nov 24 17:14:14 2004 Subject: libassuan/src (4 files) Message-ID: Date: Wednesday, November 24, 2004 @ 17:13:59 Author: werner Path: /cvs/gnupg/libassuan/src Modified: ChangeLog assuan-handler.c assuan-socket.c assuan.h Small API update and Windows fixes ------------------+ ChangeLog | 8 ++++++++ assuan-handler.c | 12 ++++++++---- assuan-socket.c | 10 +++++----- assuan.h | 4 ++-- 4 files changed, 23 insertions(+), 11 deletions(-) From cvs at cvs.gnupg.org Wed Nov 24 17:49:33 2004 From: cvs at cvs.gnupg.org (cvs user werner) Date: Wed Nov 24 17:49:38 2004 Subject: libassuan/src (6 files) Message-ID: Date: Wednesday, November 24, 2004 @ 17:49:33 Author: werner Path: /cvs/gnupg/libassuan/src Modified: ChangeLog assuan-defs.h assuan-domain-connect.c assuan-logging.c assuan-pipe-connect.c assuan-socket-connect.c * assuan-logging.c (_assuan_log_printf): New. * assuan-domain-connect.c (LOG): Removed and replaced all callers by _assuan_log_printf. This is needed for C89 and gcc 2.95 which both don't have C99 style variable arg macros. * assuan-pipe-connect.c (LOG): Ditto. * assuan-socket-connect.c (LOG): Ditto. * assuan-socket.c[!_WIN32]: Fixed includes. -------------------------+ ChangeLog | 7 +++++++ assuan-defs.h | 7 +++++++ assuan-domain-connect.c | 42 +++++++++++++++++------------------------- assuan-logging.c | 24 +++++++++++++++++++++++- assuan-pipe-connect.c | 22 ++++++++++++---------- assuan-socket-connect.c | 18 +++++------------- 6 files changed, 71 insertions(+), 49 deletions(-) From cvs at cvs.gnupg.org Wed Nov 24 17:56:53 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Wed Nov 24 17:56:55 2004 Subject: dirmngr/src (b64enc.c) Message-ID: Date: Wednesday, November 24, 2004 @ 18:03:40 Author: wk Path: /cvs/dirmngr/dirmngr/src Modified: b64enc.c Use standard malloc ----------+ b64enc.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) Index: dirmngr/src/b64enc.c diff -u dirmngr/src/b64enc.c:1.1 dirmngr/src/b64enc.c:1.2 --- dirmngr/src/b64enc.c:1.1 Tue Nov 23 14:20:44 2004 +++ dirmngr/src/b64enc.c Wed Nov 24 18:03:40 2004 @@ -54,7 +54,7 @@ state->flags |= B64ENC_NO_LINEFEEDS; else if (title) { - state->title = xtrystrdup (title); + state->title = strdup (title); if (!state->title) return gpg_error_from_errno (errno); } @@ -204,7 +204,7 @@ cleanup: if (state->title) { - xfree (state->title); + free (state->title); state->title = NULL; } state->fp = NULL; From cvs at cvs.gnupg.org Wed Nov 24 18:12:38 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Wed Nov 24 18:12:44 2004 Subject: dirmngr/src (ChangeLog ldap.c) Message-ID: Date: Wednesday, November 24, 2004 @ 18:19:25 Author: wk Path: /cvs/dirmngr/dirmngr/src Modified: ChangeLog ldap.c fixed name of ldap wrapper -----------+ ChangeLog | 5 +++++ ldap.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) Index: dirmngr/src/ChangeLog diff -u dirmngr/src/ChangeLog:1.28 dirmngr/src/ChangeLog:1.29 --- dirmngr/src/ChangeLog:1.28 Wed Nov 24 15:44:01 2004 +++ dirmngr/src/ChangeLog Wed Nov 24 18:19:25 2004 @@ -1,5 +1,10 @@ 2004-11-24 Werner Koch + * ldap.c (ldap_wrapper): Fixed default name of the ldap wrapper. + + * b64enc.c (b64enc_start, b64enc_finish): Use standard strdup/free + to manage memory. + * dirmngr.c: New options --ignore-http-dp, --ignore-ldap-dp and --ignore-ocsp-service-url. * crlcache.c (crl_cache_reload_crl): Implement them. Index: dirmngr/src/ldap.c diff -u dirmngr/src/ldap.c:1.38 dirmngr/src/ldap.c:1.39 --- dirmngr/src/ldap.c:1.38 Wed Nov 24 13:25:53 2004 +++ dirmngr/src/ldap.c Wed Nov 24 18:19:25 2004 @@ -575,7 +575,7 @@ int fd; if (!opt.ldap_wrapper_program || !*opt.ldap_wrapper_program) - pgmname = DIRMNGR_LIBEXECDIR "/ldap_wrapper"; + pgmname = DIRMNGR_LIBEXECDIR "/dirmngr_ldap"; else pgmname = opt.ldap_wrapper_program; From cvs at cvs.gnupg.org Thu Nov 25 04:41:48 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Thu Nov 25 04:41:51 2004 Subject: gnupg/g10 (ChangeLog trustdb.c) Message-ID: Date: Thursday, November 25, 2004 @ 04:48:35 Author: dshaw Path: /cvs/gnupg/gnupg/g10 Modified: ChangeLog trustdb.c * trustdb.c (uid_trust_string_fixed): Use a string that can be atoi-ed, but also has a comment for the translator. -----------+ ChangeLog | 3 +++ trustdb.c | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.641 gnupg/g10/ChangeLog:1.642 --- gnupg/g10/ChangeLog:1.641 Wed Nov 24 06:25:02 2004 +++ gnupg/g10/ChangeLog Thu Nov 25 04:48:34 2004 @@ -1,5 +1,8 @@ 2004-11-24 David Shaw + * trustdb.c (uid_trust_string_fixed): Use a string that can be + atoi-ed, but also has a comment for the translator. + * trustdb.h, trustdb.c (uid_trust_string_fixed): New. Return a fixed-size translatable string similar to trust_value_to_string. This allows for easier lining up of displays. Index: gnupg/g10/trustdb.c diff -u gnupg/g10/trustdb.c:1.132 gnupg/g10/trustdb.c:1.133 --- gnupg/g10/trustdb.c:1.132 Wed Nov 24 06:25:03 2004 +++ gnupg/g10/trustdb.c Thu Nov 25 04:48:34 2004 @@ -493,13 +493,14 @@ trust_value_to_string(), but are a fixed length. This is needed to make attractive information listings where columns line up properly. The value "10" should be the length of the strings you - choose to translate to. This is the length in printable - columns. */ + choose to translate to. This is the length in printable columns. + It gets passed to atoi() so everything after the number is + essentially a comment and need not be translated. */ const char * uid_trust_string_fixed(PKT_public_key *key,PKT_user_id *uid) { if(!key && !uid) - return _("10"); + return _("10 translator see trustdb.c:uid_trust_string_fixed"); else if(uid->is_revoked) return _("[ revoked]"); else if(uid->is_expired) From cvs at cvs.gnupg.org Thu Nov 25 04:51:55 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Thu Nov 25 04:52:09 2004 Subject: gnupg/g10 (ChangeLog export.c options.h) Message-ID: Date: Thursday, November 25, 2004 @ 04:58:42 Author: dshaw Path: /cvs/gnupg/gnupg/g10 Modified: ChangeLog export.c options.h * options.h, export.c (parse_export_options, do_export_stream): Add "export-minimal" option to disregard any sigs except selfsigs. -----------+ ChangeLog | 3 +++ export.c | 58 +++++++++++++++++++++++++++++++++++++--------------------- options.h | 5 ++++- 3 files changed, 44 insertions(+), 22 deletions(-) Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.642 gnupg/g10/ChangeLog:1.643 --- gnupg/g10/ChangeLog:1.642 Thu Nov 25 04:48:34 2004 +++ gnupg/g10/ChangeLog Thu Nov 25 04:58:42 2004 @@ -1,5 +1,8 @@ 2004-11-24 David Shaw + * options.h, export.c (parse_export_options, do_export_stream): + Add "export-minimal" option to disregard any sigs except selfsigs. + * trustdb.c (uid_trust_string_fixed): Use a string that can be atoi-ed, but also has a comment for the translator. Index: gnupg/g10/export.c diff -u gnupg/g10/export.c:1.41 gnupg/g10/export.c:1.42 --- gnupg/g10/export.c:1.41 Thu Oct 28 03:58:01 2004 +++ gnupg/g10/export.c Thu Nov 25 04:58:42 2004 @@ -48,6 +48,7 @@ {"include-local-sigs",EXPORT_INCLUDE_LOCAL_SIGS,NULL}, {"include-attributes",EXPORT_INCLUDE_ATTRIBUTES,NULL}, {"include-sensitive-revkeys",EXPORT_INCLUDE_SENSITIVE_REVKEYS,NULL}, + {"export-minimal",EXPORT_MINIMAL,NULL}, {NULL,0,NULL} /* add tags for include revoked and disabled? */ }; @@ -140,6 +141,7 @@ KEYDB_SEARCH_DESC *desc = NULL; KEYDB_HANDLE kdbhd; STRLIST sl; + u32 pk_keyid[2]; *any = 0; init_packet( &pkt ); @@ -193,8 +195,7 @@ goto leave; } - node=find_kbnode( keyblock, PKT_SECRET_KEY ); - if(node) + if((node=find_kbnode(keyblock,PKT_SECRET_KEY))) { PKT_secret_key *sk=node->pkt->pkt.secret_key; @@ -216,6 +217,9 @@ continue; } } + else if((options&EXPORT_MINIMAL) + && (node=find_kbnode(keyblock,PKT_PUBLIC_KEY))) + keyid_from_pk(node->pkt->pkt.public_key,pk_keyid); /* and write it */ for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) { @@ -301,28 +305,40 @@ continue; } - if( node->pkt->pkttype == PKT_SIGNATURE ) { - /* do not export packets which are marked as not exportable */ - if( !(options&EXPORT_INCLUDE_LOCAL_SIGS) && - !node->pkt->pkt.signature->flags.exportable ) - continue; /* not exportable */ - - /* Do not export packets with a "sensitive" revocation - key unless the user wants us to. Note that we do - export these when issuing the actual revocation (see - revoke.c). */ - if( !(options&EXPORT_INCLUDE_SENSITIVE_REVKEYS) && - node->pkt->pkt.signature->revkey ) { - int i; + if( node->pkt->pkttype == PKT_SIGNATURE ) + { + /* If we have minimal-export turned on, do not include + any signature that isn't a selfsig. Note that this + only applies to uid sigs (0x10, 0x11, 0x12, and + 0x13). A designated revocation is not stripped. */ + if((options&EXPORT_MINIMAL) + && IS_UID_SIG(node->pkt->pkt.signature) + && (node->pkt->pkt.signature->keyid[0]!=pk_keyid[0] + || node->pkt->pkt.signature->keyid[1]!=pk_keyid[1])) + continue; - for(i=0;ipkt->pkt.signature->numrevkeys;i++) - if(node->pkt->pkt.signature->revkey[i]->class & 0x40) - break; + /* do not export packets which are marked as not exportable */ + if(!(options&EXPORT_INCLUDE_LOCAL_SIGS) + && !node->pkt->pkt.signature->flags.exportable) + continue; /* not exportable */ + + /* Do not export packets with a "sensitive" revocation + key unless the user wants us to. Note that we do + export these when issuing the actual revocation + (see revoke.c). */ + if(!(options&EXPORT_INCLUDE_SENSITIVE_REVKEYS) + && node->pkt->pkt.signature->revkey) + { + int i; - if(ipkt->pkt.signature->numrevkeys) - continue; + for(i=0;ipkt->pkt.signature->numrevkeys;i++) + if(node->pkt->pkt.signature->revkey[i]->class & 0x40) + break; + + if(ipkt->pkt.signature->numrevkeys) + continue; + } } - } /* Don't export attribs? */ if( !(options&EXPORT_INCLUDE_ATTRIBUTES) && Index: gnupg/g10/options.h diff -u gnupg/g10/options.h:1.126 gnupg/g10/options.h:1.127 --- gnupg/g10/options.h:1.126 Thu Oct 21 21:18:47 2004 +++ gnupg/g10/options.h Thu Nov 25 04:58:42 2004 @@ -241,7 +241,9 @@ #define PGP7 (opt.compliance==CO_PGP7) #define PGP8 (opt.compliance==CO_PGP8) -/* Various option flags */ +/* Various option flags. Note that there should be no common string + names between the IMPORT_ and EXPORT_ flags as they can be mixed in + the keyserver-options option. */ #define IMPORT_ALLOW_LOCAL_SIGS (1<<0) #define IMPORT_REPAIR_PKS_SUBKEY_BUG (1<<1) @@ -252,6 +254,7 @@ #define EXPORT_INCLUDE_LOCAL_SIGS (1<<0) #define EXPORT_INCLUDE_ATTRIBUTES (1<<1) #define EXPORT_INCLUDE_SENSITIVE_REVKEYS (1<<2) +#define EXPORT_MINIMAL (1<<3) #define LIST_SHOW_PHOTOS (1<<0) #define LIST_SHOW_POLICY_URLS (1<<1) From cvs at cvs.gnupg.org Thu Nov 25 12:30:47 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Thu Nov 25 12:30:52 2004 Subject: dirmngr (AUTHORS NEWS README doc/dirmngr.texi po/de.po) Message-ID: Date: Thursday, November 25, 2004 @ 12:37:38 Author: wk Path: /cvs/dirmngr/dirmngr Modified: AUTHORS NEWS README doc/dirmngr.texi po/de.po Documentation updates - ready for a release ------------------+ AUTHORS | 4 +- NEWS | 4 +- README | 48 +++++++++++++++++++----- doc/dirmngr.texi | 105 ++++++++++++++++++++++++++++++++++++++++++++++++----- po/de.po | 4 +- 5 files changed, 141 insertions(+), 24 deletions(-) Index: dirmngr/AUTHORS diff -u dirmngr/AUTHORS:1.4 dirmngr/AUTHORS:1.5 --- dirmngr/AUTHORS:1.4 Fri Dec 12 18:36:49 2003 +++ dirmngr/AUTHORS Thu Nov 25 12:37:38 2004 @@ -21,10 +21,10 @@ The actual code is under the GNU GPL, except for src/cdb.h and -src/cdblib.h which are in the opublic domain. +src/cdblib.h which are in the public domain. - Copyright 2003 g10 Code GmbH + Copyright 2003, 2004 g10 Code GmbH This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Index: dirmngr/NEWS diff -u dirmngr/NEWS:1.29 dirmngr/NEWS:1.30 --- dirmngr/NEWS:1.29 Wed Nov 24 13:25:53 2004 +++ dirmngr/NEWS Thu Nov 25 12:37:38 2004 @@ -2,8 +2,8 @@ ------------------------------------------------ * New option --daemon to start dirmngr as a system daemon. This - switched to the use of different directories and also does - certificate validation on its own. + switches to the use of different directories and also does + CRl signing certificate validation on its own. * New tool dirmngr-client. Index: dirmngr/README diff -u dirmngr/README:1.6 dirmngr/README:1.7 --- dirmngr/README:1.6 Tue Apr 6 10:24:58 2004 +++ dirmngr/README Thu Nov 25 12:37:38 2004 @@ -1,21 +1,49 @@ -DirMngr + Dirmngr - X.509 Directory Manager + ------------------------------------- + Version 0.9.0 -===> Please see the info manual dirmngr.info <==== + Intro + ----- -The subdirectory jnlib is copied from GnuPG 1.9.x + Dirmngr is a server for managing and downloading certificate + revocation lists (CRLs) for X.509 certificates and for downloading + the certificates themselves. Dirmngr also handles OCSP requests as + an alternative to CRLs. Dirmngr is either invoked internaly by + gpgsm (from gnupg 1.9) or when running as a system daemon trhough + the dirmngr-client tool. -Short note about the --ldapserverlist-file fileformat: + See the file COPYING for copyright and warranty information. See + the file AUTHORS for contact addresses and code history. -The default file is $GNUPGHOME/dirmngr_ldapservers.conf -Each line contains a server formatted like this + Installation + ------------ + Please read the file INSTALL. Here is a quick summary: -# A '#' in the first column marks the line as a comment -host:port:user:password:base + 1) Unpack the tarball. With GNU tar you can do it this way: + "tar xzvf dirmngr-x.y.z.tar.gz" -base is the base DN used for searching in queries that dont specify a base -themselves. + 2) "cd dirmngr-x.y.z" + + 3) "./configure --sysconfdir=/etc --localstatedir=/var" + The two options make sure that the configuration data will + not be search under /usr/local/etc and that variable data will + be stored at a standard place too. + + 4) "make" + + 5) "make install" (you probably need to become root first) + + 6) You end up with a a dirmngr and dirmngr-client binary in + /usr/local/bin. Some other files are also installed for + internal use. + + If you are using dirmngr as part of gnupg 1.9 you are done now. + If you want to install it as a system daemon, please see the + manual by running the command "info dirmngr" + + Index: dirmngr/doc/dirmngr.texi diff -u dirmngr/doc/dirmngr.texi:1.17 dirmngr/doc/dirmngr.texi:1.18 --- dirmngr/doc/dirmngr.texi:1.17 Wed Nov 24 13:25:53 2004 +++ dirmngr/doc/dirmngr.texi Thu Nov 25 12:37:38 2004 @@ -1,4 +1,4 @@ -\input texinfo @c -*-texinfo-*- +\input texinfo @c -*-texinfo-*- @c Copyright (C) 2002 Klarälvdalens Datakonsult AB @c Copyright (c) 2004 g10 Code GmbH @c This is part of the Dirmngr manual. @@ -104,15 +104,16 @@ @c man begin DESCRIPTION -Dirmngr is a server for managing and downloading certificate -revocation lists (CRLs) for X509 certificates and for downloading the -certificates themselves. Dirmngr also handles OCSP requests as an -alternative to CRLs. Dirmngr is usually invoked by gpgsm and in -general not used directly. +Dirmngr is a server for managing and downloading certificate revocation +lists (CRLs) for X.509 certificates and for downloading the certificates +themselves. Dirmngr also handles OCSP requests as an alternative to +CRLs. Dirmngr is either invoked internally by gpgsm (from gnupg 1.9) or +when running as a system daemon through the @command{dirmngr-client} tool. @c man end @menu +* Installation:: How to install Dirmngr. * Dirmngr Commands:: List of all commands. * Dirmngr Options:: List of all options. * Dirmngr Signals:: Use of signals. @@ -128,6 +129,94 @@ * History:: Change history of this document. @end menu + +@node Installation +@chapter How to install Dirmngr. + +Installation is decribed in the file @file{INSTALL} and given that you +are already reading this documentation we can only give some hints on +further configuration. If you plan to use dirmngr as a system daemon +and not only as a part of gnupg 1.9, you should read on. + +If @command{dirmngr} is started in system daemon mode, it uses a +directory layout as common for system daemon and does not make use of +the drefault @file{~/.gnupg} directory. To comply with the rules on +GNU/Linux systems you should have build time configured +@command{dirmngr} using: + +@example +./configure --sysconfdir=/etc --localstatedir=/var +@end example + +This is to make sure that the configuration file is searched in the +directory @file{/etc/dirmngr} and the variable data below @file{/var}; +the default would be to install them in the @file{/usr/local} too where +the binaries get installed. If you selected to use the +@option{--prefix=/} you obviously don't need those option as they are +the default then. Further on we assume that you used these options. + +Dirmngr makes use of several directories when running in daemon mode: + +@table @file + +@item /etc/dirmngr +This is where all the configuration files are expected by default. + +@item /etc/dirmngr/trusted-certs +This directory should be filled with certificates of Root CAs you are +trusting in checking the CRLS and signing OCSP Reponses. Usually these +are the same certificates you use with the applications making use of +dirmngr. It is expected that each of these certificates files contain +exactly one @acronym{DER} encoded certificate in a file with the suffix +@file{.crt}. @command{dirmngr} reads those certificates on startup and +when given a SIGHUP. Certificates which are not readable or do not make +up a proper X.509 certificate are ignored; see the log file for details. + +@item /var/lib/dirmngr/extra-certs +This directory may contain extra certificates which are preloaded into +the interal cache on startup. This is convenient in cases you have a +couple intermediate CA certificates or certificates ususally used to +sign OCSP reponses. These certificates are first tried before going out +to the net to look for them. These certificates must also be +@acronym{DER} encoded and suffixed with @file{.crt}. + +@item /var/run/dirmngr +This directory keeps the socket file for accsing @command{dirmngr} services. +The name of the socket file will be @file{socket}. Make sure that this +directory has the proper permissions to let @command{dirmngr} create the +socket file and that eligible users may read and write to that socket. + +@item /var/cache/dirmngr/crls.d +This directory is used to store cached CRLs. The @file{crls.d} part +will be created by dirmngr if it does not exists but you need to make +sure that the upper directory exists. + +@end table + +To be able to see what's going on you should create the configure file +@file{/etc/dirmngr/dirmngr.conf} with at least one line: + +@example +log-file /var/log/dirmngr/dirmngr.log +@end example + +To be able to perform OCSP requests you probably want to add the line: + +@example +allow-ocsp +@end example + +Now you may start dirmngr as a system daemon using: + +@example +dirmngr --daemon +@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. + + + @c man begin COMMANDS @node Dirmngr Commands @@ -349,7 +438,7 @@ value for @var{file} is @file{dirmngr_ldapservers.conf} or @file{ldapservers.conf} when running in @option{--daemon} mode. -The server list file contains one LDAP server per line in the format +This server list file contains one LDAP server per line in the format @sc{hostname:port:username:password:base_dn} @@ -668,7 +757,7 @@ dirmngr and test whether a certificate has been revoked --- either by being listed in the corresponding CRL or by running the OCSP protocol. If no dirmngr is running, a new instances will be started but this is -in general not a good idea due tom the huge performace overhead. +in general not a good idea due to the huge performance overhead. @noindent The usual way to run this tool is either: Index: dirmngr/po/de.po diff -u dirmngr/po/de.po:1.8 dirmngr/po/de.po:1.9 --- dirmngr/po/de.po:1.8 Wed Nov 24 15:44:01 2004 +++ dirmngr/po/de.po Thu Nov 25 12:37:38 2004 @@ -8,7 +8,7 @@ "Project-Id-Version: dirmngr 0.9.0\n" "Report-Msgid-Bugs-To: gpa-dev@gnupg.org\n" "POT-Creation-Date: 2004-11-24 15:35+0100\n" -"PO-Revision-Date: 2004-11-24 15:37+0100\n" +"PO-Revision-Date: 2004-11-24 18:15+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: de\n" "MIME-Version: 1.0\n" @@ -1033,7 +1033,7 @@ #: src/ldap.c:314 #, c-format msgid "ldap wrapper %d ready: exit status %d\n" -msgstr "LDAP Wrapper %d fertig: Beendigunsstatus %d\n" +msgstr "LDAP Wrapper %d fertig: Beendigungsstatus %d\n" #: src/ldap.c:327 #, c-format From cvs at cvs.gnupg.org Thu Nov 25 13:53:43 2004 From: cvs at cvs.gnupg.org (cvs user werner) Date: Thu Nov 25 13:53:49 2004 Subject: libassuan (ChangeLog NEWS configure.ac) Message-ID: Date: Thursday, November 25, 2004 @ 13:53:43 Author: werner Path: /cvs/gnupg/libassuan Modified: ChangeLog NEWS configure.ac Released 0.6.8 --------------+ ChangeLog | 4 ++++ NEWS | 4 +++- configure.ac | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) From cvs at cvs.gnupg.org Thu Nov 25 13:59:01 2004 From: cvs at cvs.gnupg.org (cvs user werner) Date: Thu Nov 25 13:59:08 2004 Subject: libassuan (NEWS configure.ac) Message-ID: Date: Thursday, November 25, 2004 @ 13:59:01 Author: werner Path: /cvs/gnupg/libassuan Modified: NEWS configure.ac Post release preps --------------+ NEWS | 5 +++++ configure.ac | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) From cvs at cvs.gnupg.org Thu Nov 25 14:12:15 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Thu Nov 25 14:12:18 2004 Subject: dirmngr (ChangeLog configure.ac src/ChangeLog src/Makefile.am) Message-ID: Date: Thursday, November 25, 2004 @ 14:19:07 Author: wk Path: /cvs/dirmngr/dirmngr Modified: ChangeLog configure.ac src/ChangeLog src/Makefile.am config changes -----------------+ ChangeLog | 5 +++++ configure.ac | 4 ++-- src/ChangeLog | 5 +++++ src/Makefile.am | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) Index: dirmngr/ChangeLog diff -u dirmngr/ChangeLog:1.77 dirmngr/ChangeLog:1.78 --- dirmngr/ChangeLog:1.77 Fri Nov 19 16:27:28 2004 +++ dirmngr/ChangeLog Thu Nov 25 14:19:07 2004 @@ -1,3 +1,8 @@ +2004-11-25 Werner Koch + + * configure.ac: Reverted to require autoconf/make 2.57/1.7.6 as + they still seem to work alhough I am using newer versions. + 2004-11-19 Werner Koch * configure.ac: Require libassuan 0.6.8. Index: dirmngr/configure.ac diff -u dirmngr/configure.ac:1.62 dirmngr/configure.ac:1.63 --- dirmngr/configure.ac:1.62 Fri Nov 19 16:27:28 2004 +++ dirmngr/configure.ac Thu Nov 25 14:19:07 2004 @@ -19,8 +19,8 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA # Process this file with autoconf to produce a configure script. -AC_PREREQ(2.59) -min_automake_version="1.7.9" +AC_PREREQ(2.57) +min_automake_version="1.7.6" AC_INIT(dirmngr, 0.9.0-cvs, gpa-dev@gnupg.org) Index: dirmngr/src/ChangeLog diff -u dirmngr/src/ChangeLog:1.29 dirmngr/src/ChangeLog:1.30 --- dirmngr/src/ChangeLog:1.29 Wed Nov 24 18:19:25 2004 +++ dirmngr/src/ChangeLog Thu Nov 25 14:19:07 2004 @@ -1,3 +1,8 @@ +2004-11-25 Werner Koch + + * Makefile.am (dirmngr_ldap_CFLAGS): Added GPG_ERROR_CFLAGS. + Noted by Bernhard Herzog. + 2004-11-24 Werner Koch * ldap.c (ldap_wrapper): Fixed default name of the ldap wrapper. Index: dirmngr/src/Makefile.am diff -u dirmngr/src/Makefile.am:1.20 dirmngr/src/Makefile.am:1.21 --- dirmngr/src/Makefile.am:1.20 Tue Nov 23 14:20:44 2004 +++ dirmngr/src/Makefile.am Thu Nov 25 14:19:07 2004 @@ -50,7 +50,7 @@ dirmngr_ldap_SOURCES = dirmngr_ldap.c i18n.h util.h \ no-libgcrypt.c no-libgcrypt.h -dirmngr_ldap_CFLAGS = $(LDAP_INCS) +dirmngr_ldap_CFLAGS = $(LDAP_INCS) $(GPG_ERROR_CFLAGS) dirmngr_ldap_LDFLAGS = $(LDAP_RPATH) dirmngr_ldap_LDADD = ../jnlib/libjnlib.a $(LIBOBJS) $(GPG_ERROR_LIBS) \ $(LDAP_LIBS) From cvs at cvs.gnupg.org Fri Nov 26 16:44:41 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Fri Nov 26 16:44:45 2004 Subject: gnupg/g10 (ChangeLog export.c g10.c import.c options.h) Message-ID: Date: Friday, November 26, 2004 @ 16:51:37 Author: dshaw Path: /cvs/gnupg/gnupg/g10 Modified: ChangeLog export.c g10.c import.c options.h * options.h, export.c (parse_export_options, do_export_stream), import.c (parse_import_options, import_keys_internal): Make the import-options and export-options distinct since they can be mixed together as part of keyserver-options. -----------+ ChangeLog | 7 +++++++ export.c | 16 ++++++++++------ g10.c | 6 +++--- import.c | 12 +++++++----- options.h | 10 +++++----- 5 files changed, 32 insertions(+), 19 deletions(-) Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.643 gnupg/g10/ChangeLog:1.644 --- gnupg/g10/ChangeLog:1.643 Thu Nov 25 04:58:42 2004 +++ gnupg/g10/ChangeLog Fri Nov 26 16:51:37 2004 @@ -1,3 +1,10 @@ +2004-11-26 David Shaw + + * options.h, export.c (parse_export_options, do_export_stream), + import.c (parse_import_options, import_keys_internal): Make the + import-options and export-options distinct since they can be mixed + together as part of keyserver-options. + 2004-11-24 David Shaw * options.h, export.c (parse_export_options, do_export_stream): Index: gnupg/g10/export.c diff -u gnupg/g10/export.c:1.42 gnupg/g10/export.c:1.43 --- gnupg/g10/export.c:1.42 Thu Nov 25 04:58:42 2004 +++ gnupg/g10/export.c Fri Nov 26 16:51:37 2004 @@ -45,10 +45,14 @@ { struct parse_options export_opts[]= { - {"include-local-sigs",EXPORT_INCLUDE_LOCAL_SIGS,NULL}, - {"include-attributes",EXPORT_INCLUDE_ATTRIBUTES,NULL}, - {"include-sensitive-revkeys",EXPORT_INCLUDE_SENSITIVE_REVKEYS,NULL}, + {"export-local-sigs",EXPORT_LOCAL_SIGS,NULL}, + {"export-attributes",EXPORT_ATTRIBUTES,NULL}, + {"export-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL}, {"export-minimal",EXPORT_MINIMAL,NULL}, + /* Aliases for backward compatibility */ + {"include-local-sigs",EXPORT_LOCAL_SIGS,NULL}, + {"include-attributes",EXPORT_ATTRIBUTES,NULL}, + {"include-sensitive-revkeys",EXPORT_SENSITIVE_REVKEYS,NULL}, {NULL,0,NULL} /* add tags for include revoked and disabled? */ }; @@ -318,7 +322,7 @@ continue; /* do not export packets which are marked as not exportable */ - if(!(options&EXPORT_INCLUDE_LOCAL_SIGS) + if(!(options&EXPORT_LOCAL_SIGS) && !node->pkt->pkt.signature->flags.exportable) continue; /* not exportable */ @@ -326,7 +330,7 @@ key unless the user wants us to. Note that we do export these when issuing the actual revocation (see revoke.c). */ - if(!(options&EXPORT_INCLUDE_SENSITIVE_REVKEYS) + if(!(options&EXPORT_SENSITIVE_REVKEYS) && node->pkt->pkt.signature->revkey) { int i; @@ -341,7 +345,7 @@ } /* Don't export attribs? */ - if( !(options&EXPORT_INCLUDE_ATTRIBUTES) && + if( !(options&EXPORT_ATTRIBUTES) && node->pkt->pkttype == PKT_USER_ID && node->pkt->pkt.user_id->attrib_data ) { /* Skip until we get to something that is not an attrib Index: gnupg/g10/g10.c diff -u gnupg/g10/g10.c:1.289 gnupg/g10/g10.c:1.290 --- gnupg/g10/g10.c:1.289 Thu Nov 18 17:01:08 2004 +++ gnupg/g10/g10.c Fri Nov 26 16:51:37 2004 @@ -1655,9 +1655,9 @@ opt.force_v3_sigs = 1; opt.escape_from = 1; opt.import_options=IMPORT_SK2PK; - opt.export_options=EXPORT_INCLUDE_ATTRIBUTES; + opt.export_options=EXPORT_ATTRIBUTES; opt.keyserver_options.import_options=IMPORT_REPAIR_PKS_SUBKEY_BUG; - opt.keyserver_options.export_options=EXPORT_INCLUDE_ATTRIBUTES; + opt.keyserver_options.export_options=EXPORT_ATTRIBUTES; opt.keyserver_options.options= KEYSERVER_INCLUDE_SUBKEYS|KEYSERVER_INCLUDE_REVOKED|KEYSERVER_TRY_DNS_SRV|KEYSERVER_HONOR_KEYSERVER_URL; opt.verify_options= @@ -3254,7 +3254,7 @@ break; case aFastImport: - opt.import_options |= IMPORT_FAST_IMPORT; + opt.import_options |= IMPORT_FAST; case aImport: import_keys( argc? argv:NULL, argc, NULL, opt.import_options ); break; Index: gnupg/g10/import.c diff -u gnupg/g10/import.c:1.116 gnupg/g10/import.c:1.117 --- gnupg/g10/import.c:1.116 Thu Oct 14 12:48:15 2004 +++ gnupg/g10/import.c Fri Nov 26 16:51:37 2004 @@ -88,12 +88,14 @@ { struct parse_options import_opts[]= { - {"allow-local-sigs",IMPORT_ALLOW_LOCAL_SIGS,NULL}, - {"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL}, + {"import-local-sigs",IMPORT_LOCAL_SIGS,NULL}, {"repair-pks-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL}, - {"fast-import",IMPORT_FAST_IMPORT,NULL}, + {"fast-import",IMPORT_FAST,NULL}, {"convert-sk-to-pk",IMPORT_SK2PK,NULL}, {"merge-only",IMPORT_MERGE_ONLY,NULL}, + /* Aliases for backward compatibility */ + {"allow-local-sigs",IMPORT_LOCAL_SIGS,NULL}, + {"repair-hkp-subkey-bug",IMPORT_REPAIR_PKS_SUBKEY_BUG,NULL}, {NULL,0,NULL} }; @@ -195,7 +197,7 @@ that was other than a selfsig, or any revocation), then update/check the trustdb if the user specified by setting interactive or by not setting no-auto-check-trustdb */ - if (!(options&IMPORT_FAST_IMPORT) && trustdb_pending_check()) + if (!(options&IMPORT_FAST) && trustdb_pending_check()) { if (opt.interactive) update_trustdb(); @@ -1493,7 +1495,7 @@ delete_kbnode( node ); /* build_packet() can't handle this */ else if( node->pkt->pkttype == PKT_SIGNATURE && !node->pkt->pkt.signature->flags.exportable && - !(options&IMPORT_ALLOW_LOCAL_SIGS) && + !(options&IMPORT_LOCAL_SIGS) && seckey_available( node->pkt->pkt.signature->keyid ) ) { /* here we violate the rfc a bit by still allowing Index: gnupg/g10/options.h diff -u gnupg/g10/options.h:1.127 gnupg/g10/options.h:1.128 --- gnupg/g10/options.h:1.127 Thu Nov 25 04:58:42 2004 +++ gnupg/g10/options.h Fri Nov 26 16:51:37 2004 @@ -245,15 +245,15 @@ names between the IMPORT_ and EXPORT_ flags as they can be mixed in the keyserver-options option. */ -#define IMPORT_ALLOW_LOCAL_SIGS (1<<0) +#define IMPORT_LOCAL_SIGS (1<<0) #define IMPORT_REPAIR_PKS_SUBKEY_BUG (1<<1) -#define IMPORT_FAST_IMPORT (1<<2) +#define IMPORT_FAST (1<<2) #define IMPORT_SK2PK (1<<3) #define IMPORT_MERGE_ONLY (1<<4) -#define EXPORT_INCLUDE_LOCAL_SIGS (1<<0) -#define EXPORT_INCLUDE_ATTRIBUTES (1<<1) -#define EXPORT_INCLUDE_SENSITIVE_REVKEYS (1<<2) +#define EXPORT_LOCAL_SIGS (1<<0) +#define EXPORT_ATTRIBUTES (1<<1) +#define EXPORT_SENSITIVE_REVKEYS (1<<2) #define EXPORT_MINIMAL (1<<3) #define LIST_SHOW_PHOTOS (1<<0) From cvs at cvs.gnupg.org Fri Nov 26 17:18:01 2004 From: cvs at cvs.gnupg.org (cvs user werner) Date: Fri Nov 26 17:18:08 2004 Subject: libassuan/src (ChangeLog assuan-defs.h assuan-io.c) Message-ID: Date: Friday, November 26, 2004 @ 17:18:01 Author: werner Path: /cvs/gnupg/libassuan/src Modified: ChangeLog assuan-defs.h assuan-io.c Avoid warnings about unknown pragmas. ---------------+ ChangeLog | 4 ++++ assuan-defs.h | 8 +++++--- assuan-io.c | 14 ++++++++------ 3 files changed, 17 insertions(+), 9 deletions(-) From cvs at cvs.gnupg.org Fri Nov 26 17:20:09 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Fri Nov 26 17:20:11 2004 Subject: LIBGCRYPT-1-2-BRANCH libgcrypt (6 files) Message-ID: Date: Friday, November 26, 2004 @ 17:27:08 Author: wk Path: /cvs/libgcrypt/libgcrypt Tag: LIBGCRYPT-1-2-BRANCH Modified: src/ChangeLog src/ath.c src/ath.h src/gcrypt.h src/types.h tests/benchmark.c Avoid warning about double defined type byte and other hacks to let it build for W32 -------------------+ src/ChangeLog | 8 ++++++++ src/ath.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ src/ath.h | 24 ++++++++++++++++++++---- src/gcrypt.h | 12 ++++++++++++ src/types.h | 4 ++++ tests/benchmark.c | 10 ++++++++++ 6 files changed, 103 insertions(+), 4 deletions(-) Index: libgcrypt/src/ChangeLog diff -u libgcrypt/src/ChangeLog:1.151.2.7 libgcrypt/src/ChangeLog:1.151.2.8 --- libgcrypt/src/ChangeLog:1.151.2.7 Tue Nov 9 18:07:37 2004 +++ libgcrypt/src/ChangeLog Fri Nov 26 17:27:08 2004 @@ -1,3 +1,11 @@ +2004-11-26 Werner Koch + + * types.h [_WIN32]: Avoid warning about double defined type byte. + +2004-11-25 Werner Koch + + * ath.h [_WIN32]: Adjusted for modern mingw cross compiler. + 2004-11-09 Werner Koch * gcrypt.h: Removed 3 trailing commas from enums. Reported by Index: libgcrypt/src/ath.c diff -u libgcrypt/src/ath.c:1.7 libgcrypt/src/ath.c:1.7.2.1 --- libgcrypt/src/ath.c:1.7 Thu Mar 11 02:44:43 2004 +++ libgcrypt/src/ath.c Fri Nov 26 17:27:08 2004 @@ -30,11 +30,14 @@ # include #endif #include +#ifndef _WIN32 #include +#endif #include #include "ath.h" + /* The interface table. */ static struct ath_ops ops; @@ -227,13 +230,22 @@ ssize_t +#ifdef _WIN32 +ath_select (int nfd, void *rset, void *wset, void *eset, + struct timeval *timeout) +#else ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, struct timeval *timeout) +#endif { if (ops_set && ops.select) return (*ops.select) (nfd, rset, wset, eset, timeout); else +#ifdef _WIN32 + return -1; +#else return select (nfd, rset, wset, eset, timeout); +#endif } @@ -243,45 +255,82 @@ if (ops_set && ops.waitpid) return (*ops.waitpid) (pid, status, options); else +#ifdef _WIN32 + return -1; +#else return waitpid (pid, status, options); +#endif } int +#ifdef _WIN32 +ath_accept (int s, void *addr, int *length_ptr) +#else ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr) +#endif { if (ops_set && ops.accept) return (*ops.accept) (s, addr, length_ptr); else +#ifdef _WIN32 + return -1; +#else return accept (s, addr, length_ptr); +#endif } int +#ifdef _WIN32 +ath_connect (int s, void *addr, socklen_t length) +#else ath_connect (int s, struct sockaddr *addr, socklen_t length) +#endif { if (ops_set && ops.connect) return (*ops.connect) (s, addr, length); else +#ifdef _WIN32 + return -1; +#else return connect (s, addr, length); +#endif } int +#ifdef _WIN32 +ath_sendmsg (int s, const void *msg, int flags) +#else ath_sendmsg (int s, const struct msghdr *msg, int flags) +#endif { if (ops_set && ops.sendmsg) return (*ops.sendmsg) (s, msg, flags); else +#ifdef _WIN32 + return -1; +#else return sendmsg (s, msg, flags); +#endif } int +#ifdef _WIN32 +ath_recvmsg (int s, void *msg, int flags) +#else ath_recvmsg (int s, struct msghdr *msg, int flags) +#endif { if (ops_set && ops.recvmsg) return (*ops.recvmsg) (s, msg, flags); else +#ifdef _WIN32 + return -1; +#else return recvmsg (s, msg, flags); +#endif } + Index: libgcrypt/src/ath.h diff -u libgcrypt/src/ath.h:1.9 libgcrypt/src/ath.h:1.9.2.1 --- libgcrypt/src/ath.h:1.9 Thu Mar 11 02:44:43 2004 +++ libgcrypt/src/ath.h Fri Nov 26 17:27:08 2004 @@ -22,9 +22,6 @@ #define ATH_H #ifdef _WIN32 -#warning We need to replace these hacks by cleaner code. -typedef int ssize_t; -typedef int pid_t; #include #else #include @@ -78,6 +75,15 @@ int (*mutex_unlock) (void *priv); ssize_t (*read) (int fd, void *buf, size_t nbytes); ssize_t (*write) (int fd, const void *buf, size_t nbytes); +#ifdef _WIN32 + ssize_t (*select) (int nfd, void *rset, void *wset, void *eset, + struct timeval *timeout); + ssize_t (*waitpid) (pid_t pid, int *status, int options); + int (*accept) (int s, void *addr, int *length_ptr); + int (*connect) (int s, void *addr, socklen_t length); + int (*sendmsg) (int s, const void *msg, int flags); + int (*recvmsg) (int s, void *msg, int flags); +#else ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, struct timeval *timeout); ssize_t (*waitpid) (pid_t pid, int *status, int options); @@ -85,6 +91,7 @@ int (*connect) (int s, struct sockaddr *addr, socklen_t length); int (*sendmsg) (int s, const struct msghdr *msg, int flags); int (*recvmsg) (int s, struct msghdr *msg, int flags); +#endif }; gpg_err_code_t ath_install (struct ath_ops *ath_ops, int check_only); @@ -100,11 +107,19 @@ int ath_mutex_lock (ath_mutex_t *mutex); int ath_mutex_unlock (ath_mutex_t *mutex); - /* Replacement for the POSIX functions, which can be used to allow other (user-level) threads to run. */ ssize_t ath_read (int fd, void *buf, size_t nbytes); ssize_t ath_write (int fd, const void *buf, size_t nbytes); +#ifdef _WIN32 +ssize_t ath_select (int nfd, void *rset, void *wset, void *eset, + struct timeval *timeout); +ssize_t ath_waitpid (pid_t pid, int *status, int options); +int ath_accept (int s, void *addr, int *length_ptr); +int ath_connect (int s, void *addr, int length); +int ath_sendmsg (int s, const void *msg, int flags); +int ath_recvmsg (int s, void *msg, int flags); +#else ssize_t ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, struct timeval *timeout); ssize_t ath_waitpid (pid_t pid, int *status, int options); @@ -112,5 +127,6 @@ int ath_connect (int s, struct sockaddr *addr, socklen_t length); int ath_sendmsg (int s, const struct msghdr *msg, int flags); int ath_recvmsg (int s, struct msghdr *msg, int flags); +#endif #endif /* ATH_H */ Index: libgcrypt/src/gcrypt.h diff -u libgcrypt/src/gcrypt.h:1.125.2.2 libgcrypt/src/gcrypt.h:1.125.2.3 --- libgcrypt/src/gcrypt.h:1.125.2.2 Tue Nov 9 18:07:37 2004 +++ libgcrypt/src/gcrypt.h Fri Nov 26 17:27:08 2004 @@ -28,7 +28,9 @@ #include #include +#ifndef _WIN32 #include +#endif /*!_WIN32*/ #include /* This is required for error code compatibility. */ @@ -171,6 +173,15 @@ int (*mutex_unlock) (void **priv); ssize_t (*read) (int fd, void *buf, size_t nbytes); ssize_t (*write) (int fd, const void *buf, size_t nbytes); +#ifdef _WIN32 + ssize_t (*select) (int nfd, void *rset, void *wset, void *eset, + struct timeval *timeout); + ssize_t (*waitpid) (pid_t pid, int *status, int options); + int (*accept) (int s, void *addr, int *length_ptr); + int (*connect) (int s, void *addr, int length); + int (*sendmsg) (int s, const void *msg, int flags); + int (*recvmsg) (int s, void *msg, int flags); +#else ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset, struct timeval *timeout); ssize_t (*waitpid) (pid_t pid, int *status, int options); @@ -178,6 +189,7 @@ int (*connect) (int s, struct sockaddr *addr, socklen_t length); int (*sendmsg) (int s, const struct msghdr *msg, int flags); int (*recvmsg) (int s, struct msghdr *msg, int flags); +#endif }; #define GCRY_THREAD_OPTION_PTH_IMPL \ Index: libgcrypt/src/types.h diff -u libgcrypt/src/types.h:1.4 libgcrypt/src/types.h:1.4.4.1 --- libgcrypt/src/types.h:1.4 Sun Jun 15 03:46:11 2003 +++ libgcrypt/src/types.h Fri Nov 26 17:27:08 2004 @@ -43,7 +43,11 @@ #ifndef HAVE_BYTE_TYPEDEF #undef byte /* maybe there is a macro with this name */ +/* Windows typedefs byte in the rpc headers. Avoid warning about + double definition. */ +#if !(defined(_WIN32) && defined(cbNDRContext)) typedef unsigned char byte; +#endif #define HAVE_BYTE_TYPEDEF #endif Index: libgcrypt/tests/benchmark.c diff -u libgcrypt/tests/benchmark.c:1.3 libgcrypt/tests/benchmark.c:1.3.2.1 --- libgcrypt/tests/benchmark.c:1.3 Wed Mar 3 09:08:05 2004 +++ libgcrypt/tests/benchmark.c Fri Nov 26 17:27:08 2004 @@ -24,7 +24,9 @@ #include #include #include +#ifndef _WIN32 #include +#endif #include #define PGM "benchmark" @@ -39,19 +41,27 @@ static void start_timer (void) { +#ifdef _WIN32 + started_at = stopped_at = clock (); +#else struct tms tmp; times (&tmp); started_at = stopped_at = tmp.tms_utime; +#endif } static void stop_timer (void) { +#ifdef _WIN32 + stopped_at = clock (); +#else struct tms tmp; times (&tmp); stopped_at = tmp.tms_utime; +#endif } static const char * From cvs at cvs.gnupg.org Fri Nov 26 17:39:54 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Fri Nov 26 17:39:57 2004 Subject: gnupg/doc (ChangeLog gpg.sgml) Message-ID: Date: Friday, November 26, 2004 @ 17:46:53 Author: dshaw Path: /cvs/gnupg/gnupg/doc Modified: ChangeLog gpg.sgml * gpg.sgml: Document export-minimal. -----------+ ChangeLog | 4 ++++ gpg.sgml | 15 +++++++++++---- 2 files changed, 15 insertions(+), 4 deletions(-) Index: gnupg/doc/ChangeLog diff -u gnupg/doc/ChangeLog:1.85 gnupg/doc/ChangeLog:1.86 --- gnupg/doc/ChangeLog:1.85 Fri Oct 29 00:08:15 2004 +++ gnupg/doc/ChangeLog Fri Nov 26 17:46:53 2004 @@ -1,3 +1,7 @@ +2004-11-26 David Shaw + + * gpg.sgml: Document export-minimal. + 2004-10-28 David Shaw * DETAILS: Document SIG_SUBPACKET status tag. Index: gnupg/doc/gpg.sgml diff -u gnupg/doc/gpg.sgml:1.76 gnupg/doc/gpg.sgml:1.77 --- gnupg/doc/gpg.sgml:1.76 Tue Oct 19 05:04:14 2004 +++ gnupg/doc/gpg.sgml Fri Nov 26 17:46:53 2004 @@ -1307,7 +1307,7 @@ -allow-local-sigs +import-local-sigs Allow importing key signatures marked as "local". This is not generally useful unless a shared keyring scheme is being used. @@ -1344,7 +1344,7 @@ -include-local-sigs +export-local-sigs Allow exporting key signatures marked as "local". This is not generally useful unless a shared keyring scheme is being used. @@ -1352,7 +1352,7 @@ -include-attributes +export-attributes Include attribute user IDs (photo IDs) while exporting. This is useful to export keys if they are going to be used by an OpenPGP @@ -1360,12 +1360,19 @@ -include-sensitive-revkeys +export-sensitive-revkeys Include designated revoker information that was marked as "sensitive". Defaults to no. + +export-minimal + +Export the smallest key possible. Currently this is done by leaving +out any signatures that are not self-signatures. Defaults to no. + + From cvs at cvs.gnupg.org Fri Nov 26 17:41:06 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Fri Nov 26 17:41:08 2004 Subject: gnupg/g10 (ChangeLog export.c) Message-ID: Date: Friday, November 26, 2004 @ 17:48:05 Author: dshaw Path: /cvs/gnupg/gnupg/g10 Modified: ChangeLog export.c * export.c (do_export_stream): Allow export-minimal to work with secret keys, even though a non-selfsig secret key signature is rare. -----------+ ChangeLog | 4 ++++ export.c | 11 +++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.644 gnupg/g10/ChangeLog:1.645 --- gnupg/g10/ChangeLog:1.644 Fri Nov 26 16:51:37 2004 +++ gnupg/g10/ChangeLog Fri Nov 26 17:48:05 2004 @@ -1,5 +1,9 @@ 2004-11-26 David Shaw + * export.c (do_export_stream): Allow export-minimal to work with + secret keys, even though a non-selfsig secret key signature is + rare. + * options.h, export.c (parse_export_options, do_export_stream), import.c (parse_import_options, import_keys_internal): Make the import-options and export-options distinct since they can be mixed Index: gnupg/g10/export.c diff -u gnupg/g10/export.c:1.43 gnupg/g10/export.c:1.44 --- gnupg/g10/export.c:1.43 Fri Nov 26 16:51:37 2004 +++ gnupg/g10/export.c Fri Nov 26 17:48:05 2004 @@ -145,7 +145,7 @@ KEYDB_SEARCH_DESC *desc = NULL; KEYDB_HANDLE kdbhd; STRLIST sl; - u32 pk_keyid[2]; + u32 keyid[2]; *any = 0; init_packet( &pkt ); @@ -220,10 +220,13 @@ keystr(sk_keyid)); continue; } + + if(options&EXPORT_MINIMAL) + keyid_from_sk(sk,keyid); } else if((options&EXPORT_MINIMAL) && (node=find_kbnode(keyblock,PKT_PUBLIC_KEY))) - keyid_from_pk(node->pkt->pkt.public_key,pk_keyid); + keyid_from_pk(node->pkt->pkt.public_key,keyid); /* and write it */ for( kbctx=NULL; (node = walk_kbnode( keyblock, &kbctx, 0 )); ) { @@ -317,8 +320,8 @@ 0x13). A designated revocation is not stripped. */ if((options&EXPORT_MINIMAL) && IS_UID_SIG(node->pkt->pkt.signature) - && (node->pkt->pkt.signature->keyid[0]!=pk_keyid[0] - || node->pkt->pkt.signature->keyid[1]!=pk_keyid[1])) + && (node->pkt->pkt.signature->keyid[0]!=keyid[0] + || node->pkt->pkt.signature->keyid[1]!=keyid[1])) continue; /* do not export packets which are marked as not exportable */ From cvs at cvs.gnupg.org Sat Nov 27 11:37:50 2004 From: cvs at cvs.gnupg.org (cvs user werner) Date: Sat Nov 27 11:37:57 2004 Subject: libassuan/src (ChangeLog assuan-socket.c) Message-ID: Date: Saturday, November 27, 2004 @ 11:37:50 Author: werner Path: /cvs/gnupg/libassuan/src Modified: ChangeLog assuan-socket.c include/sys/types.h -----------------+ ChangeLog | 5 +++++ assuan-socket.c | 1 + 2 files changed, 6 insertions(+) From cvs at cvs.gnupg.org Mon Nov 29 21:59:53 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Mon Nov 29 21:59:56 2004 Subject: STABLE-BRANCH-1-2 gnupg/g10 (ChangeLog getkey.c) Message-ID: Date: Monday, November 29, 2004 @ 22:07:08 Author: dshaw Path: /cvs/gnupg/gnupg/g10 Tag: STABLE-BRANCH-1-2 Modified: ChangeLog getkey.c * getkey.c (parse_key_usage): New function to parse out key usage flags. Set PUBKEY_USAGE_UNKNOWN to handle flags (i.e. authentication) that we don't understand in this branch. (fixup_uidnode, merge_selfsigs_main, merge_selfsigs_subkey): Call it from here to remove duplicate code. This is bug 378. -----------+ ChangeLog | 15 ++++++-- getkey.c | 103 +++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 73 insertions(+), 45 deletions(-) Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.249.2.232 gnupg/g10/ChangeLog:1.249.2.233 --- gnupg/g10/ChangeLog:1.249.2.232 Tue Sep 14 03:55:57 2004 +++ gnupg/g10/ChangeLog Mon Nov 29 22:07:08 2004 @@ -1,3 +1,11 @@ +2004-11-29 David Shaw + + * getkey.c (parse_key_usage): New function to parse out key usage + flags. Set PUBKEY_USAGE_UNKNOWN to handle flags + (i.e. authentication) that we don't understand in this branch. + (fixup_uidnode, merge_selfsigs_main, merge_selfsigs_subkey): Call + it from here to remove duplicate code. This is bug 378. + 2004-09-13 David Shaw * getkey.c (premerge_public_with_secret): Fix subkey<->binding sig @@ -14,9 +22,10 @@ * hkp.c (dehtmlize): Understand the quote character (i.e. """) in HTML responses. - * keydb.h, getkey.c (get_user_id_printable): Rename to - get_user_id_native and remove the printable stuff since we're - print-ifying valid utf8 characters. Change all callers in + * keydb.h, getkey.c (get_user_id_printable, + get_user_id_string_printable): Rename to get_user_id_native and + get_user_id_string_native and remove the printable stuff since + we're print-ifying valid utf8 characters. Change all callers in import.c, sign.c, and encode.c. 2004-08-19 David Shaw Index: gnupg/g10/getkey.c diff -u gnupg/g10/getkey.c:1.78.2.33 gnupg/g10/getkey.c:1.78.2.34 --- gnupg/g10/getkey.c:1.78.2.33 Tue Sep 14 03:55:58 2004 +++ gnupg/g10/getkey.c Mon Nov 29 22:07:08 2004 @@ -1248,6 +1248,45 @@ } } +static int +parse_key_usage(PKT_signature *sig) +{ + int key_usage=0; + const byte *p; + size_t n; + byte flags; + + p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_KEY_FLAGS,&n); + if(p && n) + { + /* first octet of the keyflags */ + flags=*p; + + if(flags & 3) + { + key_usage |= PUBKEY_USAGE_SIG; + flags&=~3; + } + + if(flags & 12) + { + key_usage |= PUBKEY_USAGE_ENC; + flags&=~12; + } + + if(flags) + key_usage |= PUBKEY_USAGE_UNKNOWN; + } + + /* We set PUBKEY_USAGE_UNKNOWN to indicate that this key has a + capability that we do not handle. This serves to distinguish + between a zero key usage which we handle as the default + capabilities for that algorithm, and a usage that we do not + handle. */ + + return key_usage; +} + /* * Apply information from SIGNODE (which is the valid self-signature * associated with that UID) to the UIDNODE: @@ -1280,17 +1319,7 @@ uid->expiredate = sig->expiredate; /* store the key flags in the helper variable for later processing */ - uid->help_key_usage = 0; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 3) ) - uid->help_key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 12) ) - uid->help_key_usage |= PUBKEY_USAGE_ENC; - /* Note: we do not set the CERT flag here because it can be assumed - * that thre is no real policy to set it. */ - } + uid->help_key_usage=parse_key_usage(sig); /* ditto or the key expiration */ uid->help_key_expire = 0; @@ -1480,33 +1509,27 @@ pk->numrevkeys*sizeof(struct revocation_key)); } - if ( signode ) { + if ( signode ) + { /* some information from a direct key signature take precedence * over the same information given in UID sigs. */ PKT_signature *sig = signode->pkt->pkt.signature; const byte *p; - size_t n; - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 3) ) - key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 12) ) - key_usage |= PUBKEY_USAGE_ENC; - } + + key_usage=parse_key_usage(sig); p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if ( p ) { - key_expire = keytimestamp + buffer_to_u32(p); - key_expire_seen = 1; - } + if ( p ) + { + key_expire = keytimestamp + buffer_to_u32(p); + key_expire_seen = 1; + } /* mark that key as valid: one direct key signature should * render a key as valid */ pk->is_valid = 1; - } + } /* pass 1.5: look for key revocation signatures that were not made by the key (i.e. did a revocation key issue a revocation for @@ -1831,7 +1854,6 @@ u32 keytimestamp = 0; u32 key_expire = 0; const byte *p; - size_t n; if ( subnode->pkt->pkttype != PKT_PUBLIC_SUBKEY ) BUG (); @@ -1889,23 +1911,20 @@ subpk->is_valid = 1; sig = signode->pkt->pkt.signature; sig->flags.chosen_selfsig=1; /* so we know which selfsig we chose later */ - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 3) ) - key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 12) ) - key_usage |= PUBKEY_USAGE_ENC; - } - if ( !key_usage ) { /* no key flags at all: get it from the algo */ + + key_usage=parse_key_usage(sig); + if ( !key_usage ) + { + /* no key flags at all: get it from the algo */ key_usage = openpgp_pk_algo_usage ( subpk->pubkey_algo ); - } - else { /* check that the usage matches the usage as given by the algo */ + } + else + { + /* check that the usage matches the usage as given by the algo */ int x = openpgp_pk_algo_usage ( subpk->pubkey_algo ); if ( x ) /* mask it down to the actual allowed usage */ - key_usage &= x; - } + key_usage &= x; + } /* Type 20 Elgamal subkeys, any subkey on a type 20 primary, or any subkey on an old v3 Elgamal(e) primary are not usable. */ From cvs at cvs.gnupg.org Mon Nov 29 22:00:25 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Mon Nov 29 22:00:37 2004 Subject: STABLE-BRANCH-1-2 gnupg/include (ChangeLog cipher.h) Message-ID: Date: Monday, November 29, 2004 @ 22:07:43 Author: dshaw Path: /cvs/gnupg/gnupg/include Tag: STABLE-BRANCH-1-2 Modified: ChangeLog cipher.h * cipher.h: Add PUBKEY_USAGE_UNKNOWN. -----------+ ChangeLog | 4 ++++ cipher.h | 1 + 2 files changed, 5 insertions(+) Index: gnupg/include/ChangeLog diff -u gnupg/include/ChangeLog:1.34.2.19 gnupg/include/ChangeLog:1.34.2.20 --- gnupg/include/ChangeLog:1.34.2.19 Mon Mar 29 15:56:55 2004 +++ gnupg/include/ChangeLog Mon Nov 29 22:07:43 2004 @@ -1,3 +1,7 @@ +2004-11-29 David Shaw + + * cipher.h: Add PUBKEY_USAGE_UNKNOWN. + 2004-03-29 Werner Koch * mpi.h: s/exp/exponent/ to shutup a compiler warning. Index: gnupg/include/cipher.h diff -u gnupg/include/cipher.h:1.53.2.5 gnupg/include/cipher.h:1.53.2.6 --- gnupg/include/cipher.h:1.53.2.5 Tue Dec 2 06:24:55 2003 +++ gnupg/include/cipher.h Mon Nov 29 22:07:43 2004 @@ -51,6 +51,7 @@ #define PUBKEY_USAGE_SIG 1 /* key is good for signatures */ #define PUBKEY_USAGE_ENC 2 /* key is good for encryption */ #define PUBKEY_USAGE_CERT 4 /* key is also good to certify other keys*/ +#define PUBKEY_USAGE_UNKNOWN 128 /* key has an unknown usage bit */ #define DIGEST_ALGO_MD5 1 #define DIGEST_ALGO_SHA1 2 From cvs at cvs.gnupg.org Mon Nov 29 22:07:00 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Mon Nov 29 22:07:03 2004 Subject: gnupg/include (ChangeLog cipher.h) Message-ID: Date: Monday, November 29, 2004 @ 22:14:19 Author: dshaw Path: /cvs/gnupg/gnupg/include Modified: ChangeLog cipher.h * cipher.h: Add PUBKEY_USAGE_UNKNOWN. -----------+ ChangeLog | 4 ++++ cipher.h | 1 + 2 files changed, 5 insertions(+) Index: gnupg/include/ChangeLog diff -u gnupg/include/ChangeLog:1.79 gnupg/include/ChangeLog:1.80 --- gnupg/include/ChangeLog:1.79 Wed Nov 3 21:03:46 2004 +++ gnupg/include/ChangeLog Mon Nov 29 22:14:18 2004 @@ -1,3 +1,7 @@ +2004-11-29 David Shaw + + * cipher.h: Add PUBKEY_USAGE_UNKNOWN. + 2004-11-03 Timo Schulz * errors.h: Add w32_strerror prototype. Index: gnupg/include/cipher.h diff -u gnupg/include/cipher.h:1.62 gnupg/include/cipher.h:1.63 --- gnupg/include/cipher.h:1.62 Sat Jan 17 04:10:09 2004 +++ gnupg/include/cipher.h Mon Nov 29 22:14:18 2004 @@ -50,6 +50,7 @@ #define PUBKEY_USAGE_ENC 2 /* key is good for encryption */ #define PUBKEY_USAGE_CERT 4 /* key is also good to certify other keys*/ #define PUBKEY_USAGE_AUTH 8 /* key is good for authentication */ +#define PUBKEY_USAGE_UNKNOWN 128 /* key has an unknown usage bit */ #define DIGEST_ALGO_MD5 1 #define DIGEST_ALGO_SHA1 2 From cvs at cvs.gnupg.org Mon Nov 29 22:14:34 2004 From: cvs at cvs.gnupg.org (cvs user dshaw) Date: Mon Nov 29 22:14:37 2004 Subject: gnupg/g10 (ChangeLog getkey.c) Message-ID: Date: Monday, November 29, 2004 @ 22:21:52 Author: dshaw Path: /cvs/gnupg/gnupg/g10 Modified: ChangeLog getkey.c * getkey.c (parse_key_usage): New function to parse out key usage flags. Set PUBKEY_USAGE_UNKNOWN to handle flags that we don't understand. (fixup_uidnode, merge_selfsigs_main, merge_selfsigs_subkey): Call it from here to remove duplicate code. -----------+ ChangeLog | 15 ++++++- getkey.c | 116 +++++++++++++++++++++++++++++++++++------------------------- 2 files changed, 80 insertions(+), 51 deletions(-) Index: gnupg/g10/ChangeLog diff -u gnupg/g10/ChangeLog:1.645 gnupg/g10/ChangeLog:1.646 --- gnupg/g10/ChangeLog:1.645 Fri Nov 26 17:48:05 2004 +++ gnupg/g10/ChangeLog Mon Nov 29 22:21:52 2004 @@ -1,3 +1,11 @@ +2004-11-29 David Shaw + + * getkey.c (parse_key_usage): New function to parse out key usage + flags. Set PUBKEY_USAGE_UNKNOWN to handle flags that we don't + understand. + (fixup_uidnode, merge_selfsigs_main, merge_selfsigs_subkey): Call + it from here to remove duplicate code. + 2004-11-26 David Shaw * export.c (do_export_stream): Allow export-minimal to work with @@ -782,9 +790,10 @@ (keystr_from_desc): Handle short keyids and warn on v3 fingerprints. - * keydb.h, getkey.c (get_user_id_printable): Rename to - get_user_id_native and remove the printable stuff since we're - print-ifying valid utf8 characters. Change all callers in + * keydb.h, getkey.c (get_user_id_printable, + get_user_id_string_printable): Rename to get_user_id_native and + get_user_id_string_native and remove the printable stuff since + we're print-ifying valid utf8 characters. Change all callers in import.c, sign.c, keylist.c, and encode.c. * keyserver.c (keyserver_search_prompt): Make sure the search Index: gnupg/g10/getkey.c diff -u gnupg/g10/getkey.c:1.120 gnupg/g10/getkey.c:1.121 --- gnupg/g10/getkey.c:1.120 Fri Sep 24 22:34:38 2004 +++ gnupg/g10/getkey.c Mon Nov 29 22:21:52 2004 @@ -1242,6 +1242,51 @@ } } +static int +parse_key_usage(PKT_signature *sig) +{ + int key_usage=0; + const byte *p; + size_t n; + byte flags; + + p=parse_sig_subpkt(sig->hashed,SIGSUBPKT_KEY_FLAGS,&n); + if(p && n) + { + /* first octet of the keyflags */ + flags=*p; + + if(flags & 3) + { + key_usage |= PUBKEY_USAGE_SIG; + flags&=~3; + } + + if(flags & 12) + { + key_usage |= PUBKEY_USAGE_ENC; + flags&=~12; + } + + if(flags & 0x20) + { + key_usage |= PUBKEY_USAGE_AUTH; + flags&=~0x20; + } + + if(flags) + key_usage |= PUBKEY_USAGE_UNKNOWN; + } + + /* We set PUBKEY_USAGE_UNKNOWN to indicate that this key has a + capability that we do not handle. This serves to distinguish + between a zero key usage which we handle as the default + capabilities for that algorithm, and a usage that we do not + handle. */ + + return key_usage; +} + /* * Apply information from SIGNODE (which is the valid self-signature * associated with that UID) to the UIDNODE: @@ -1274,19 +1319,7 @@ uid->expiredate = sig->expiredate; /* store the key flags in the helper variable for later processing */ - uid->help_key_usage = 0; - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 3) ) - uid->help_key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 12) ) - uid->help_key_usage |= PUBKEY_USAGE_ENC; - /* Note: we do not set the CERT flag here because it can be assumed - * that thre is no real policy to set it. */ - if ( (*p & 0x20) ) - uid->help_key_usage |= PUBKEY_USAGE_AUTH; - } + uid->help_key_usage=parse_key_usage(sig); /* ditto or the key expiration */ uid->help_key_expire = 0; @@ -1484,35 +1517,27 @@ pk->numrevkeys*sizeof(struct revocation_key)); } - if ( signode ) { + if ( signode ) + { /* some information from a direct key signature take precedence * over the same information given in UID sigs. */ PKT_signature *sig = signode->pkt->pkt.signature; const byte *p; - size_t n; - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 3) ) - key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 12) ) - key_usage |= PUBKEY_USAGE_ENC; - if ( (*p & 0x20) ) - key_usage |= PUBKEY_USAGE_AUTH; - } + + key_usage=parse_key_usage(sig); p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); - if ( p ) { - key_expire = keytimestamp + buffer_to_u32(p); - key_expire_seen = 1; - } + if ( p ) + { + key_expire = keytimestamp + buffer_to_u32(p); + key_expire_seen = 1; + } /* mark that key as valid: one direct key signature should * render a key as valid */ pk->is_valid = 1; - } + } /* pass 1.5: look for key revocation signatures that were not made by the key (i.e. did a revocation key issue a revocation for @@ -1835,7 +1860,6 @@ u32 keytimestamp = 0; u32 key_expire = 0; const byte *p; - size_t n; if ( subnode->pkt->pkttype != PKT_PUBLIC_SUBKEY ) BUG (); @@ -1893,25 +1917,21 @@ sig = signode->pkt->pkt.signature; sig->flags.chosen_selfsig=1; /* so we know which selfsig we chose later */ - - p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_FLAGS, &n ); - if ( p && n ) { - /* first octet of the keyflags */ - if ( (*p & 3) ) - key_usage |= PUBKEY_USAGE_SIG; - if ( (*p & 12) ) - key_usage |= PUBKEY_USAGE_ENC; - if ( (*p & 0x20) ) - key_usage |= PUBKEY_USAGE_AUTH; - } - if ( !key_usage ) { /* no key flags at all: get it from the algo */ + + key_usage=parse_key_usage(sig); + if ( !key_usage ) + { + /* no key flags at all: get it from the algo */ key_usage = openpgp_pk_algo_usage ( subpk->pubkey_algo ); - } - else { /* check that the usage matches the usage as given by the algo */ + } + else + { + /* check that the usage matches the usage as given by the algo */ int x = openpgp_pk_algo_usage ( subpk->pubkey_algo ); if ( x ) /* mask it down to the actual allowed usage */ - key_usage &= x; - } + key_usage &= x; + } + subpk->pubkey_usage = key_usage; p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL); From cvs at cvs.gnupg.org Tue Nov 30 10:41:18 2004 From: cvs at cvs.gnupg.org (cvs user twoaday) Date: Tue Nov 30 10:41:24 2004 Subject: GNUPG-1-9-BRANCH gnupg/jnlib (ChangeLog w32-afunix.c w32-afunix.h) Message-ID: Date: Tuesday, November 30, 2004 @ 10:48:37 Author: twoaday Path: /cvs/gnupg/gnupg/jnlib Tag: GNUPG-1-9-BRANCH Added: w32-afunix.c w32-afunix.h Modified: ChangeLog 2004-11-30 Timo Schulz * w32-afunix.c: New. AF_UNIX emulation for W32. * w32-afunix.h: Likewise. --------------+ ChangeLog | 5 ++ w32-afunix.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ w32-afunix.h | 47 +++++++++++++++++++++++ 3 files changed, 167 insertions(+) Index: gnupg/jnlib/ChangeLog diff -u gnupg/jnlib/ChangeLog:1.3.2.17 gnupg/jnlib/ChangeLog:1.3.2.18 --- gnupg/jnlib/ChangeLog:1.3.2.17 Tue Nov 23 18:09:51 2004 +++ gnupg/jnlib/ChangeLog Tue Nov 30 10:48:37 2004 @@ -1,3 +1,8 @@ +2004-11-30 Timo Schulz + + * w32-afunix.c: New. AF_UNIX emulation for W32. + * w32-afunix.h: Likewise. + 2004-11-22 Werner Koch * logging.c (log_test_fd): Add test on LOGSTREAM. Reported by Index: gnupg/jnlib/w32-afunix.c diff -u /dev/null gnupg/jnlib/w32-afunix.c:1.1.2.1 --- /dev/null Tue Nov 30 10:48:37 2004 +++ gnupg/jnlib/w32-afunix.c Tue Nov 30 10:48:37 2004 @@ -0,0 +1,115 @@ +/* w32-afunix.c + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ +#ifdef _WIN32 +#include +#include +#include + +#include "w32-afunix.h" + +int +_w32_close (int fd) +{ + int rc = closesocket (fd); + if (rc && WSAGetLastError () == WSAENOTSOCK) + rc = close (fd); + return rc; +} + + +int +_w32_sock_new (int domain, int type, int proto) +{ + if (domain == AF_UNIX || domain == AF_LOCAL) + domain = AF_INET; + return socket (domain, type, proto); +} + + +int +_w32_sock_connect (int sockfd, struct sockaddr * addr, int addrlen) +{ + struct sockaddr_in myaddr; + struct sockaddr_un * unaddr; + FILE * fp; + int port = 0; + + unaddr = (struct sockaddr_un *)addr; + fp = fopen (unaddr->sun_path, "rb"); + if (!fp) + return -1; + fscanf (fp, "%d", &port); + fclose (fp); + /* XXX: set errno in this case */ + if (port < 0 || port > 65535) + return -1; + + myaddr.sin_family = AF_INET; + myaddr.sin_port = port; + myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + + /* we need this later. */ + unaddr->sun_family = myaddr.sin_family; + unaddr->sun_port = myaddr.sin_port; + unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr; + + return connect (sockfd, (struct sockaddr *)&myaddr, sizeof myaddr); +} + + +int +_w32_sock_bind (int sockfd, struct sockaddr * addr, int addrlen) +{ + if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX) + { + struct sockaddr_in myaddr; + struct sockaddr_un * unaddr; + FILE * fp; + int len = sizeof myaddr; + int rc; + + myaddr.sin_port = 0; + myaddr.sin_family = AF_INET; + myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + + rc = bind (sockfd, (struct sockaddr *)&myaddr, len); + if (rc) + return rc; + rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len); + if (rc) + return rc; + unaddr = (struct sockaddr_un *)addr; + fp = fopen (unaddr->sun_path, "wb"); + if (!fp) + return -1; + fprintf (fp, "%d", myaddr.sin_port); + fclose (fp); + + /* we need this later. */ + unaddr->sun_family = myaddr.sin_family; + unaddr->sun_port = myaddr.sin_port; + unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr; + + return 0; + } + return bind (sockfd, addr, addrlen); +} + +#endif /*_WIN32*/ Index: gnupg/jnlib/w32-afunix.h diff -u /dev/null gnupg/jnlib/w32-afunix.h:1.1.2.1 --- /dev/null Tue Nov 30 10:48:37 2004 +++ gnupg/jnlib/w32-afunix.h Tue Nov 30 10:48:37 2004 @@ -0,0 +1,47 @@ +/* w32-afunix.h + * Copyright (C) 2004 g10 Code GmbH + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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 + */ +#ifdef _WIN32 +#ifndef W32AFUNIX_DEFS_H +#define W32AFUNIX_DEFS_H + +#include +#include +#include + +#define DIRSEP_C '\\' + +#define AF_LOCAL AF_UNIX +/* We need to prefix the structure with a sockaddr_in header so we can + use it later for sendto and recvfrom. */ +struct sockaddr_un +{ + short sun_family; + unsigned short sun_port; + struct in_addr sun_addr; + char sun_path[108-2-4]; /* Path name. */ +}; + +int _w32_close (int fd); +int _w32_sock_new (int domain, int type, int proto); +int _w32_sock_bind (int sockfd, struct sockaddr *addr, int addrlen); +int _w32_sock_connect (int sockfd, struct sockaddr *addr, int addrlen); + +#endif /*W32AFUNIX_DEFS_H*/ +#endif /*_WIN32*/ From cvs at cvs.gnupg.org Mon Nov 22 22:24:17 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Thu Dec 2 16:36:56 2004 Subject: dirmngr (21 files) Message-ID: Date: Monday, November 22, 2004 @ 22:30:50 Author: wk Path: /cvs/dirmngr/dirmngr Modified: NEWS doc/dirmngr.texi jnlib/ChangeLog jnlib/logging.c src/ChangeLog src/Makefile.am src/certcache.c src/certcache.h src/crlcache.c src/crlcache.h src/crlfetch.c src/dirmngr.c src/dirmngr.h src/dirmngr_ldap.c src/http.c src/http.h src/ldap.c src/ocsp.c src/server.c src/validate.c src/validate.h * logging.c (log_test_fd): Add test on LOGSTREAM. * dirmngr_ldap.c (main): New option --proxy. * ocsp.c (do_ocsp_request): Take care of opt.disable_http. * crlfetch.c (crl_fetch): Honor the --honor-http-proxy variable. (crl_fetch): Take care of opt.disable_http and disable_ldap. (crl_fetch_default, ca_cert_fetch, start_cert_fetch): * ldap.c (run_ldap_wrapper): New arg PROXY. (url_fetch_ldap, attr_fetch_ldap, start_cert_fetch_ldap): Pass it. * http.c (http_open_document): Add arg PROXY. (http_open): Ditto. (send_request): Ditto and implement it as an override. * ocsp.c (validate_responder_cert): Use validate_cert_chain. * Makefile.am (AM_CPPFLAGS): Add macros for a few system directories. * dirmngr.h (opt): New members homedir_data, homedir_cache, ldap_wrapper_program, system_daemon, honor_http_proxy, http_proxy, ldap_proxy, only_ldap_proxy, disable_ldap, disable_http. * dirmngr.c (main): Initialize new opt members HOMEDIR_DATA and HOMEDIR_CACHE. (parse_rereadable_options): New options --ldap-wrapper-program, --http-wrapper-program, --disable-ldap, --disable-http, --honor-http-proxy, --http-proxy, --ldap-proxy, --only-ldap-proxy. (reread_configuration): New. * ldap.c (ldap_wrapper): Use the correct name for the wrapper. * crlcache.c (DBDIR_D): Make it depend on opt.SYSTEM_DAEMON. (cleanup_cache_dir, open_dir, update_dir, make_db_file_name) (crl_cache_insert, create_directory_if_needed): Use opt.HOMEDIR_CACHE * validate.c (check_revocations): New. * crlcache.c (crl_cache_isvalid): Factored most code out to (cache_isvalid): .. new. (crl_cache_cert_isvalid): New. * server.c (cmd_checkcrl): Cleaned up by using this new function. (reload_crl): Moved to .. * crlcache.c (crl_cache_reload_crl): .. here and made global. * certcache.c (cert_compute_fpr): Renamed from computer_fpr and made global. (find_cert_bysn): Try to lookup missing certs. (cert_cache_init): Intialize using opt.HOMEDIR_DATA. --------------------+ NEWS | 15 ++ doc/dirmngr.texi | 50 ++++++++- jnlib/ChangeLog | 4 jnlib/logging.c | 9 + src/ChangeLog | 48 ++++++++ src/Makefile.am | 2 src/certcache.c | 82 ++++++++++++-- src/certcache.h | 4 src/crlcache.c | 282 +++++++++++++++++++++++++++++++++++++++++++++------ src/crlcache.h | 5 src/crlfetch.c | 40 ++++++- src/dirmngr.c | 144 +++++++++++++++++++++++--- src/dirmngr.h | 17 ++- src/dirmngr_ldap.c | 21 +++ src/http.c | 33 +++-- src/http.h | 6 - src/ldap.c | 35 +++++- src/ocsp.c | 63 +++++++---- src/server.c | 228 +---------------------------------------- src/validate.c | 162 ++++++++++++++++++++++++----- src/validate.h | 10 + 21 files changed, 902 insertions(+), 358 deletions(-) Index: dirmngr/NEWS diff -u dirmngr/NEWS:1.27 dirmngr/NEWS:1.28 --- dirmngr/NEWS:1.27 Tue Nov 16 19:24:36 2004 +++ dirmngr/NEWS Mon Nov 22 22:30:50 2004 @@ -1,11 +1,22 @@ Noteworthy changes in version 0.9.0 ------------------------------------------------ - WARNING: CURRENTLY UNDER HEAVY RECONSTRUCTION. Many things might - not yet work again. + * New option --daemon to start dirmngr as a system daemon. This + switched to the use of different directories and also does + certificate validation on its own. * New tool dirmngr-client. + * New options: --ldap-wrapper-program, --http-wrapper-program, + --disable-ldap, --disable-http, --honor-http-proxy, --http-proxy, + --ldap-proxy and --only-ldap-proxy. + + * Uses an external ldap wrapper to cope with timeouts and general + LDAP problems. Prepared for using + + * SIGHUP may be used to reread the configuration and to flush the + certificate cache. + Noteworthy changes in version 0.5.6 (2004-09-28) ------------------------------------------------ Index: dirmngr/doc/dirmngr.texi diff -u dirmngr/doc/dirmngr.texi:1.15 dirmngr/doc/dirmngr.texi:1.16 --- dirmngr/doc/dirmngr.texi:1.15 Thu Nov 18 16:37:48 2004 +++ dirmngr/doc/dirmngr.texi Mon Nov 22 22:30:50 2004 @@ -155,7 +155,8 @@ @item --daemon @opindex daemon Run in background daemon mode and listen for commands on a socket. -Note that this also changes the default home directory. +Note that this also changes the default home directory and enables the +internal certificate validation code. @item --list-crls @opindex list-crls @@ -210,11 +211,14 @@ @table @asis @item With @code{--daemon} given on the commandline - the directory named @file{/etc/dirmngr}. +the directory named @file{/etc/dirmngr} for configuration files, +@file{/var/lib/dirmngr/} for extra data and @file{/var/cache/dirmngr} +for cached CRLs. @item Without @code{--daemon} given on the commandline the directory named @file{.gnupg} directly below the home directory of the user unless the environment variable @code{GNUPGHOME} has been set -in which case its value will be used. +in which case its value will be used. All kind of data is stored below +this directory. @end table @@ -290,11 +294,46 @@ Enabling this option forces loading of expired CRLs; this is only useful for debugging. +@item --disable-ldap +@opindex disable-ldap +Entirely disables the use of LDAP. + +@item --disable-http +@opindex disable-http +Entirely disables the use of HTTP. + +@item --honor-http-proxy +@opindex honor-http-proxy +If the environment variable @env{http_proxy} has been set, use its +value to access HTTP servers. + +@item --http-proxy @var{host}[:@var{port}] +@opindex http-proxy +Use @var{host} and @var{port} to access HTTP servers. The use of this +options overrides the environment variable @env{http_proxy} regardless +whether @option{--honor-http-proxy} has been set. + + +@item --ldap-proxy @var{host}[:@var{port}] +@opindex ldap-proxy +Use @var{host} and @var{port} to connect to LDAP servers. If @var{port} +is ommitted, port 389 (standard LDAP port) is used. This overrides any +specified host and port part in a LDAP URL and will also be used if host +and port have been ommitted from the URL. + +@item --only-ldap-proxy +@opindex only-ldap-proxy +Never use anything else but the LDAP "proxy" as configured with +@option{--ldap-proxy}. Usually @command{dirmngr} tries to use other +configured LDAP server if the connection using the "proxy" failed. + + @item --ldapserverlist-file @var{file} @opindex ldapserverlist-file Read the list of LDAP servers to consult for CRLs and certificates from file instead of the default per-user ldap server list file. The default -value for @var{file} is @samp{dirmngr_ldapservers.conf}. +value for @var{file} is @file{dirmngr_ldapservers.conf} or +@file{ldapservers.conf} when running in @option{--daemon} mode. The server list file contains one LDAP server per line in the format @@ -307,6 +346,7 @@ Specify the number of seconds to wait for an LDAP query before timing out. The default is currently 100 seconds. + @item --add-servers @opindex add-servers This options makes dirmngr add any servers it discovers when validating @@ -370,7 +410,7 @@ @cpindex SIGHUP This signals flushes all internally cached CRLs as well as any cached certificates. Then the certificate cache is reinitialized as on -startup. +startup. Options are re-read from the configuration file. @item SIGTERM @cpindex SIGTERM Index: dirmngr/jnlib/ChangeLog diff -u dirmngr/jnlib/ChangeLog:1.9 dirmngr/jnlib/ChangeLog:1.10 --- dirmngr/jnlib/ChangeLog:1.9 Tue Nov 16 19:24:35 2004 +++ dirmngr/jnlib/ChangeLog Mon Nov 22 22:30:50 2004 @@ -1,3 +1,7 @@ +2004-11-22 Werner Koch + + * logging.c (log_test_fd): Add test on LOGSTREAM. + 2004-10-21 Werner Koch * logging.c (do_logv): Use set_log_stream to setup a default. Index: dirmngr/jnlib/logging.c diff -u dirmngr/jnlib/logging.c:1.8 dirmngr/jnlib/logging.c:1.9 --- dirmngr/jnlib/logging.c:1.8 Tue Nov 16 19:24:35 2004 +++ dirmngr/jnlib/logging.c Mon Nov 22 22:30:50 2004 @@ -411,9 +411,12 @@ int log_test_fd (int fd) { - int tmp = fileno (logstream); - if ( tmp != -1 && tmp == fd) - return 1; + if (logstream) + { + int tmp = fileno (logstream); + if ( tmp != -1 && tmp == fd) + return 1; + } if (log_socket != -1 && log_socket == fd) return 1; return 0; Index: dirmngr/src/ChangeLog diff -u dirmngr/src/ChangeLog:1.24 dirmngr/src/ChangeLog:1.25 --- dirmngr/src/ChangeLog:1.24 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/ChangeLog Mon Nov 22 22:30:50 2004 @@ -1,3 +1,51 @@ +2004-11-22 Werner Koch + + * dirmngr_ldap.c (main): New option --proxy. + * ocsp.c (do_ocsp_request): Take care of opt.disable_http. + * crlfetch.c (crl_fetch): Honor the --honor-http-proxy variable. + (crl_fetch): Take care of opt.disable_http and disable_ldap. + (crl_fetch_default, ca_cert_fetch, start_cert_fetch): + * ldap.c (run_ldap_wrapper): New arg PROXY. + (url_fetch_ldap, attr_fetch_ldap, start_cert_fetch_ldap): Pass it. + + * http.c (http_open_document): Add arg PROXY. + (http_open): Ditto. + (send_request): Ditto and implement it as an override. + + * ocsp.c (validate_responder_cert): Use validate_cert_chain. + + * Makefile.am (AM_CPPFLAGS): Add macros for a few system + directories. + * dirmngr.h (opt): New members homedir_data, homedir_cache, + ldap_wrapper_program, system_daemon, honor_http_proxy, http_proxy, + ldap_proxy, only_ldap_proxy, disable_ldap, disable_http. + * dirmngr.c (main): Initialize new opt members HOMEDIR_DATA and + HOMEDIR_CACHE. + (parse_rereadable_options): New options --ldap-wrapper-program, + --http-wrapper-program, --disable-ldap, --disable-http, + --honor-http-proxy, --http-proxy, --ldap-proxy, --only-ldap-proxy. + (reread_configuration): New. + + * ldap.c (ldap_wrapper): Use the correct name for the wrapper. + + * crlcache.c (DBDIR_D): Make it depend on opt.SYSTEM_DAEMON. + (cleanup_cache_dir, open_dir, update_dir, make_db_file_name) + (crl_cache_insert, create_directory_if_needed): Use opt.HOMEDIR_CACHE + + * validate.c (check_revocations): New. + * crlcache.c (crl_cache_isvalid): Factored most code out to + (cache_isvalid): .. new. + (crl_cache_cert_isvalid): New. + * server.c (cmd_checkcrl): Cleaned up by using this new function. + (reload_crl): Moved to .. + * crlcache.c (crl_cache_reload_crl): .. here and made global. + + * certcache.c (cert_compute_fpr): Renamed from computer_fpr and + made global. + (find_cert_bysn): Try to lookup missing certs. + (cert_cache_init): Intialize using opt.HOMEDIR_DATA. + + 2004-11-19 Werner Koch * dirmngr-client.c (status_cb): New. Use it in very verbose mode. Index: dirmngr/src/Makefile.am diff -u dirmngr/src/Makefile.am:1.18 dirmngr/src/Makefile.am:1.19 --- dirmngr/src/Makefile.am:1.18 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/Makefile.am Mon Nov 22 22:30:50 2004 @@ -30,6 +30,8 @@ AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" AM_CPPFLAGS += -DDIRMNGR_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\"" AM_CPPFLAGS += -DDIRMNGR_LIBEXECDIR="\"$(libexecdir)\"" +AM_CPPFLAGS += -DDIRMNGR_DATADIR="\"$(localstatedir)/lib/@PACKAGE@\"" +AM_CPPFLAGS += -DDIRMNGR_CACHEDIR="\"$(localstatedir)/cache/@PACKAGE@\"" AM_CFLAGS = -I$(top_srcdir)/jnlib @LIBGCRYPT_CFLAGS@ @LIBASSUAN_CFLAGS@ \ @KSBA_CFLAGS@ @GPG_ERROR_CFLAGS@ $(PTH_CFLAGS) Index: dirmngr/src/certcache.c diff -u dirmngr/src/certcache.c:1.4 dirmngr/src/certcache.c:1.5 --- dirmngr/src/certcache.c:1.4 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/certcache.c Mon Nov 22 22:30:50 2004 @@ -32,8 +32,10 @@ #include "dirmngr.h" #include "misc.h" +#include "crlfetch.h" #include "certcache.h" + #define MAX_EXTRA_CACHED_CERTS 200 /* FIXME: This is a debugging value. */ @@ -136,10 +138,10 @@ } -/* Computer the fingerprint of the certificate CERT and put it into +/* Compute the fingerprint of the certificate CERT and put it into the 20 bytes large buffer DIGEST. Return address of this buffer. */ -static unsigned char * -compute_fpr (ksba_cert_t cert, unsigned char *digest) +unsigned char * +cert_compute_fpr (ksba_cert_t cert, unsigned char *digest) { gpg_error_t err; gcry_md_hd_t md; @@ -237,7 +239,7 @@ idx %= 256; } - compute_fpr (cert, fpr); + cert_compute_fpr (cert, fpr); for (ci=cert_cache[*fpr]; ci; ci = ci->next) if (ci->cert && !memcmp (ci->fpr, fpr, 20)) return gpg_error (GPG_ERR_DUP_VALUE); @@ -298,8 +300,9 @@ dir = opendir (dirname); if (!dir) { - log_info (_("can't access directory `%s': %s\n"), - dirname, strerror (errno)); + if (opt.system_daemon) + log_info (_("can't access directory `%s': %s\n"), + dirname, strerror (errno)); return 0; /* We do not consider this a severe error. */ } @@ -376,7 +379,7 @@ load_certs_from_dir (dname, 1); xfree (dname); - dname = make_filename (opt.homedir, "extra-certs", NULL); + dname = make_filename (opt.homedir_data, "extra-certs", NULL); load_certs_from_dir (dname, 0); xfree (dname); @@ -538,15 +541,68 @@ /* Return the certificate matching ISSUER_DN and SERIALNO; if it is not already in the cache, try to find it from other resources. */ ksba_cert_t -find_cert_bysn (const char *issuer_dn, ksba_sexp_t serialno) +find_cert_bysn (ctrl_t ctrl, const char *issuer_dn, ksba_sexp_t serialno) { + gpg_error_t err; ksba_cert_t cert; + ksba_reader_t reader; cert = get_cert_bysn (issuer_dn, serialno); - if (cert) - return cert; - return NULL; + /* Fixme: We should not use the simple ca-fetch_cert but do a + regular lookup and iterate over all certificates until we found + a matching S/N. */ + while (!cert) + { + ksba_sexp_t sn; + char *issdn; + + err = ca_cert_fetch (ctrl, issuer_dn, &reader); + if (err) + { + log_error (_("error fetching certificate for issuer: %s\n"), + gpg_strerror (err)); + return NULL; + } + + err = ksba_cert_new (&cert); + if (!err) + err = ksba_cert_read_der (cert, reader); + ksba_reader_release (reader); + if (err) + { + log_error (_("invalid issuer certificate: %s\n"), + gpg_strerror (err) ); + ksba_cert_release (cert); + return NULL; + } + + issdn = ksba_cert_get_issuer (cert, 0); + if (strcmp (issuer_dn, issdn)) + { + log_debug ("find_cert_bysn: Ooops: Issuer DN does not match\n"); + ksba_cert_release (cert); + cert = NULL; + ksba_free (issdn); + break; + } + + sn = ksba_cert_get_serial (cert); + if (!compare_serialno (serialno, sn)) + { + ksba_free (sn); + cache_cert (cert); + break; /* Ready. */ + } + + log_debug ("find_cert_bysn: S/N does not match\n"); + ksba_cert_release (cert); + cert = NULL; + ksba_free (sn); + break; /* FIXME: That should be a get next cert. */ + } + + return cert; } @@ -560,7 +616,7 @@ unsigned char fpr[20]; cert_item_t ci; - compute_fpr (cert, fpr); + cert_compute_fpr (cert, fpr); acquire_cache_read_lock (); for (ci=cert_cache[*fpr]; ci; ci = ci->next) @@ -614,7 +670,7 @@ const char *s = ksba_name_enum (authid, 0); if (s && *authidno) { - issuer_cert = find_cert_bysn (s, authidno); + issuer_cert = find_cert_bysn (ctrl, s, authidno); } /* Print a note so that the user does not feel too helpless when an issuer certificate was found and gpgsm prints BAD Index: dirmngr/src/certcache.h diff -u dirmngr/src/certcache.h:1.3 dirmngr/src/certcache.h:1.4 --- dirmngr/src/certcache.h:1.3 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/certcache.h Mon Nov 22 22:30:50 2004 @@ -30,6 +30,9 @@ /* Print some statistics to the log file. */ void cert_cache_print_stats (void); +/* Compute the fingerprint of the certificate CERT and put it into + the 20 bytes large buffer DIGEST. Return address of this buffer. */ +unsigned char *cert_compute_fpr (ksba_cert_t cert, unsigned char *digest); /* Put CERT into the certificate cache. */ gpg_error_t cache_cert (ksba_cert_t cert); @@ -60,4 +63,5 @@ + #endif /*CERTCACHE_H*/ Index: dirmngr/src/crlcache.c diff -u dirmngr/src/crlcache.c:1.48 dirmngr/src/crlcache.c:1.49 --- dirmngr/src/crlcache.c:1.48 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/crlcache.c Mon Nov 22 22:30:50 2004 @@ -105,7 +105,7 @@ #include "cdb.h" /* Change this whenever the format changes */ -#define DBDIR_D "dirmngr-cache.d" +#define DBDIR_D (opt.system_daemon? "crls.d" : "dirmngr-cache.d") #define DBDIRFILE "DIR.txt" #define DBDIRVERSION 1 @@ -194,7 +194,7 @@ DIR *dir; char *fname; - fname = make_filename (opt.homedir, name, NULL); + fname = make_filename (opt.homedir_cache, name, NULL); dir = opendir (fname); if (!dir) { @@ -221,7 +221,7 @@ static int cleanup_cache_dir (int force) { - char *dname = make_filename (opt.homedir, DBDIR_D, NULL); + char *dname = make_filename (opt.homedir_cache, DBDIR_D, NULL); DIR *dir; struct dirent *de; int problem = 0; @@ -489,7 +489,7 @@ gpg_error_t err = 0; int anyerr = 0; - fname = make_filename (opt.homedir, DBDIR_D, DBDIRFILE, NULL); + fname = make_filename (opt.homedir_cache, DBDIR_D, DBDIRFILE, NULL); lineno = 0; fp = open_dir_file (fname); @@ -687,7 +687,7 @@ unsigned int lineno; gpg_error_t err = 0; - fname = make_filename (opt.homedir, DBDIR_D, DBDIRFILE, NULL); + fname = make_filename (opt.homedir_cache, DBDIR_D, DBDIRFILE, NULL); /* Fixme: Take an update file lock here. */ @@ -725,7 +725,7 @@ for (p=tmpbuf; *p; p++) if (*p == '/') *p = '.'; - tmpfname = make_filename (opt.homedir, DBDIR_D, tmpbuf, NULL); + tmpfname = make_filename (opt.homedir_cache, DBDIR_D, tmpbuf, NULL); xfree (tmpbuf); } fpout = fopen (tmpfname, "w"); @@ -859,7 +859,7 @@ memcpy (bname, "crl-", 4); memcpy (bname + 4, issuer_hash, 40); strcpy (bname + 44, ".db"); - return make_filename (opt.homedir, DBDIR_D, bname, NULL); + return make_filename (opt.homedir_cache, DBDIR_D, bname, NULL); } @@ -1129,14 +1129,15 @@ /* Check whether the certificate identified by ISSUER_HASH and - SERIALNO is valid; i.e. not listed in our cache. With + SN/SNLEN is valid; i.e. not listed in our cache. With FORCE_REFRESH set to true, a new CRL will be retrieved even if the cache has not yet expired. We use a 30 minutes threshold here so that invoking this function several times won't load the CRL over and over. */ -crl_cache_result_t -crl_cache_isvalid (ctrl_t ctrl, const char *issuer_hash, const char *serialno, - int force_refresh) +static crl_cache_result_t +cache_isvalid (ctrl_t ctrl, const char *issuer_hash, + const unsigned char *sn, size_t snlen, + int force_refresh) { crl_cache_t cache = get_current_cache (); crl_cache_result_t retval; @@ -1144,8 +1145,6 @@ int rc; crl_cache_entry_t entry; dirmngr_isotime_t current_time; - unsigned char snbuf_buffer[50]; - unsigned char *snbuf; size_t n; entry = find_entry (cache->entries, issuer_hash); @@ -1206,38 +1205,39 @@ return CRL_CACHE_DONTKNOW; } - n = strlen (serialno)/2+1; - if (n < sizeof snbuf_buffer - 1) - snbuf = snbuf_buffer; - else - snbuf = xmalloc (n); - - n = unhexify (snbuf, serialno); - rc = cdb_find (cdb, snbuf, n); + rc = cdb_find (cdb, sn, snlen); if (rc == 1) { n = cdb_datalen (cdb); if (n != 16) - log_error (_("WARNING: invalid cache record length for S/N %s\n"), - serialno ); + { + log_error (_("WARNING: invalid cache record length for S/N ")); + log_printhex ("", sn, snlen); + } else if (opt.verbose) { unsigned char record[16]; + char *tmp = hexify_data (sn, snlen); if (cdb_read (cdb, record, n, cdb_datapos (cdb))) log_error (_("problem reading cache record for S/N %s: %s\n"), - serialno, strerror (errno)); + tmp, strerror (errno)); else log_info (_("S/N %s is not valid; reason=%02X date=%.15s\n"), - serialno, *record, record+1); + tmp, *record, record+1); + xfree (tmp); } retval = CRL_CACHE_INVALID; } else if (!rc) { if (opt.verbose) - log_info (_("S/N %s is valid, it is not listed in the CRL\n"), - serialno ); + { + char *serialno = hexify_data (sn, snlen); + log_info (_("S/N %s is valid, it is not listed in the CRL\n"), + serialno ); + xfree (serialno); + } retval = CRL_CACHE_VALID; } else @@ -1247,15 +1247,123 @@ retval = CRL_CACHE_DONTKNOW; } - if (snbuf != snbuf_buffer) - xfree (snbuf); - unlock_db_file (cache, entry); return retval; } +/* Check whether the certificate identified by ISSUER_HASH and + SERIALNO is valid; i.e. not listed in our cache. With + FORCE_REFRESH set to true, a new CRL will be retrieved even if the + cache has not yet expired. We use a 30 minutes threshold here so + that invoking this function several times won't load the CRL over + and over. */ +crl_cache_result_t +crl_cache_isvalid (ctrl_t ctrl, const char *issuer_hash, const char *serialno, + int force_refresh) +{ + crl_cache_result_t result; + unsigned char snbuf_buffer[50]; + unsigned char *snbuf; + size_t n; + + n = strlen (serialno)/2+1; + if (n < sizeof snbuf_buffer - 1) + snbuf = snbuf_buffer; + else + snbuf = xmalloc (n); + + n = unhexify (snbuf, serialno); + + result = cache_isvalid (ctrl, issuer_hash, snbuf, n, force_refresh); + + if (snbuf != snbuf_buffer) + xfree (snbuf); + + return result; +} + + +/* Check whether the certificate CERT is valid; i.e. not listed in our + cache. With FORCE_REFRESH set to true, a new CRL will be retrieved + even if the cache has not yet expired. We use a 30 minutes + threshold here so that invoking this function several times won't + load the CRL over and over. */ +gpg_error_t +crl_cache_cert_isvalid (ctrl_t ctrl, ksba_cert_t cert, + int force_refresh) +{ + gpg_error_t err; + crl_cache_result_t result; + unsigned char issuerhash[20]; + char issuerhash_hex[41]; + ksba_sexp_t serial; + unsigned char *sn; + size_t snlen; + char *endp, *tmp; + int i; + + /* Compute the hash value of the issuer name. */ + tmp = ksba_cert_get_issuer (cert, 0); + if (!tmp) + { + log_error ("oops: issuer missing in certificate\n"); + return gpg_error (GPG_ERR_INV_CERT_OBJ); + } + gcry_md_hash_buffer (GCRY_MD_SHA1, issuerhash, tmp, strlen (tmp)); + xfree (tmp); + for (i=0,tmp=issuerhash_hex; i < 20; i++, tmp += 2) + sprintf (tmp, "%02X", issuerhash[i]); + + /* Get the serial number. */ + serial = ksba_cert_get_serial (cert); + if (!serial) + { + log_error ("oops: S/N missing in certificate\n"); + return gpg_error (GPG_ERR_INV_CERT_OBJ); + } + sn = serial; + if (*sn != '(') + { + log_error ("oops: invalid S/N\n"); + xfree (serial); + return gpg_error (GPG_ERR_INV_CERT_OBJ); + } + sn++; + snlen = strtoul (sn, &endp, 10); + sn = endp; + if (*sn != ':') + { + log_error ("oops: invalid S/N\n"); + xfree (serial); + return gpg_error (GPG_ERR_INV_CERT_OBJ); + } + sn++; + + /* Check the cache. */ + result = cache_isvalid (ctrl, issuerhash_hex, sn, snlen, force_refresh); + switch (result) + { + case CRL_CACHE_VALID: + err = 0; + break; + case CRL_CACHE_INVALID: + err = gpg_error (GPG_ERR_CERT_REVOKED); + break; + case CRL_CACHE_DONTKNOW: + err = gpg_error (GPG_ERR_NO_CRL_KNOWN); + case CRL_CACHE_CANTUSE: + err = gpg_error (GPG_ERR_NO_CRL_KNOWN); + break; + default: + log_fatal ("cache_isvalid returned invalid status code %d\n", result); + } + + xfree (serial); + return err; +} + /* Return the certificate for ISSUER or NULL if it can't be found. */ static ksba_cert_t @@ -1553,7 +1661,8 @@ gpg_strerror (err)); goto failure; } - err = validate_cert_chain (ctrl, issuer_cert, NULL); + err = validate_cert_chain (ctrl, issuer_cert, + NULL, VALIDATE_MODE_CRL); if (err) { log_error (_("error checking validity of CRL " @@ -1708,7 +1817,7 @@ for (p=tmpfname; *p; p++) if (*p == '/') *p = '.'; - fname = make_filename (opt.homedir, DBDIR_D, tmpfname, NULL); + fname = make_filename (opt.homedir_cache, DBDIR_D, tmpfname, NULL); xfree (tmpfname); if (!remove (fname)) log_info (_("removed stale temporary cache file `%s'\n"), fname); @@ -2040,3 +2149,112 @@ return err; } + +/* Locate the corresponding CRL for the certificate CERT, read and + verify the CRL and store it in the cache. */ +gpg_error_t +crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert) +{ + gpg_error_t err; + ksba_reader_t reader = NULL; + char *issuer = NULL; + ksba_name_t distpoint = NULL; + ksba_name_t issuername = NULL; + char *distpoint_uri = NULL; + char *issuername_uri = NULL; + int any_dist_point = 0; + int seq; + + /* Loop over all distribution points, get the CRLs and put them into + the cache. */ + if (DBG_X509) + log_debug ("checking distribution points\n"); + seq = 0; + while ( !(err = ksba_cert_get_crl_dist_point (cert, seq++, + &distpoint, + &issuername, NULL ))) + { + if (!distpoint && !issuername) + { + if (DBG_X509) + log_debug ("no issuer name and no distribution point\n"); + break; /* Not allowed; i.e. an invalid certificate. We give + up here and hope that the default method returns a + suitable CRL. */ + } + + /* Get the URIs. */ + xfree (distpoint_uri); distpoint_uri = NULL; + xfree (issuername_uri); issuername_uri = NULL; + distpoint_uri = ksba_name_get_uri (distpoint, 0); + issuername_uri = ksba_name_get_uri (issuername, 0); + ksba_name_release (distpoint); distpoint = NULL; + ksba_name_release (issuername); issuername = NULL; + any_dist_point = 1; + + err = crl_fetch (ctrl, distpoint_uri, &reader); + if (err) + { + log_error (_("crl_fetch via DP failed: %s\n"), gpg_strerror (err)); + goto leave; + } + + err = crl_cache_insert (ctrl, distpoint_uri, reader); + if (err) + { + log_error (_("crl_cache_insert via DP failed: %s\n"), + gpg_strerror (err)); + goto leave; + } + } + if (gpg_err_code (err) == GPG_ERR_EOF) + err = 0; + + /* If we did not found any distpoint, try something reasonable. */ + if (!any_dist_point ) + { + if (DBG_X509) + log_debug ("no distribution point - trying issuer name\n"); + + if (reader) + { + crl_close_reader (reader); + reader = NULL; + } + + issuer = ksba_cert_get_issuer (cert, 0); + if (!issuer) + { + log_error ("oops: issuer missing in certificate\n"); + err = gpg_error (GPG_ERR_INV_CERT_OBJ); + goto leave; + } + + err = crl_fetch_default (ctrl, issuer, &reader); + if (err) + { + log_error (_("crl_fetch via issuer failed: %s\n"), + gpg_strerror (err)); + goto leave; + } + + err = crl_cache_insert (ctrl, "default location(s)", reader); + if (err) + { + log_error (_("crl_cache_insert via issuer failed: %s\n"), + gpg_strerror (err)); + goto leave; + } + } + + leave: + if (reader) + crl_close_reader (reader); + xfree (distpoint_uri); + xfree (issuername_uri); + ksba_name_release (distpoint); + ksba_name_release (issuername); + ksba_free (issuer); + return err; +} + Index: dirmngr/src/crlcache.h diff -u dirmngr/src/crlcache.h:1.23 dirmngr/src/crlcache.h:1.24 --- dirmngr/src/crlcache.h:1.23 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/crlcache.h Mon Nov 22 22:30:50 2004 @@ -61,6 +61,9 @@ const char *cert_id, int force_refresh); +gpg_error_t crl_cache_cert_isvalid (ctrl_t ctrl, ksba_cert_t cert, + int force_refresh); + gpg_error_t crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader); @@ -68,5 +71,7 @@ gpg_error_t crl_cache_load (ctrl_t ctrl, const char *filename); +gpg_error_t crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert); + #endif /* CRLCACHE_H */ Index: dirmngr/src/crlfetch.c diff -u dirmngr/src/crlfetch.c:1.20 dirmngr/src/crlfetch.c:1.21 --- dirmngr/src/crlfetch.c:1.20 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/crlfetch.c Mon Nov 22 22:30:50 2004 @@ -67,7 +67,17 @@ { struct http_context_s hd; - err = http_open_document (&hd, url, 0); + if (opt.disable_http) + { + log_error (_("CRL access not possible due to disabled %s\n"), + "HTTP"); + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + } + else + err = http_open_document (&hd, url, + opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0, + opt.http_proxy); + if (err) log_error (_("error retrieving `%s': %s\n"), url, gpg_strerror (err)); else if (hd.status_code != 200) @@ -103,7 +113,15 @@ { const char *s; - err = url_fetch_ldap (ctrl, url, NULL, 0, reader); + if (opt.disable_ldap) + { + log_error (_("CRL access not possible due to disabled %s\n"), + "LDAP"); + err = gpg_error (GPG_ERR_NOT_SUPPORTED); + } + else + err = url_fetch_ldap (ctrl, url, NULL, 0, reader); + /* if (err) */ /* { */ /* /\* If the function failed we try again using our default */ @@ -144,6 +162,12 @@ gpg_error_t crl_fetch_default (ctrl_t ctrl, const char *issuer, ksba_reader_t *reader) { + if (opt.disable_ldap) + { + log_error (_("CRL access not possible due to disabled %s\n"), + "LDAP"); + return gpg_error (GPG_ERR_NOT_SUPPORTED); + } return attr_fetch_ldap (ctrl, issuer, "certificateRevocationList;binary", reader); } @@ -153,6 +177,12 @@ int ca_cert_fetch (ctrl_t ctrl, const char *dn, ksba_reader_t *reader) { + if (opt.disable_ldap) + { + log_error (_("CRL access not possible due to disabled %s\n"), + "LDAP"); + return gpg_error (GPG_ERR_NOT_SUPPORTED); + } return attr_fetch_ldap (ctrl, dn, "cACertificate;binary", reader); } @@ -161,6 +191,12 @@ start_cert_fetch (ctrl_t ctrl, cert_fetch_context_t *context, strlist_t patterns, const ldap_server_t server) { + if (opt.disable_ldap) + { + log_error (_("Certificate search not possible due to disabled %s\n"), + "LDAP"); + return gpg_error (GPG_ERR_NOT_SUPPORTED); + } return start_cert_fetch_ldap (ctrl, context, patterns, server); } Index: dirmngr/src/dirmngr.c diff -u dirmngr/src/dirmngr.c:1.44 dirmngr/src/dirmngr.c:1.45 --- dirmngr/src/dirmngr.c:1.44 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/dirmngr.c Mon Nov 22 22:30:50 2004 @@ -76,6 +76,12 @@ oNoDetach, oLogFile, oBatch, + oDisableHTTP, + oDisableLDAP, + oHonorHTTPProxy, + oHTTPProxy, + oLDAPProxy, + oOnlyLDAPProxy, oLDAPFile, oLDAPTimeout, oLDAPAddServers, @@ -86,6 +92,8 @@ oForce, oAllowOCSP, oSocketName, + oLDAPWrapperProgram, + oHTTPWrapperProgram, aTest }; @@ -117,6 +125,14 @@ { oBatch , "batch" ,0, N_("run without asking a user")}, { oForce, "force" ,0, N_("force loading of outdated CRLs")}, { oAllowOCSP, "allow-ocsp",0,N_("allow sending OCSP requests")}, + { oDisableHTTP, "disable-http", 0, N_("inhibit the use of HTTP")}, + { oDisableLDAP, "disable-ldap", 0, N_("inhibit the use of LDAP")}, + { oHTTPProxy, "http-proxy", 2, + N_("|URL|redirect all HTTP requests to URL")}, + { oLDAPProxy, "ldap-proxy", 2, + N_("|HOST|use HOST for LDAP queries")}, + { oOnlyLDAPProxy, "only-ldap-proxy", 0, + N_("do not use fallback hosts with --ldap-proxy")}, { oLDAPFile, "ldapserverlist-file", 2, N_("|FILE|read LDAP server list from FILE")}, @@ -139,6 +155,9 @@ { oDebugWait, "debug-wait", 1, "@"}, { oNoGreeting, "no-greeting", 0, "@"}, { oHomedir, "homedir", 2, "@" }, + { oLDAPWrapperProgram, "ldap-wrapper-program", 2, "@"}, + { oHTTPWrapperProgram, "http-wrapper-program", 2, "@"}, + { oHonorHTTPProxy, "honor-http-proxy", 0, "@" }, {0} }; @@ -153,6 +172,8 @@ /* Keep track of the current log file so that we can avoid updating the log file after a SIGHUP if it didn't changed. Malloced. */ static char *current_logfile; +/* Name of a config file, which will be reread on a HUP if it is not NULL. */ +static char *config_filename; /* Helper to implement --debug-level. */ static const char *debug_level; /* Flag indicating that a shutdown has been requested. */ @@ -344,6 +365,13 @@ opt.quiet = 0; opt.verbose = 0; opt.debug = 0; + opt.ldap_wrapper_program = NULL; + opt.disable_http = 0; + opt.disable_ldap = 0; + opt.honor_http_proxy = 0; + opt.http_proxy = NULL; + opt.ldap_proxy = NULL; + opt.only_ldap_proxy = 0; return 1; } @@ -367,10 +395,24 @@ } break; + case oLDAPWrapperProgram: + opt.ldap_wrapper_program = pargs->r.ret_str; + break; + case oHTTPWrapperProgram: + opt.http_wrapper_program = pargs->r.ret_str; + break; + + case oDisableHTTP: opt.disable_http = 1; break; + case oDisableLDAP: opt.disable_ldap = 1; break; + case oHonorHTTPProxy: opt.honor_http_proxy = 1; break; + case oHTTPProxy: opt.http_proxy = pargs->r.ret_str; break; + case oLDAPProxy: opt.ldap_proxy = pargs->r.ret_str; break; + case oOnlyLDAPProxy: opt.only_ldap_proxy = 1; break; + default: return 0; /* Not handled. */ } - set_debug (); + return 1; /* Handled. */ } @@ -396,7 +438,6 @@ int debug_wait = 0; int rc; int homedir_seen = 0; - int daemon_seen = 0; set_strusage (my_strusage); log_set_prefix ("dirmngr", 1|4); @@ -458,6 +499,9 @@ #endif } + /* Reset rereadable options to default values. */ + parse_rereadable_options (NULL, 0); + /* LDAP defaults */ opt.add_new_ldapservers = 0; opt.ldaptimeout.tv_sec = DEFAULT_LDAP_TIMEOUT; @@ -494,14 +538,18 @@ homedir_seen = 1; } else if (pargs.r_opt == aDaemon) - daemon_seen = 1; + opt.system_daemon = 1; } /* If --daemon has been given on the command line but not --homedir, we switch to /etc/dirmngr as default home directory. Note, that this also overrides the GNUPGHOME environment variable. */ - if (daemon_seen && !homedir_seen) - opt.homedir = DIRMNGR_SYSCONFDIR; + if (opt.system_daemon && !homedir_seen) + { + opt.homedir = DIRMNGR_SYSCONFDIR; + opt.homedir_data = DIRMNGR_DATADIR; + opt.homedir_cache = DIRMNGR_CACHEDIR; + } if (default_config) configname = make_filename (opt.homedir, "dirmngr.conf", NULL ); @@ -608,7 +656,8 @@ { fclose( configfp ); configfp = NULL; - xfree(configname); + /* Keep a copy of the name so that it can be read on SIGHUP. */ + config_filename = configname; configname = NULL; goto next_pass; } @@ -619,6 +668,11 @@ if (nogreeting ) greeting = 0; + if (!opt.homedir_data) + opt.homedir_data = opt.homedir; + if (!opt.homedir_cache) + opt.homedir_cache = opt.homedir; + if (greeting) { fprintf (stderr, "%s %s; %s\n", @@ -642,7 +696,10 @@ /* Get LDAP server list from file. */ if (!ldapfile) { - ldapfile = make_filename (opt.homedir, "dirmngr_ldapservers.conf", NULL); + ldapfile = make_filename (opt.homedir, + opt.system_daemon? + "ldapservers.conf":"dirmngr_ldapservers.conf", + NULL); opt.ldapservers = parse_ldapserver_file (ldapfile); xfree (ldapfile); } @@ -896,7 +953,6 @@ else if (cmd == aGPGConfList) { char *filename; - /* List options and default values in the GPG Conf format. */ /* The following list is taken from gnupg/tools/gpgconf-comp.c. */ @@ -915,10 +971,11 @@ /* First the configuration file. This is not an option, but it is vital information for GPG Conf. */ - filename = make_filename (opt.homedir, "dirmngr.conf", NULL); + if (!config_filename) + config_filename = make_filename (opt.homedir, "dirmngr.conf", NULL ); + printf ("gpgconf-dirmngr.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, filename); - xfree (filename); + GC_OPT_FLAG_DEFAULT, config_filename); printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE); printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE); @@ -932,7 +989,10 @@ and having both of them is thus problematic. --no-detach is also only usable on the command line. --batch is unused. */ - filename = make_filename (opt.homedir, "dirmngr_ldapservers.conf", NULL); + filename = make_filename (opt.homedir, + opt.system_daemon? + "ldapservers.conf":"dirmngr_ldapservers.conf", + NULL); printf ("ldapserverlist-file:%lu:\"%s\n", GC_OPT_FLAG_DEFAULT, filename); xfree (filename); @@ -946,6 +1006,13 @@ printf ("faked-system-time:%lu:\n", GC_OPT_FLAG_NONE); printf ("no-greeting:%lu:\n", GC_OPT_FLAG_NONE); + + printf ("disable-http:%lu:\n", GC_OPT_FLAG_NONE); + printf ("disable-ldap:%lu:\n", GC_OPT_FLAG_NONE); + printf ("http-proxy:%lu:\n", GC_OPT_FLAG_NONE); + printf ("ldap-proxy:%lu:\n", GC_OPT_FLAG_NONE); + printf ("only-ldap-proxy:%lu:\n", GC_OPT_FLAG_NONE); + } cleanup (); return !!rc; @@ -1140,6 +1207,57 @@ /* Stuff used in daemon mode. */ + + + +/* Reread parts of the configuration. Note, that this function is + obviously not thread-safe and should only be called from the PTH + signal handler. + + Fixme: Due to the way the argument parsing works, we create a + memory leak here for all string type arguments. There is currently + no clean way to tell whether the memory for the argument has been + allocated or points into the process' original arguments. Unless + we have a mechanism to tell this, we need to live on with this. */ +static void +reread_configuration (void) +{ + ARGPARSE_ARGS pargs; + FILE *fp; + unsigned int configlineno = 0; + int dummy; + + if (!config_filename) + return; /* No config file. */ + + fp = fopen (config_filename, "r"); + if (!fp) + { + log_error (_("option file `%s': %s\n"), + config_filename, strerror(errno) ); + return; + } + + parse_rereadable_options (NULL, 1); /* Start from the default values. */ + + memset (&pargs, 0, sizeof pargs); + dummy = 0; + pargs.argc = &dummy; + pargs.flags = 1; /* do not remove the args */ + while (optfile_parse (fp, config_filename, &configlineno, &pargs, opts) ) + { + if (pargs.r_opt < -1) + pargs.err = 1; /* Print a warning. */ + else /* Try to parse this option - ignore unchangeable ones. */ + parse_rereadable_options (&pargs, 1); + } + fclose (fp); + + set_debug (); +} + + + /* The signal handler. */ static void handle_signal (int signo) @@ -1149,7 +1267,7 @@ case SIGHUP: log_info (_("SIGHUP received - " "re-reading configuration and flushing caches\n")); -/* reread_configuration (); */ + reread_configuration (); cert_cache_deinit (0); crl_cache_deinit (); cert_cache_init (); Index: dirmngr/src/dirmngr.h diff -u dirmngr/src/dirmngr.h:1.20 dirmngr/src/dirmngr.h:1.21 --- dirmngr/src/dirmngr.h:1.20 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/dirmngr.h Mon Nov 22 22:30:50 2004 @@ -67,12 +67,27 @@ int quiet; /* be as quiet as possible */ int dry_run; /* don't change any persistent data */ int batch; /* batch mode */ - const char *homedir;/* configuration directory name */ + const char *homedir; /* Configuration directory name */ + const char *homedir_data; /* Ditto for data files (/usr/share/dirmngr). */ + const char *homedir_cache; /* Ditto for cache files (/var/cache/dirmngr). */ + + char *ldap_wrapper_program; /* Override value for the LDAP wrapper + program. */ + char *http_wrapper_program; /* Override value for the HTTP wrapper + program. */ + int system_daemon; /* We are running in system daemon mode. */ int running_detached; /* We are running in detached mode. */ int force; /* Force loading outdated CRLs. */ + int disable_http; /* Do not use HTTP at all. */ + int disable_ldap; /* Do not use LDAP at all. */ + int honor_http_proxy; /* Honor the http_proxy env variable. */ + const char *http_proxy; /* Use given HTTP proxy. */ + const char *ldap_proxy; /* Use given LDAP proxy. */ + int only_ldap_proxy; /* Only use the LDAP proxy; no fallback. */ + int allow_ocsp; /* Allow using OCSP. */ int max_replies; Index: dirmngr/src/dirmngr_ldap.c diff -u dirmngr/src/dirmngr_ldap.c:1.2 dirmngr/src/dirmngr_ldap.c:1.3 --- dirmngr/src/dirmngr_ldap.c:1.2 Thu Nov 18 16:37:48 2004 +++ dirmngr/src/dirmngr_ldap.c Mon Nov 22 22:30:50 2004 @@ -54,6 +54,7 @@ oTimeout = 500, oMulti, + oProxy, oHost, oPort, oUser, @@ -74,6 +75,8 @@ { oTimeout, "timeout", 1, N_("|N|set LDAP timeout to N seconds")}, { oMulti, "multi", 0, N_("return all values in" " a record oriented format")}, + { oProxy, "proxy", 2, + N_("|NAME|ignore host part and connect through NAME")}, { oHost, "host", 2, N_("|NAME|connect to host NAME")}, { oPort, "port", 1, N_("|N|connect to port N")}, { oUser, "user", 2, N_("|NAME|use user NAME for authentication")}, @@ -97,6 +100,7 @@ /* Note that we can't use const for the strings because ldap_* are not defined that way. */ + char *proxy; /* Host and Port override. */ char *user; /* Authentication user. */ char *pass; /* Authentication password. */ char *host; /* Override host. */ @@ -165,6 +169,7 @@ { ARGPARSE_ARGS pargs; int any_err = 0; + char *p; set_strusage (my_strusage); log_set_prefix ("dirmngr_ldap", JNLIB_LOG_WITH_PREFIX); @@ -197,6 +202,7 @@ case oEnvPass: opt.pass = getenv ("DIRMNGR_LDAP_PASS"); break; + case oProxy: opt.proxy = pargs.r.ret_str; break; case oHost: opt.host = pargs.r.ret_str; break; case oPort: opt.port = pargs.r.ret_int; break; case oDN: opt.dn = pargs.r.ret_str; break; @@ -206,6 +212,20 @@ default : pargs.err = 2; break; } } + + if (opt.proxy) + { + opt.host = xstrdup (opt.proxy); + p = strchr (opt.host, ':'); + if (p) + { + *p++ = 0; + opt.port = atoi (p); + } + if (!opt.port) + opt.port = 389; /* make sure ports gets overridden. */ + } + if (opt.port < 0 || opt.port > 65535) log_error (_("invalid port number %d\n"), opt.port); @@ -215,6 +235,7 @@ if (argc < 1) usage (1); + for (; argc; argc--, argv++) if (process_url (*argv)) any_err = 1; Index: dirmngr/src/http.c diff -u dirmngr/src/http.c:1.6 dirmngr/src/http.c:1.7 --- dirmngr/src/http.c:1.6 Tue Nov 16 19:24:35 2004 +++ dirmngr/src/http.c Mon Nov 22 22:30:50 2004 @@ -1,5 +1,5 @@ /* http.c - HTTP protocol handler - * Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc. + * Copyright (C) 1999, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -63,7 +63,7 @@ static int insert_escapes (unsigned char *buffer, const unsigned char *string, const unsigned char *special); static uri_tuple_t parse_tuple (unsigned char *string); -static gpg_error_t send_request (http_t hd); +static gpg_error_t send_request (http_t hd, const char *proxy); static unsigned char *build_rel_path (parsed_uri_t uri); static gpg_error_t parse_response (http_t hd); @@ -72,7 +72,8 @@ gpg_error_t -http_open (http_t hd, http_req_t reqtype, const char *url, unsigned int flags) +http_open (http_t hd, http_req_t reqtype, const char *url, unsigned int flags, + const char *proxy) { gpg_error_t err; @@ -89,7 +90,7 @@ err = http_parse_uri (&hd->uri, url); if (!err) { - err = send_request (hd); + err = send_request (hd, proxy); if (!err) { hd->fp_write = fdopen (hd->sock, "w"); @@ -156,13 +157,16 @@ /* Convenience function to send a request and wait for the response. - Closes the handle on error. */ + Closes the handle on error. If PROXY is not NULL, this value will + be used as a HTTP proxy and any enabled $http_proxy gets + ignored. */ gpg_error_t -http_open_document (http_t hd, const char *document, unsigned int flags) +http_open_document (http_t hd, const char *document, unsigned int flags, + const char *proxy) { gpg_error_t err; - err = http_open (hd, HTTP_REQ_GET, document, flags); + err = http_open (hd, HTTP_REQ_GET, document, flags, proxy); if (err) return err; @@ -444,7 +448,7 @@ * Returns 0 if the request was successful */ static gpg_error_t -send_request (http_t hd) +send_request (http_t hd, const char *proxy) { const unsigned char *server; unsigned char *request, *p; @@ -456,17 +460,20 @@ server = *hd->uri->host ? hd->uri->host : "localhost"; port = hd->uri->port ? hd->uri->port : 80; - if ((hd->flags & HTTP_FLAG_TRY_PROXY) - && (http_proxy = getenv (HTTP_PROXY_ENV))) + if (proxy + || ( (hd->flags & HTTP_FLAG_TRY_PROXY) + && (http_proxy = getenv (HTTP_PROXY_ENV)))) { parsed_uri_t uri; + + if (proxy) + http_proxy = proxy; err = http_parse_uri (&uri, http_proxy); if (err) { - log_error (_("invalid %s: %s\n"), - HTTP_PROXY_ENV_PRINTABLE, - gpg_strerror (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); } Index: dirmngr/src/http.h diff -u dirmngr/src/http.h:1.1 dirmngr/src/http.h:1.2 --- dirmngr/src/http.h:1.1 Fri Dec 12 18:36:49 2003 +++ dirmngr/src/http.h Mon Nov 22 22:30:50 2004 @@ -76,12 +76,14 @@ void http_release_parsed_uri (parsed_uri_t uri); gpg_error_t http_open (http_t hd, http_req_t reqtype, - const char *url, unsigned int flags ); + const char *url, unsigned int flags, + const char *proxy); void http_start_data (http_t hd); gpg_error_t http_wait_response (http_t hd, unsigned int *ret_status); void http_close (http_t hd, int keep_read_stream); gpg_error_t http_open_document (http_t hd, - const char *document, unsigned int flags); + const char *document, unsigned int flags, + const char *proxy); #endif /*HTTP_H*/ Index: dirmngr/src/ldap.c diff -u dirmngr/src/ldap.c:1.35 dirmngr/src/ldap.c:1.36 --- dirmngr/src/ldap.c:1.35 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/ldap.c Mon Nov 22 22:30:50 2004 @@ -1,6 +1,6 @@ /* ldap.c - LDAP access * Copyright (C) 2002 Klarälvdalens Datakonsult AB - * Copyright (C) 2003 g10 Code GmbH + * Copyright (C) 2003, 2004 g10 Code GmbH * * This file is part of DirMngr. * @@ -541,11 +541,16 @@ if (!pid) { /* Child. */ - char *pgmname = "/home/wk/w/dirmngr/src/dirmngr_ldap"; /*FIXME*/ + char *pgmname; char **arg_list; int n, i, j; int fd; + if (!opt.ldap_wrapper_program || !*opt.ldap_wrapper_program) + pgmname = DIRMNGR_LIBEXECDIR "/ldap_wrapper"; + else + pgmname = opt.ldap_wrapper_program; + /* Create command line argument array. */ for (i=0; argv[i]; i++) ; @@ -658,6 +663,7 @@ The function returns a new stream at R_FP. */ static gpg_error_t run_ldap_wrapper (ctrl_t ctrl, + const char *proxy, const char *host, int port, const char *user, const char *pass, const char *dn, const char *filter, const char *attr, @@ -678,6 +684,11 @@ } if (opt.verbose) argv[argc++] = "-vv"; + if (proxy) + { + argv[argc++] = "--proxy"; + argv[argc++] = proxy; + } if (host) { argv[argc++] = "--host"; @@ -725,12 +736,16 @@ url_fetch_ldap (ctrl_t ctrl, const char *url, const char *host, int port, ksba_reader_t *reader) { - return run_ldap_wrapper (ctrl, - host, port, - NULL, NULL, - NULL, NULL, NULL, url, - reader); + gpg_error_t err; + err = run_ldap_wrapper (ctrl, + opt.ldap_proxy, + host, port, + NULL, NULL, + NULL, NULL, NULL, url, + reader); + + return err; /* FIXME: This option might be used for DoS attacks. Becuase it will enlarge the list of servers to consult without a limit and all LDAP queries w/o a host are will then try each host in @@ -754,6 +769,7 @@ for (server = opt.ldapservers; server; server = server->next) { err = run_ldap_wrapper (ctrl, + opt.ldap_proxy, server->host, server->port, server->user, server->pass, dn, "objectClass=*", attr, NULL, @@ -978,6 +994,11 @@ if (opt.verbose) argv[argc++] = "-vv"; argv[argc++] = "--multi"; + if (opt.ldap_proxy) + { + argv[argc++] = "--proxy"; + argv[argc++] = opt.ldap_proxy; + } if (host) { argv[argc++] = "--host"; Index: dirmngr/src/ocsp.c diff -u dirmngr/src/ocsp.c:1.9 dirmngr/src/ocsp.c:1.10 --- dirmngr/src/ocsp.c:1.9 Wed Aug 18 18:41:42 2004 +++ dirmngr/src/ocsp.c Mon Nov 22 22:30:50 2004 @@ -27,6 +27,7 @@ #include "dirmngr.h" #include "misc.h" #include "http.h" +#include "validate.h" #include "ocsp.h" @@ -112,8 +113,13 @@ struct http_context_s http; ksba_ocsp_response_status_t response_status; const char *t; - - + + if (opt.disable_http) + { + log_error (_("OCSP request not possible due to disabled HTTP\n")); + return gpg_error (GPG_ERR_NOT_SUPPORTED); + } + err = ksba_ocsp_add_target (ocsp, cert, issuer_cert); if (err) { @@ -139,7 +145,9 @@ return err; } - err = http_open (&http, HTTP_REQ_POST, url, 0); + err = http_open (&http, HTTP_REQ_POST, url, + opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0, + opt.http_proxy); if (err) { log_error (_("error connecting to `%s': %s\n"), url, gpg_strerror (err)); @@ -236,29 +244,38 @@ static gpg_error_t validate_responder_cert (ctrl_t ctrl, ksba_cert_t cert) { + gpg_error_t err; char *fpr; - /* We avoid duplicating the entire certificate validation code from - gpgsm here. Because we have no way calling back to the client - and letting it compute the validity, we use the ugly hack of - telling the client that the response will only be valid if the - certificate given in this status message is valid. - - Note, that in theory we could simply ask the client via an - inquire to validate a certificate but this might involve calling - DirMngr again recursivly - we can't do that as of now (neither - DirMngr nor gpgsm have the ability for concurrent access to - DirMngr. - */ - - /* FIXME: We should cache this certificate locally, so that the next - call to dirmngr won't need to look it up - if this works at - all. */ - fpr = get_fingerprint_hexstring (cert); - dirmngr_status (ctrl, "ONLY_VALID_IF_CERT_VALID", fpr, NULL); - xfree (fpr); + if (opt.system_daemon) + { + err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_OCSP); + } + else + { + /* We avoid duplicating the entire certificate validation code + from gpgsm here. Because we have no way calling back to the + client and letting it compute the validity, we use the ugly + hack of telling the client that the response will only be + valid if the certificate given in this status message is + valid. + + Note, that in theory we could simply ask the client via an + inquire to validate a certificate but this might involve + calling DirMngr again recursivly - we can't do that as of now + (neither DirMngr nor gpgsm have the ability for concurrent + access to DirMngr. */ + + /* FIXME: We should cache this certificate locally, so that the next + call to dirmngr won't need to look it up - if this works at + all. */ + fpr = get_fingerprint_hexstring (cert); + dirmngr_status (ctrl, "ONLY_VALID_IF_CERT_VALID", fpr, NULL); + xfree (fpr); + err = 0; + } - return 0; + return err; } Index: dirmngr/src/server.c diff -u dirmngr/src/server.c:1.45 dirmngr/src/server.c:1.46 --- dirmngr/src/server.c:1.45 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/server.c Mon Nov 22 22:30:50 2004 @@ -83,8 +83,8 @@ target string D as long as the source string S, i.e.: strlen(s)+1. NOte further that If S contains an escaped binary nul the resulting string D will contain the 0 as well as all other characters but it - will be impossible to kno whether this is the original eos or a - copied nul. */ + will be impossible to know whether this is the original EOS or a + copied Nul. */ static void strcpy_escaped_plus (char *d, const unsigned char *s) { @@ -190,114 +190,6 @@ } -/* Locate the corresponding CRL for the certificate CERT, read and - verify the CRL and store it in the cache. */ -static int -reload_crl (ctrl_t ctrl, ksba_cert_t cert) -{ - gpg_error_t err; - ksba_reader_t reader = NULL; - char *issuer = NULL; - ksba_name_t distpoint = NULL; - ksba_name_t issuername = NULL; - char *distpoint_uri = NULL; - char *issuername_uri = NULL; - int any_dist_point = 0; - int seq; - - /* Loop over all distribution points, get the CRLs and put them into - the cache. */ - if (DBG_X509) - log_debug ("checking distribution points\n"); - seq = 0; - while ( !(err = ksba_cert_get_crl_dist_point (cert, seq++, - &distpoint, - &issuername, NULL ))) - { - if (!distpoint && !issuername) - { - if (DBG_X509) - log_debug ("no issuer name and no distribution point\n"); - break; /* Not allowed; i.e. an invalid certificate. We give - up here and hope that the default method returns a - suitable CRL. */ - } - - /* Get the URIs. */ - xfree (distpoint_uri); distpoint_uri = NULL; - xfree (issuername_uri); issuername_uri = NULL; - distpoint_uri = ksba_name_get_uri (distpoint, 0); - issuername_uri = ksba_name_get_uri (issuername, 0); - ksba_name_release (distpoint); distpoint = NULL; - ksba_name_release (issuername); issuername = NULL; - any_dist_point = 1; - - err = crl_fetch (ctrl, distpoint_uri, &reader); - if (err) - { - log_error (_("crl_fetch via DP failed: %s\n"), gpg_strerror (err)); - goto leave; - } - - err = crl_cache_insert (ctrl, distpoint_uri, reader); - if (err) - { - log_error (_("crl_cache_insert via DP failed: %s\n"), - gpg_strerror (err)); - goto leave; - } - } - if (gpg_err_code (err) == GPG_ERR_EOF) - err = 0; - - /* If we did not found any distpoint, try something reasonable. */ - if (!any_dist_point ) - { - if (DBG_X509) - log_debug ("no distribution point - trying issuer name\n"); - - if (reader) - { - crl_close_reader (reader); - reader = NULL; - } - - issuer = ksba_cert_get_issuer (cert, 0); - if (!issuer) - { - log_error ("oops: issuer missing in certificate\n"); - err = gpg_error (GPG_ERR_INV_CERT_OBJ); - goto leave; - } - - err = crl_fetch_default (ctrl, issuer, &reader); - if (err) - { - log_error (_("crl_fetch via issuer failed: %s\n"), - gpg_strerror (err)); - goto leave; - } - - err = crl_cache_insert (ctrl, "default location(s)", reader); - if (err) - { - log_error (_("crl_cache_insert via issuer failed: %s\n"), - gpg_strerror (err)); - goto leave; - } - } - - leave: - if (reader) - crl_close_reader (reader); - xfree (distpoint_uri); - xfree (issuername_uri); - ksba_name_release (distpoint); - ksba_name_release (issuername); - ksba_free (issuer); - return err; -} - /* Ask the client to return the certificate asscociated with the @@ -336,7 +228,7 @@ goto leave; xfree (value); value = NULL; - err = reload_crl (ctrl, cert); + err = crl_cache_reload_crl (ctrl, cert); leave: ksba_cert_release (cert); @@ -526,10 +418,7 @@ ctrl_t ctrl = assuan_get_pointer (ctx); gpg_error_t err; unsigned char fprbuffer[20], *fpr; - unsigned char issuerhash[20]; - char issuerhash_hex[41]; ksba_cert_t cert; - char *serialno = NULL; fpr = get_fingerprint_from_line (line, fprbuffer); cert = fpr? get_cert_byfpr (fpr) : NULL; @@ -566,113 +455,18 @@ assert (cert); - /* Compute the hash value of the issuer name. */ - { - char *tmp; - int i; - - tmp = ksba_cert_get_issuer (cert, 0); - if (!tmp) - { - log_error ("oops: issuer missing in certificate\n"); - err = gpg_error (GPG_ERR_INV_CERT_OBJ); - goto leave; - } - gcry_md_hash_buffer (GCRY_MD_SHA1, issuerhash, tmp, strlen (tmp)); - xfree (tmp); - for (i=0,tmp=issuerhash_hex; i < 20; i++, tmp += 2) - sprintf (tmp, "%02X", issuerhash[i]); - } - - /* FIXME: We don't have a suitable check function so we need to format the - S/N as string first. */ - { - ksba_sexp_t serial; - unsigned char *p; - unsigned long n; - char *endp, *tmp; - int i; - - serial = ksba_cert_get_serial (cert); - if (!serial) - { - log_error ("oops: S/N missing in certificate\n"); - err = gpg_error (GPG_ERR_INV_CERT_OBJ); - goto leave; - } - p = serial; - if (*p != '(') - { - log_error ("oops: invalid S/N\n"); - err = gpg_error (GPG_ERR_INV_CERT_OBJ); - xfree (serial); - goto leave; - } - p++; - n = strtoul (p, &endp, 10); - p = endp; - if (*p != ':') - { - log_error ("oops: invalid S/N\n"); - err = gpg_error (GPG_ERR_INV_CERT_OBJ); - xfree (serial); - goto leave; - } - p++; - - serialno = tmp = xtrymalloc (n*2 + 1); - if (!serialno) - { - err = gpg_error_from_errno (errno); - xfree (serial); - goto leave; - } - - for (i=0; i < n; i++, tmp += 2) - sprintf (tmp, "%02X", p[i]); - *tmp = 0; - xfree (serial); - } - - /* Now use our old function to do the actual CRL check. */ - { - int reloaded = 0; - - again: - switch (crl_cache_isvalid (ctrl, - issuerhash_hex, serialno, - ctrl->force_crl_refresh)) - { - case CRL_CACHE_VALID: - err = 0; - break; - case CRL_CACHE_INVALID: - err = gpg_error (GPG_ERR_CERT_REVOKED); - break; - case CRL_CACHE_DONTKNOW: - if (reloaded) - err = gpg_error (GPG_ERR_NO_CRL_KNOWN); - else - { - reloaded = 1; - err = reload_crl (ctrl, cert); - if (!err) - goto again; - } - break; - case CRL_CACHE_CANTUSE: - err = gpg_error (GPG_ERR_NO_CRL_KNOWN); - break; - default: - log_fatal ("crl_cache_isvalid returned invalid status code\n"); - } - } + err = crl_cache_cert_isvalid (ctrl, cert, ctrl->force_crl_refresh); + if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN) + { + err = crl_cache_reload_crl (ctrl, cert); + if (!err) + err = crl_cache_cert_isvalid (ctrl, cert, 0); + } leave: if (err) log_error (_("command %s failed: %s\n"), "CHECKCRL", gpg_strerror (err)); ksba_cert_release (cert); - xfree (serialno); return map_to_assuan_status (err); } @@ -1001,7 +795,7 @@ if(err) goto leave; - err = validate_cert_chain (ctrl, cert, NULL); + err = validate_cert_chain (ctrl, cert, NULL, VALIDATE_MODE_CRL_RECURSIVE); leave: if (err) Index: dirmngr/src/validate.c diff -u dirmngr/src/validate.c:1.3 dirmngr/src/validate.c:1.4 --- dirmngr/src/validate.c:1.3 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/validate.c Mon Nov 22 22:30:50 2004 @@ -31,9 +31,24 @@ #include "dirmngr.h" #include "certcache.h" +#include "crlcache.h" #include "validate.h" #include "misc.h" +/* While running the validation function we need to keep tarckl of the + cretificates and the validation outcome of each. We use this type + for it. */ +struct chain_item_s +{ + ksba_cert_t cert; /* The certificate. */ + unsigned char fpr[20]; /* Fingerprint of the certificate. */ + int is_self_signed; /* This certificate is self-signed. */ + int is_valid; /* The certifiate is valid except for revocations. */ +}; +typedef struct chain_item_s *chain_item_t; + + +/* A couple of constants with Object Identifiers. */ static const char oid_kp_serverAuth[] = "1.3.6.1.5.5.7.3.1"; static const char oid_kp_clientAuth[] = "1.3.6.1.5.5.7.3.2"; static const char oid_kp_codeSigning[] = "1.3.6.1.5.5.7.3.3"; @@ -42,7 +57,7 @@ static const char oid_kp_ocspSigning[] = "1.3.6.1.5.5.7.3.9"; - +/* Prototypes. */ static gpg_error_t check_cert_sig (ksba_cert_t issuer_cert, ksba_cert_t cert); @@ -165,34 +180,88 @@ return 0; } +/* Helper for validate_cert_chain. IDX is the index to the last + element in the chain and NOT the length of the chain. */ +static gpg_error_t +check_revocations (ctrl_t ctrl, chain_item_t *chain, int idx) +{ + gpg_error_t err = 0; + int any_revoked = 0; + int any_no_crl = 0; + int any_crl_too_old = 0; + + + assert (idx >=0); + if (!idx && !chain[0]->cert) + return 0; /* Target certificate is a trusted root certificate. */ + + for (;idx >= 0 && !err; idx--) + { + assert (chain[idx]->cert); + + err = crl_cache_cert_isvalid (ctrl, chain[idx]->cert, 0); + if (gpg_err_code (err) == GPG_ERR_NO_CRL_KNOWN) + { + err = crl_cache_reload_crl (ctrl, chain[idx]->cert); + if (!err) + err = crl_cache_cert_isvalid (ctrl, chain[idx]->cert, 0); + } + switch (gpg_err_code (err)) + { + case 0: err = 0; break; + case GPG_ERR_CERT_REVOKED: any_revoked = 1; err = 0; break; + case GPG_ERR_NO_CRL_KNOWN: any_no_crl = 1; err = 0; break; + case GPG_ERR_CRL_TOO_OLD: any_crl_too_old = 1; err = 0; break; + default: break; + } + } + + + if (err) + ; + else if (any_revoked) + err = gpg_error (GPG_ERR_CERT_REVOKED); + else if (any_no_crl) + err = gpg_error (GPG_ERR_NO_CRL_KNOWN); + else if (any_crl_too_old) + err = gpg_error (GPG_ERR_CRL_TOO_OLD); + else + err = 0; + return err; +} + + /* Validate the certificate CHAIN up to the trust anchor. Optionally return the closest expiration time in R_EXPTIME (this is useful for - caching issues). */ - - /* FIXME: We need to check for evoked certifciates too. */ + caching issues). MODE is one of the VALIDATE_MODE_* constants. */ gpg_error_t -validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime) +validate_cert_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime, + int mode) { gpg_error_t err = 0; - int depth = 0, maxdepth; + int depth, maxdepth; char *issuer = NULL; char *subject = NULL; ksba_cert_t subject_cert = NULL, issuer_cert = NULL; ksba_isotime_t current_time; ksba_isotime_t exptime; int any_expired = 0; - int any_revoked = 0; - int any_no_crl = 0; - int any_crl_too_old = 0; int any_no_policy_match = 0; + chain_item_t *chain; + - /* Get the current time. */ - get_isotime (current_time); if (r_exptime) *r_exptime = 0; *exptime = 0; + if (opt.system_daemon) + return 0; /* For backward compatibility we only do this in daemon + mode. */ + + /* Get the current time. */ + get_isotime (current_time); + if (DBG_X509) dump_cert ("subject", cert); @@ -200,6 +269,11 @@ subject_cert = cert; maxdepth = 50; + chain = xtrycalloc (maxdepth+1, sizeof *chain); + if (!chain) + return gpg_error_from_errno (errno); + depth = 0; + for (;;) { /* Get the subject and issuer name from the current @@ -273,7 +347,7 @@ if (gpg_err_code (err) == GPG_ERR_NO_POLICY_MATCH) { any_no_policy_match = 1; - err = 1; /*???? FIXME*/ + err = 0; } else if (err) goto leave; @@ -293,7 +367,6 @@ err = allowed_ca (subject_cert, NULL); if (err) goto leave; /* No. */ - err = is_trusted_cert (subject_cert); if (!err) @@ -317,8 +390,6 @@ if (err) goto leave; - /* FIXME: Now check whether this certificate has been revoked. */ - break; /* Okay: a self-signed certicate is an end-point. */ } @@ -425,8 +496,12 @@ err = cert_use_cert_p (issuer_cert); if (err) goto leave; /* No. */ - - /* FIXME: Now check whether this certificate has been revoked. */ + + /* Append the certificate to our list. */ + assert (depth <= maxdepth); + ksba_cert_ref (subject_cert); + chain[depth]->cert = subject_cert; + cert_compute_fpr (subject_cert, chain[depth]->fpr); if (opt.verbose) log_info ("certificate is good\n"); @@ -439,17 +514,52 @@ if (!err) { /* If we encountered an error somewhere during the checks, set the error code to the most critical one */ - if (any_revoked) - err = gpg_error (GPG_ERR_CERT_REVOKED); - else if (any_expired) + if (any_expired) err = gpg_error (GPG_ERR_CERT_EXPIRED); - else if (any_no_crl) - err = gpg_error (GPG_ERR_NO_CRL_KNOWN); - else if (any_crl_too_old) - err = gpg_error (GPG_ERR_CRL_TOO_OLD); else if (any_no_policy_match) err = gpg_error (GPG_ERR_NO_POLICY_MATCH); } + + + /* May the certificate be used for OCSP response signing. */ + if (mode == VALIDATE_MODE_OCSP && chain[0]->cert) + { + err = cert_use_ocsp_p (chain[0]->cert); + } + + /* May the certificate be used for CR signing. */ + + /* FIXME. */ + + + if (!err) + { /* Now that everything is fine, walk the chain and check each + certificate for revocations. + + chain[0] - The target certificate. + chain[1] - The CA which signed chain[0] + ... + chain[depth] - The CA which signed chain[depth-1]. + + Note that we do not include the root certificate in this list + because we axiomatically know that it is trusted and there is + no point to do futher investigations. DEPTH might be zero in + case the target certificate is directly signed by the root + certificate or there might even be no list at all (DEPTH is 0 + and chain[0]->cert is NULL) if the target certificate is the + root certificate. + + Now for each certificate in the chain check whether it has + been included in a CRL and thus be revoked. We don't do OCSP + here because this does not seem to make much sense. This + might become a recursive process and we should better cache + our validity results to avoid double work. Far worse a + catch-22 may happen for an improper setup hierachy and we + need a way to break up this deadlock. */ + + err = check_revocations (ctrl, chain, depth); + } + leave: if (r_exptime) @@ -458,6 +568,10 @@ ksba_cert_release (issuer_cert); if (subject_cert != cert) ksba_cert_release (subject_cert); + for (; depth; depth--) + if (chain[depth]->cert) + ksba_cert_release (chain[depth]->cert); + xfree (chain); return err; } Index: dirmngr/src/validate.h diff -u dirmngr/src/validate.h:1.2 dirmngr/src/validate.h:1.3 --- dirmngr/src/validate.h:1.2 Fri Nov 19 16:27:28 2004 +++ dirmngr/src/validate.h Mon Nov 22 22:30:50 2004 @@ -22,10 +22,18 @@ #define VALIDATE_H +enum { + VALIDATE_MODE_CRL = 1, + VALIDATE_MODE_CRL_RECURSIVE = 2, + VALIDATE_MODE_OCSP = 3 +}; + + /* Validate the certificate CHAIN up to the trust anchor. Optionally return the closest expiration time in R_EXPTIME. */ gpg_error_t validate_cert_chain (ctrl_t ctrl, - ksba_cert_t cert, ksba_isotime_t r_exptime); + ksba_cert_t cert, ksba_isotime_t r_exptime, + int mode); /* Return 0 if the certificate CERT is usable for certification. */ gpg_error_t cert_use_cert_p (ksba_cert_t cert); From cvs at cvs.gnupg.org Wed Nov 24 13:19:08 2004 From: cvs at cvs.gnupg.org (cvs user wk) Date: Thu Dec 2 16:37:02 2004 Subject: dirmngr (15 files) Message-ID: Date: Wednesday, November 24, 2004 @ 13:25:53 Author: wk Path: /cvs/dirmngr/dirmngr Modified: NEWS TODO doc/dirmngr.texi po/POTFILES.in po/de.po po/dirmngr.pot src/ChangeLog src/certcache.c src/crlcache.c src/dirmngr-client.c src/dirmngr.c src/dirmngr.h src/dirmngr_ldap.c src/ldap.c src/validate.c Translated all strings - puh. * dirmngr.c: New options --ignore-http-dp and --ignore-ldap-dp. * crlcache.c (crl_cache_reload_crl): Implement them. ----------------------+ NEWS | 5 TODO | 9 doc/dirmngr.texi | 28 - po/POTFILES.in | 4 po/de.po | 1294 +++++++++++++++++++++++++++++++++++++------------ po/dirmngr.pot | 1173 ++++++++++++++++++++++++++++++++++---------- src/ChangeLog | 10 src/certcache.c | 2 src/crlcache.c | 19 src/dirmngr-client.c | 2 src/dirmngr.c | 12 src/dirmngr.h | 2 src/dirmngr_ldap.c | 3 src/ldap.c | 23 src/validate.c | 4 15 files changed, 2001 insertions(+), 589 deletions(-) Index: dirmngr/NEWS diff -u dirmngr/NEWS:1.28 dirmngr/NEWS:1.29 --- dirmngr/NEWS:1.28 Mon Nov 22 22:30:50 2004 +++ dirmngr/NEWS Wed Nov 24 13:25:53 2004 @@ -9,10 +9,11 @@ * New options: --ldap-wrapper-program, --http-wrapper-program, --disable-ldap, --disable-http, --honor-http-proxy, --http-proxy, - --ldap-proxy and --only-ldap-proxy. + --ldap-proxy, --only-ldap-proxy, --ignore-ldap-dp and + --ignore-http-dp. * Uses an external ldap wrapper to cope with timeouts and general - LDAP problems. Prepared for using + LDAP problems. * SIGHUP may be used to reread the configuration and to flush the certificate cache. Index: dirmngr/TODO diff -u dirmngr/TODO:1.15 dirmngr/TODO:1.16 --- dirmngr/TODO:1.15 Tue Nov 23 14:20:44 2004 +++ dirmngr/TODO Wed Nov 24 13:25:53 2004 @@ -14,4 +14,13 @@ * Properly use locks in crlcache.c +* name subordination (nameRelativeToCRLIssuer) + is not yet supported by Dirmngr. + +* CRL DP URI + The CRL DP shall use an URI for LDAP without a host name. The host + name shall be looked by using the DN in the URI. We don't implement + this yet. Solution is to have a mapping DN->host in our ldapservers + configuration file. + Index: dirmngr/doc/dirmngr.texi diff -u dirmngr/doc/dirmngr.texi:1.16 dirmngr/doc/dirmngr.texi:1.17 --- dirmngr/doc/dirmngr.texi:1.16 Mon Nov 22 22:30:50 2004 +++ dirmngr/doc/dirmngr.texi Wed Nov 24 13:25:53 2004 @@ -302,6 +302,20 @@ @opindex disable-http Entirely disables the use of HTTP. +@item --ignore-http-dp +@opindex ignore-http-dp +When looking for the location of a CRL, the to be tested certificate +usually contains so called @dfn{CRL Distribution Point} (DP) entries +which are URLs describing the way to access the URL. The first found DP +entry is used. With this option all entries using the @acronym{HTTP} +scheme are ignored when looking for a suitable DP. + +@item --ignore-ldap-dp +@opindex ignore-ldap-dp +This is similar to @option{--ignore-http-dp} but ignores entries using +the @acronym{LDAP} scheme. Both options may be combined resulting in +ignoring DPs entirely. + @item --honor-http-proxy @opindex honor-http-proxy If the environment variable @env{http_proxy} has been set, use its @@ -725,13 +739,6 @@ @opindex ping Check whether the dirmngr daemon is up and running. -@item --use-daemon -@opindex use-daemon -Always try to use a running background daemon. The default is to try -to start a dirmngr if a connecting a daemon fails. This option is -also implicitly use with @code{--ping}. - - @item --cache-cert @opindex cache-cert Put the given certificate into the cache of a running dirmngr. This is @@ -742,6 +749,13 @@ Validate the given certificate using dirmngr's internal validation code. This is mainly useful for debugging. +@item --lookup +@opindex lookup +Take the remaining arguments and run a lookup command on each of them. +The results are Base-64 encoded outputs (without header lines). This +may be used to retrieve certificates from a server. However the output +format is not very well suited if more than one certificate is returned. + @end table Index: dirmngr/po/POTFILES.in diff -u dirmngr/po/POTFILES.in:1.2 dirmngr/po/POTFILES.in:1.3 --- dirmngr/po/POTFILES.in:1.2 Tue Nov 16 19:24:35 2004 +++ dirmngr/po/POTFILES.in Wed Nov 24 13:25:53 2004 @@ -2,6 +2,7 @@ jnlib/argparse.c jnlib/logging.c +src/certcache.c src/crlcache.c src/crlfetch.c src/dirmngr.c @@ -10,6 +11,9 @@ src/misc.c src/ocsp.c src/server.c +src/validate.c src/dirmngr-client.c src/no-libgcrypt.c +src/dirmngr_ldap.c + Index: dirmngr/po/de.po diff -u dirmngr/po/de.po:1.6 dirmngr/po/de.po:1.7 --- dirmngr/po/de.po:1.6 Mon Oct 4 13:52:07 2004 +++ dirmngr/po/de.po Wed Nov 24 13:25:53 2004 @@ -5,229 +5,326 @@ # msgid "" msgstr "" -"Project-Id-Version: dirmngr 0.5.6\n" +"Project-Id-Version: dirmngr 0.9.0\n" "Report-Msgid-Bugs-To: gpa-dev@gnupg.org\n" -"POT-Creation-Date: 2004-10-04 13:52+0200\n" -"PO-Revision-Date: 2004-10-04 13:52+0200\n" +"POT-Creation-Date: 2004-11-24 13:16+0100\n" +"PO-Revision-Date: 2004-11-24 13:16+0100\n" "Last-Translator: Werner Koch \n" "Language-Team: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -#: jnlib/logging.c:555 +#: jnlib/logging.c:624 #, c-format msgid "you found a bug ... (%s:%d)\n" msgstr "Sie haben einen Bug (Softwarefehler) gefunden ... (%s:%d)\n" -#: src/crlcache.c:177 +#: src/certcache.c:87 +#, c-format +msgid "can't acquire read lock on the certificate cache: %s\n" +msgstr "Lesesperre für den Zertifikatcache kann nicht gesetzt werden: %s\n" + +#: src/certcache.c:95 +#, c-format +msgid "can't acquire write lock on the certificate cache: %s\n" +msgstr "Schreibsperre für den Zertifikatcache kann nicht gesetzt werden: %s\n" + +#: src/certcache.c:103 +#, c-format +msgid "can't release lock on the certificate cache: %s\n" +msgstr "Sperre für den Zertifikatcache kann nicht freigegeben werden: %s\n" + +#: src/certcache.c:220 +#, c-format +msgid "dropping %u certificates from the cache\n" +msgstr "%u Zertifikate werden aus dem Zertifikat Cache entfernt\n" + +#: src/certcache.c:304 +#, c-format +msgid "can't access directory `%s': %s\n" +msgstr "Fehler beim Zugriff auf das Verzeichnis `%s': %s\n" + +#: src/certcache.c:323 src/crlcache.c:2142 src/ldap.c:605 +#, c-format +msgid "can't open `%s': %s\n" +msgstr "`%s' kann nicht geöffnet werden: %s\n" + +#: src/certcache.c:332 +#, c-format +msgid "can't setup KSBA reader: %s\n" +msgstr "KSAB Reader Objekt kann nicht erstellt werden: %s\n" + +#: src/certcache.c:345 +#, c-format +msgid "can't parse certificate `%s': %s\n" +msgstr "Zertifikat `%s' kann nicht zerlegt werden: %s\n" + +#: src/certcache.c:354 +#, c-format +msgid "certificate `%s' already cached\n" +msgstr "Zertifikat `%s' ist bereits im Cache\n" + +#: src/certcache.c:356 +#, c-format +msgid "certificate `%s' loaded\n" +msgstr "Zertifikat `%s' wurde geladen\n" + +#: src/certcache.c:358 +#, c-format +msgid "error loading certificate `%s': %s\n" +msgstr "Fehler beim Laden des Zertifikats `%s': %s\n" + +#: src/certcache.c:432 +#, c-format +msgid "permanently loaded certificates: %u\n" +msgstr " dauerhaft geladene Zertifikate: %u\n" + +#: src/certcache.c:434 +#, c-format +msgid " runtime cached certificates: %u\n" +msgstr "zur Laufzeit geladene Zertifikate: %u\n" + +#: src/certcache.c:449 src/dirmngr-client.c:297 +msgid "certificate already cached\n" +msgstr "Zertifikat ist bereits im Cache\n" + +#: src/certcache.c:451 +msgid "certificate cached\n" +msgstr "Zertifikat wurde gecachet\n" + +#: src/certcache.c:453 src/dirmngr-client.c:301 +#, c-format +msgid "error caching certificate: %s\n" +msgstr "Fehler beim Cachen des Zertifikats: %s\n" + +#: src/certcache.c:563 src/crlcache.c:1396 +#, c-format +msgid "error fetching certificate for issuer: %s\n" +msgstr "Fehler beim Holen des Zertifikats für den Issuer: %s\n" + +#: src/certcache.c:574 src/crlcache.c:1412 +#, c-format +msgid "invalid issuer certificate: %s\n" +msgstr "Ungültiges Issuer-Zertifikat: %s\n" + +#: src/certcache.c:655 src/validate.c:288 +msgid "no issuer found in certificate\n" +msgstr "Im Zertifikat ist kein Herausgeber enthalten\n" + +#: src/certcache.c:665 +#, c-format +msgid "error getting authorityKeyIdentifier: %s\n" +msgstr "Fehler beim Holen des \"authorityKeyIdentifier\": %s\n" + +#: src/crlcache.c:201 #, c-format msgid "creating directory `%s'\n" msgstr "Das Verzeichniss `%s' wird erzeugt\n" -#: src/crlcache.c:181 +#: src/crlcache.c:205 #, c-format msgid "error creating directory `%s': %s\n" msgstr "Fehler beim Erzeugen des Verzeichnis '%s': %s\n" -#: src/crlcache.c:209 +#: src/crlcache.c:233 #, c-format msgid "ignoring database dir `%s'\n" msgstr "Das Cache-Verzeichniss `%s' wird ignoriert\n" -#: src/crlcache.c:218 +#: src/crlcache.c:242 #, c-format msgid "error reading directory `%s': %s\n" msgstr "Fehler beim Lesen des Verzeichniss `%s': %s\n" -#: src/crlcache.c:239 +#: src/crlcache.c:263 #, c-format msgid "removing cache file `%s'\n" msgstr "Die Cache-Datei `%s' wird entfernt\n" -#: src/crlcache.c:248 +#: src/crlcache.c:272 #, c-format msgid "not removing file `%s'\n" msgstr "Die Datei `%s' wird nicht gelöscht\n" -#: src/crlcache.c:317 src/crlcache.c:962 +#: src/crlcache.c:341 src/crlcache.c:986 #, c-format msgid "error closing cache file: %s\n" msgstr "Fehler beim Schliessen der Cache-Datei: %s\n" -#: src/crlcache.c:354 src/crlcache.c:678 +#: src/crlcache.c:378 src/crlcache.c:702 #, c-format msgid "failed to open cache dir file `%s': %s\n" msgstr "Die Cache-Verzeichnissdatei `%s' konnte nicht geöffnet werden: %s\n" -#: src/crlcache.c:364 +#: src/crlcache.c:388 #, c-format msgid "error creating new cache dir file `%s': %s\n" msgstr "Fehler beim Erzeugen der neuen Cache-Verzeichnissdatei `%s': %s\n" -#: src/crlcache.c:371 +#: src/crlcache.c:395 #, c-format msgid "error writing new cache dir file `%s': %s\n" msgstr "Fehler beim Schreiben der neuen Cache-Verzeichnissdatei `%s': %s\n" -#: src/crlcache.c:378 +#: src/crlcache.c:402 #, c-format msgid "error closing new cache dir file `%s': %s\n" msgstr "Fehler beim Schliessen der neuen Cache-Verzeichnissdatei `%s': %s\n" -#: src/crlcache.c:383 +#: src/crlcache.c:407 #, c-format msgid "new cache dir file `%s' created\n" msgstr "Neue Cache-Verzeichnissdatei `%s' wurde erzeugt\n" -#: src/crlcache.c:388 +#: src/crlcache.c:412 #, c-format msgid "failed to re-open cache dir file `%s': %s\n" msgstr "Fehler beim Wiederöffnen der Cache-Verzeichnissdatei `%s': %s\n" -#: src/crlcache.c:415 +#: src/crlcache.c:439 #, c-format msgid "first record of `%s' is not the version\n" msgstr "Der erste Datensatz von `%s' enthält nicht die Version\n" -#: src/crlcache.c:426 +#: src/crlcache.c:450 msgid "old version of cache directory - cleaning up\n" msgstr "Alte Version des Cache-Verzeichnisses - räume auf\n" -#: src/crlcache.c:442 +#: src/crlcache.c:466 msgid "old version of cache directory - giving up\n" msgstr "Alte Version des Cache-Verzeichnisses - gebe auf\n" -#: src/crlcache.c:530 +#: src/crlcache.c:554 #, c-format msgid "extra field detected in crl record of `%s' line %u\n" msgstr "Weiteres Feld im CRL Datensatz von `%s', Zeile %u festgestellt\n" -#: src/crlcache.c:542 +#: src/crlcache.c:566 #, c-format msgid "unsupported record type in `%s' line %u skipped\n" msgstr "Nicht unterstützter Datensatztyp in `%s', Zeile %u übergangen\n" -#: src/crlcache.c:550 src/crlcache.c:779 src/dirmngr.c:810 +#: src/crlcache.c:574 src/crlcache.c:803 src/dirmngr.c:1191 #, c-format msgid "error reading `%s': %s\n" msgstr "Fehler beim Lesen von `%s': %s\n" -#: src/crlcache.c:562 +#: src/crlcache.c:586 #, c-format msgid "invalid issuer hash in `%s' line %u\n" msgstr "Ungültiger Issuer Hashwert in `%s', Zeile %u\n" -#: src/crlcache.c:568 +#: src/crlcache.c:592 #, c-format msgid "no issuer DN in `%s' line %u\n" msgstr "Kein Issuer DN in `%s', Zeile %u\n" -#: src/crlcache.c:575 +#: src/crlcache.c:599 #, c-format msgid "invalid timestamp in `%s' line %u\n" msgstr "Ungültiger Zeitstempel in `%s', Zeile %u\n" -#: src/crlcache.c:581 +#: src/crlcache.c:605 #, c-format msgid "WARNING: invalid cache file hash in `%s' line %u\n" msgstr "WARNUNG: Ungültiger Cache-Datei Hashwert in `%s', Zeile %u\n" -#: src/crlcache.c:587 +#: src/crlcache.c:611 msgid "detected errors in cache dir file\n" msgstr "Id der Cache-Verzeichnissdatei wurden Fehler erkannt\n" -#: src/crlcache.c:588 +#: src/crlcache.c:612 msgid "please check the reason and manually delete that file\n" msgstr "" "Bitte ermitteln sie die Ursache und löschen sie die Datei dann manuell\n" -#: src/crlcache.c:711 +#: src/crlcache.c:735 #, c-format msgid "failed to create temporary cache dir file `%s': %s\n" msgstr "" "Die temporäre Cache-Verzeichnissdatei `%s' konnte nicht erzeugt werden: %s\n" -#: src/crlcache.c:784 +#: src/crlcache.c:808 #, c-format msgid "error writing `%s': %s\n" msgstr "Fehler beim Schreiben auf `%s': %s\n" -#: src/crlcache.c:795 +#: src/crlcache.c:819 #, c-format msgid "error closing `%s': %s\n" msgstr "Fehler beim Schliessen von `%s': %s\n" -#: src/crlcache.c:803 +#: src/crlcache.c:827 #, c-format msgid "error renaming `%s' to `%s': %s\n" msgstr "Fehler beim Umbenennen von `%s` nach `%s': %s\n" -#: src/crlcache.c:858 +#: src/crlcache.c:882 #, c-format msgid "can't hash `%s': %s\n" msgstr "Hashwert von `%s' kann nicht gebildet werden: %s\n" -#: src/crlcache.c:866 +#: src/crlcache.c:890 #, c-format msgid "error setting up MD5 hash context: %s\n" msgstr "Fehler beim Vorbereiten des MD5 Hashkontext: %s\n" -#: src/crlcache.c:882 +#: src/crlcache.c:906 #, c-format msgid "error hashing `%s': %s\n" msgstr "Fehler beim Hashen von `%s': %s\n" -#: src/crlcache.c:910 +#: src/crlcache.c:934 #, c-format msgid "invalid formatted checksum for `%s'\n" msgstr "Ungültig formatierte Prüfsumme für `%s'\n" -#: src/crlcache.c:953 +#: src/crlcache.c:977 msgid "too many open cache files; can't open anymore\n" msgstr "Zu viele geöffnete Cache-Dateien; weitere kann nicht geöffnet werden\n" -#: src/crlcache.c:970 +#: src/crlcache.c:994 #, c-format msgid "opening cache file `%s'\n" msgstr "Die Cache-Datei `%s' wird geöffnet\n" -#: src/crlcache.c:989 +#: src/crlcache.c:1013 #, c-format msgid "error opening cache file `%s': %s\n" msgstr "Fehler beim Öffnen der Cache-Datei `%s': %s\n" -#: src/crlcache.c:998 +#: src/crlcache.c:1022 #, c-format msgid "error initializing cache file `%s' for reading: %s\n" msgstr "Fehler beim Initialisieren der Cache-Datei `%s' zum Lesen: %s\n" -#: src/crlcache.c:1020 +#: src/crlcache.c:1044 msgid "calling unlock_db_file on a closed file\n" msgstr "unlock_db_file wird für eine geschlossene Datei aufgerufen\n" -#: src/crlcache.c:1022 +#: src/crlcache.c:1046 msgid "calling unlock_db_file on an unlocked file\n" msgstr "unlock_db_file wird für eine nicht gesperrte Datei aufgerufen\n" -#: src/crlcache.c:1070 +#: src/crlcache.c:1100 #, c-format msgid "failed to create a new cache object: %s\n" msgstr "Ein neues Cache-Objekt konnte nciht erzeugt werden: %s\n" -#: src/crlcache.c:1123 +#: src/crlcache.c:1153 #, c-format msgid "no CRL available for issuer id %s\n" msgstr "Es ist keine CRL für den Issuer mit der ID %s vorhanden\n" -#: src/crlcache.c:1130 +#: src/crlcache.c:1160 #, c-format msgid "cached CRL for issuer id %s too old; update required\n" msgstr "" "Die zwischengespeicherte CRL für den Issuer mit der ID %s is zu alt; ein " "Update wird benötigt\n" -#: src/crlcache.c:1144 +#: src/crlcache.c:1174 #, c-format msgid "" "force-crl-refresh active and %d minutes passed for issuer id %s; update " @@ -236,198 +333,187 @@ "\"force-crl-refresh\" ist aktiviert und %d Minuten für den Issuer mit Id %s " "sind vorbei; Update wird benötigt\n" -#: src/crlcache.c:1152 +#: src/crlcache.c:1182 #, c-format msgid "force-crl-refresh active for issuer id %s; update required\n" msgstr "" "\"force-crl-refresh\" ist für den Issuer mit der Id %s aktiviert; Update " "wird benötigt\n" -#: src/crlcache.c:1161 +#: src/crlcache.c:1191 #, c-format msgid "available CRL for issuer ID %s can't be used\n" msgstr "" "Die vorhandene CRL für den Issuer mit der ID %s kann nicht benutzt werden\n" -#: src/crlcache.c:1172 +#: src/crlcache.c:1202 #, c-format msgid "cached CRL for issuer id %s tampered; we need to update\n" msgstr "" "Die zwischengespeicherte CRL für den Issuer mit der ID %s wurde verändert; " "eine Update wird benötigt\n" -#: src/crlcache.c:1190 -#, c-format -msgid "WARNING: invalid cache record length for S/N %s\n" -msgstr "WARNUNG: Ungültige Länge des Cache Dateisatzes für S/N %s\n" +#: src/crlcache.c:1214 +msgid "WARNING: invalid cache record length for S/N " +msgstr "WARNUNG: Ungültige Länge des Cache Dateisatzes für S/N " -#: src/crlcache.c:1197 +#: src/crlcache.c:1223 #, c-format msgid "problem reading cache record for S/N %s: %s\n" msgstr "Problem beim Lesen des Cache Datensatzes für S/N %s: %s\n" -#: src/crlcache.c:1200 +#: src/crlcache.c:1226 #, c-format msgid "S/N %s is not valid; reason=%02X date=%.15s\n" msgstr "S/N %s ist nicht gültig; Grund=%02X Datum=%.15s\n" -#: src/crlcache.c:1208 +#: src/crlcache.c:1237 #, c-format msgid "S/N %s is valid, it is not listed in the CRL\n" msgstr "S/N %s ist gültig; sie ist nicht in der CRL enthalten\n" -#: src/crlcache.c:1214 +#: src/crlcache.c:1245 #, c-format msgid "error getting data from cache file: %s\n" msgstr "Fehler beim Holen der Daten aus der Cache-Datei: %s\n" -#: src/crlcache.c:1252 -#, c-format -msgid "error fetching certificate for issuer: %s\n" -msgstr "Fehler beim Holen des Zertifikats für den Issuer: %s\n" - -#: src/crlcache.c:1275 -#, c-format -msgid "invalid issuer certificate: %s\n" -msgstr "Ungültiges Issuer-Zertifikat: %s\n" - -#: src/crlcache.c:1295 +#: src/crlcache.c:1435 src/validate.c:636 #, c-format msgid "unknown hash algorithm `%s'\n" msgstr "Ungültige Hashmethode `%s'\n" -#: src/crlcache.c:1302 +#: src/crlcache.c:1442 #, c-format msgid "gcry_md_open for algorithm %d failed: %s\n" msgstr "gcry_md_open für Methode %d fehlgeschlagen: %s\n" -#: src/crlcache.c:1336 src/crlcache.c:1353 +#: src/crlcache.c:1476 src/crlcache.c:1493 msgid "got an invalid S-expression from libksba\n" msgstr "Ungültige S-Expression von Libksba erhalten\n" -#: src/crlcache.c:1343 src/crlcache.c:1360 src/misc.c:430 +#: src/crlcache.c:1483 src/crlcache.c:1500 src/misc.c:432 #, c-format msgid "converting S-expression failed: %s\n" msgstr "Konvertierung der S-Expression fehlgeschlagen: %s\n" -#: src/crlcache.c:1375 src/ocsp.c:325 +#: src/crlcache.c:1515 src/ocsp.c:343 #, c-format msgid "creating S-expression failed: %s\n" msgstr "Erzeugen der S-Expression fehlgeschlagen: %s\n" -#: src/crlcache.c:1427 +#: src/crlcache.c:1567 #, c-format msgid "ksba_crl_parse failed: %s\n" msgstr "ksba_crl_parse fehlgeschlagen: %s\n" -#: src/crlcache.c:1443 +#: src/crlcache.c:1583 #, c-format msgid "no issuer found in CRL: %s\n" msgstr "In der CRL wurde kein Issuer gefunden: %s\n" -#: src/crlcache.c:1461 +#: src/crlcache.c:1601 #, c-format msgid "error getting update times of CRL: %s\n" msgstr "Die \"Update Times\" konnte nicht aus der CRL bestimmt werden: %s\n" -#: src/crlcache.c:1468 +#: src/crlcache.c:1608 #, c-format msgid "update times of this CRL: this=%s next=%s\n" msgstr "Die \"Update Times\" dieser CRL sind: this=%s next=%s\n" -#: src/crlcache.c:1487 +#: src/crlcache.c:1627 #, c-format msgid "error getting CRL item: %s\n" msgstr "Fehler beim Holen eines CRL Items: %s\n" -#: src/crlcache.c:1502 +#: src/crlcache.c:1642 #, c-format msgid "error inserting item into temporary cache file: %s\n" msgstr "Fehler beim Einfügen eines Items in die temporäre Cache-Datei: %s\n" -#: src/crlcache.c:1520 +#: src/crlcache.c:1660 #, c-format msgid "CRL signature verification failed: %s\n" msgstr "Signaturprüfung der CRL ist fehlgeschlagen: %s\n" -#: src/crlcache.c:1639 +#: src/crlcache.c:1668 #, c-format -msgid "ksba_crl_new failed: %s\n" -msgstr "ksba_crl_new fehlgeschlagen: %s\n" +msgid "error checking validity of CRL signing certificate: %s\n" +msgstr "Fehler beim Püfen des CRL Signierzertifikats: %s\n" -#: src/crlcache.c:1648 +#: src/crlcache.c:1793 #, c-format -msgid "ksba_reader_set_file failed: %s\n" -msgstr "ksba_reader_set_file fehlgeschlagen: %s\n" +msgid "ksba_crl_new failed: %s\n" +msgstr "ksba_crl_new fehlgeschlagen: %s\n" -#: src/crlcache.c:1654 +#: src/crlcache.c:1800 #, c-format msgid "ksba_crl_set_reader failed: %s\n" msgstr "ksba_crl_set_reader fehlgeschlagen: %s\n" -#: src/crlcache.c:1677 +#: src/crlcache.c:1823 #, c-format msgid "removed stale temporary cache file `%s'\n" msgstr "Die alte temporäre Cache-Datei `%s' wurde entfernt\n" -#: src/crlcache.c:1680 +#: src/crlcache.c:1826 #, c-format msgid "problem removing stale temporary cache file `%s': %s\n" msgstr "Problem beim Löschen der alten temporären Cache-Datei `%s': %s\n" -#: src/crlcache.c:1690 +#: src/crlcache.c:1836 #, c-format msgid "error creating temporary cache file `%s': %s\n" msgstr "Fehler beim Erzeugen der temporären Cache-Datei `%s': %s\n" -#: src/crlcache.c:1700 +#: src/crlcache.c:1846 #, c-format msgid "crl_parse_insert failed: %s\n" msgstr "crl_parse_insert fehlgeschlagen: %s\n" -#: src/crlcache.c:1709 +#: src/crlcache.c:1855 #, c-format msgid "error finishing temporary cache file `%s': %s\n" msgstr "Fehler beim Fertigstellen der temporären Cache-Datei `%s': %s\n" -#: src/crlcache.c:1716 +#: src/crlcache.c:1862 #, c-format msgid "error closing temporary cache file `%s': %s\n" msgstr "Fehler beim Schliessen der temporären Cache-Datei `%s': %s\n" -#: src/crlcache.c:1741 +#: src/crlcache.c:1887 #, c-format msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n" msgstr "" "WARNUNG: Neue CRL ist immer noch zu alt; sie verfiel am %s - wird trotzdem " "geladen\n" -#: src/crlcache.c:1745 +#: src/crlcache.c:1891 #, c-format msgid "new CRL still too old; it expired on %s\n" msgstr "Neue CRL ist immer noch zu alt; sie verviel am %s\n" -#: src/crlcache.c:1761 +#: src/crlcache.c:1907 #, c-format msgid "unknown crtical CRL extension %s\n" msgstr "Unbekannte kritische CRL Erweiterung %s\n" -#: src/crlcache.c:1771 +#: src/crlcache.c:1917 #, c-format msgid "error reading CRL extensions: %s\n" msgstr "Fehler beim Lesen einer CRL Erweiterung: %s\n" -#: src/crlcache.c:1805 +#: src/crlcache.c:1951 #, c-format msgid "creating cache file `%s'\n" msgstr "Cache-Datei `%s' wird erzeugt\n" -#: src/crlcache.c:1809 +#: src/crlcache.c:1955 #, c-format msgid "problem renaming `%s' to `%s': %s\n" msgstr "Problem beim Umbenennen von `%s' nach `%s': %s\n" -#: src/crlcache.c:1823 +#: src/crlcache.c:1969 msgid "" "updating the DIR file failed - cache entry will get lost with the next " "program start\n" @@ -435,12 +521,12 @@ "Update der Cache-Verzeichnissdatei fehlgeschlagen - Cache Eintrag wird mit " "dem nächste Programmstart verloren gehen\n" -#: src/crlcache.c:1860 +#: src/crlcache.c:2005 #, c-format msgid "Begin CRL dump (retrieved via %s)\n" msgstr "Anfang CRL Ausgabe (geholt via %s)\n" -#: src/crlcache.c:1880 +#: src/crlcache.c:2025 #, c-format msgid "" " ERROR: The CRL will not be used because it was still too old after an " @@ -448,7 +534,7 @@ msgstr "" " FEHLER: Die CRL wird nicht benutzt, da sie trotz eines Updates zu alt war!\n" -#: src/crlcache.c:1882 +#: src/crlcache.c:2027 #, c-format msgid "" " ERROR: The CRL will not be used due to an unknown critical extension!\n" @@ -456,62 +542,92 @@ " FEHLER: Die CRL wird nicht benutzt, da sie eine unbekannte kritische CRL " "Erweiterung trägt!\n" -#: src/crlcache.c:1884 +#: src/crlcache.c:2029 #, c-format msgid " ERROR: The CRL will not be used\n" msgstr " FEHLER: Die CRL wird nicht benutzt\n" -#: src/crlcache.c:1891 +#: src/crlcache.c:2036 #, c-format msgid " ERROR: This cached CRL may has been tampered with!\n" msgstr "" " FEHLER: Diese zwischengespeicherte CRL ist möglicherweise abgeändert " "worden!\n" -#: src/crlcache.c:1908 +#: src/crlcache.c:2053 msgid " WARNING: invalid cache record length\n" msgstr " WARNUNG: Ungültige Länge eines Cache-Datensatzes\n" -#: src/crlcache.c:1915 +#: src/crlcache.c:2060 #, c-format msgid "problem reading cache record: %s\n" msgstr "Problem beim Lesen eines Cache-Datensatzes: %s\n" -#: src/crlcache.c:1926 +#: src/crlcache.c:2071 #, c-format msgid "problem reading cache key: %s\n" msgstr "Problem beim Lesen eines Cache Schlüssels: %s\n" -#: src/crlcache.c:1957 +#: src/crlcache.c:2102 #, c-format msgid "error reading cache entry from db: %s\n" msgstr "Fehler beim Lesen eine Cache Eintrags aus der DB: %s\n" -#: src/crlcache.c:1960 +#: src/crlcache.c:2105 #, c-format msgid "End CRL dump\n" msgstr "Ende CRL Ausgabe\n" -#: src/crlcache.c:1996 +#: src/crlcache.c:2217 #, c-format -msgid "can't open `%s': %s\n" -msgstr "`%s' kann nicht geöffnet werden: %s\n" +msgid "crl_fetch via DP failed: %s\n" +msgstr "crl_fetch über den DP fehlgeschlagen: %s\n" -#: src/crlfetch.c:130 +#: src/crlcache.c:2224 +#, c-format +msgid "crl_cache_insert via DP failed: %s\n" +msgstr "crl_cache_insert über den DP fehlgeschlagen: %s\n" + +#: src/crlcache.c:2255 +#, c-format +msgid "crl_fetch via issuer failed: %s\n" +msgstr "crl_fetch über den Issuer fehlgeschlagen: %s\n" + +#: src/crlcache.c:2263 +#, c-format +msgid "crl_cache_insert via issuer failed: %s\n" +msgstr "crl_cache_insert über den Issuer fehlgeschlagen: %s\n" + +#: src/crlfetch.c:61 msgid "using \"http\" instead of \"https\"\n" msgstr "Es wird \"HTTP\" anstatt \"HTTPS\" verwendet\n" -#: src/crlfetch.c:141 +#: src/crlfetch.c:72 src/crlfetch.c:116 src/crlfetch.c:136 src/crlfetch.c:151 +#, c-format +msgid "CRL access not possible due to disabled %s\n" +msgstr "CRL Zugriff nicht möglich da %s abgeschaltet ist\n" + +#: src/crlfetch.c:82 #, c-format msgid "error retrieving `%s': %s\n" msgstr "Fehler beim Holen von `%s': %s\n" -#: src/crlfetch.c:144 +#: src/crlfetch.c:85 #, c-format msgid "error retrieving `%s': http status %u\n" msgstr "Fehler beim Holen von `%s': HTTP Status %u\n" -#: src/dirmngr.c:88 +#: src/crlfetch.c:97 src/ldap.c:673 +#, c-format +msgid "error initializing reader object: %s\n" +msgstr "Fehler beim Initialisieren des \"reader\" Objekts: %s\n" + +#: src/crlfetch.c:165 +#, c-format +msgid "Certificate search not possible due to disabled %s\n" +msgstr "Zertifikatsuche ist nicht möglich da %s abgeschaltet ist\n" + +#: src/dirmngr.c:105 msgid "" "@Commands:\n" " " @@ -519,31 +635,35 @@ "@Kommandos:\n" " " -#: src/dirmngr.c:90 -msgid "run in server mode" -msgstr "Im Servermodus laufen lassen" +#: src/dirmngr.c:107 +msgid "run in server mode (foreground)" +msgstr "Im Servermodus ausführen (Vordergrund)" -#: src/dirmngr.c:91 +#: src/dirmngr.c:108 +msgid "run in daemon mode (background)" +msgstr "Im Daemonmodus ausführen (Hintergrund)" + +#: src/dirmngr.c:109 msgid "list the contents of the CRL cache" msgstr "Den Inhalt des CRL Caches anzeigen" -#: src/dirmngr.c:92 +#: src/dirmngr.c:110 msgid "|FILE|load CRL from FILE into cache" msgstr "|DATEI|Lade die CRL aus der DATEI in den Cache" -#: src/dirmngr.c:93 +#: src/dirmngr.c:111 msgid "|URL|fetch a CRL from URL" msgstr "|URL|Hole eine CRL von dieser URL" -#: src/dirmngr.c:94 +#: src/dirmngr.c:112 msgid "shutdown the dirmngr" msgstr "Den Dirmngr herunterfahren" -#: src/dirmngr.c:95 +#: src/dirmngr.c:113 msgid "flush the cache" msgstr "Den Cache löschen" -#: src/dirmngr.c:98 +#: src/dirmngr.c:116 msgid "" "@\n" "Options:\n" @@ -553,83 +673,115 @@ "Optionen:\n" " " -#: src/dirmngr.c:100 +#: src/dirmngr.c:118 src/dirmngr-client.c:64 src/dirmngr_ldap.c:73 msgid "verbose" msgstr "ausführlich" -#: src/dirmngr.c:101 +#: src/dirmngr.c:119 src/dirmngr-client.c:65 src/dirmngr_ldap.c:74 msgid "be somewhat more quiet" msgstr "etwas weniger Ausgaben erzeugen" -#: src/dirmngr.c:102 +#: src/dirmngr.c:120 msgid "sh-style command output" msgstr "Kommandausgabe für /bin/sh" -#: src/dirmngr.c:103 +#: src/dirmngr.c:121 msgid "csh-style command output" msgstr "Kommandausgabe für /bin/csh" -#: src/dirmngr.c:104 +#: src/dirmngr.c:122 msgid "|FILE|read options from FILE" msgstr "|DATEI|Lese Optionen aus DATEI" -#: src/dirmngr.c:106 +#: src/dirmngr.c:124 msgid "|LEVEL|set the debugging level to LEVEL" msgstr "|NAME|Setze die Debugebene auf NAME" -#: src/dirmngr.c:107 +#: src/dirmngr.c:125 msgid "do not detach from the console" msgstr "Nicht von der Konsole loslösen" -#: src/dirmngr.c:108 +#: src/dirmngr.c:126 msgid "|FILE|write logs to FILE" msgstr "|DATEI|Schreibe Logs in DATEI" -#: src/dirmngr.c:109 +#: src/dirmngr.c:127 msgid "run without asking a user" msgstr "Ausführung ohne Benutzernachfrage" -#: src/dirmngr.c:110 +#: src/dirmngr.c:128 msgid "force loading of outdated CRLs" msgstr "Laden von abgelaufenen CRLs erzwingen" -#: src/dirmngr.c:111 +#: src/dirmngr.c:129 msgid "allow sending OCSP requests" msgstr "OCSP Anfragen erlauben" -#: src/dirmngr.c:114 +#: src/dirmngr.c:130 +msgid "inhibit the use of HTTP" +msgstr "Sperre die Benutzung von HTTP" + +#: src/dirmngr.c:131 +msgid "inhibit the use of LDAP" +msgstr "Sperre die Benutzung von LDAP" + +#: src/dirmngr.c:133 +msgid "ignore HTTP CRL distribution points" +msgstr "Ãœbergehe HTTP CRL Distribution Points" + +#: src/dirmngr.c:135 +msgid "ignore LDAP CRL distribution points" +msgstr "Ãœbergehe LDAP CRL Distribution Points" + +#: src/dirmngr.c:137 +msgid "|URL|redirect all HTTP requests to URL" +msgstr "|URL|Leite alle HTTP Anfragen über URL" + +#: src/dirmngr.c:139 +msgid "|HOST|use HOST for LDAP queries" +msgstr "|HOST|Benutze HOST für LDAP Anfragen" + +#: src/dirmngr.c:141 +msgid "do not use fallback hosts with --ldap-proxy" +msgstr "Keine Benuztung der Rückgriffshosts mit --ldap-proxy" + +#: src/dirmngr.c:144 msgid "|FILE|read LDAP server list from FILE" msgstr "|DATEI|Lese die LDAP Serverliste aus DATEI" -#: src/dirmngr.c:116 +#: src/dirmngr.c:146 msgid "add new servers discovered in CRL distribution points to serverlist" msgstr "Füge neue Server aus den CRL Distribution Points der Serverliste hinzu" -#: src/dirmngr.c:118 +#: src/dirmngr.c:148 src/dirmngr_ldap.c:75 msgid "|N|set LDAP timeout to N seconds" msgstr "|N|Setze das LDAP Timeout auf N Sekunden" -#: src/dirmngr.c:120 +#: src/dirmngr.c:150 msgid "|URL|use OCSP responder at URL" msgstr "|URL|Benutze den OCSP Reponder mit dieser URL" -#: src/dirmngr.c:121 +#: src/dirmngr.c:151 msgid "|FPR|OCSP response signed by FPR" msgstr "|FPR|OCSP Antwort ist durch FPR signiert" -#: src/dirmngr.c:124 +#: src/dirmngr.c:154 msgid "|N|do not return more than N items in one query" msgstr "|N|Nicht mehr als N Angaben in einer Anfrage zurückgeben" -#: src/dirmngr.c:153 +#: src/dirmngr.c:156 +msgid "|FILE|listen on socket FILE" +msgstr "|DATEI|Anfragen auf Socket DATEI annehmen" + +#: src/dirmngr.c:211 src/dirmngr-client.c:126 src/dirmngr_ldap.c:134 msgid "Please report bugs to .\n" msgstr "Berichte über Bugs (Programmfehler) bitte an .\n" -#: src/dirmngr.c:157 +#: src/dirmngr.c:215 msgid "Usage: dirmngr [options] (-h for help)" msgstr "Gebrauch: dirmnr [Optionen] [Kommando [Argumente]]" -#: src/dirmngr.c:160 +#: src/dirmngr.c:218 msgid "" "Syntax: dirmngr [options] [command [args]]\n" "LDAP and OCSP access for GnuPG\n" @@ -637,438 +789,972 @@ "Syntax: dirmngr [Optionen] [Kommando [Argumente]]\n" "LDAP und OCSP Zugriff für GnuPG\n" -#: src/dirmngr.c:231 +#: src/dirmngr.c:289 #, c-format msgid "invalid debug-level `%s' given\n" msgstr "Ungültige Debugebene '%s' angegeben\n" -#: src/dirmngr.c:232 +#: src/dirmngr.c:290 #, c-format msgid "valid debug levels are: %s\n" msgstr "Gültige Debugebenen sind: %s\n" -#: src/dirmngr.c:269 +#: src/dirmngr.c:328 msgid "usage: dirmngr [options] " msgstr "Gebrauch: dirmngr [Optionen] " -#: src/dirmngr.c:310 src/dirmngr.c:320 +#: src/dirmngr.c:353 +#, c-format +msgid "error spawning ldap wrapper ripper thread: %s\n" +msgstr "Fehler beim Starten des LDAP Wrapper Thread: %s\n" + +#: src/dirmngr.c:471 src/dirmngr.c:481 #, c-format msgid "%s is too old (need %s, have %s)\n" msgstr "%s ist zu alt (benötige %s, habe %s)\n" -#: src/dirmngr.c:399 +#: src/dirmngr.c:582 #, c-format msgid "NOTE: no default option file `%s'\n" msgstr "Hinweis: Voreingestellte Optionendatei `%s' nicht vorhanden\n" -#: src/dirmngr.c:404 +#: src/dirmngr.c:587 src/dirmngr.c:1248 #, c-format msgid "option file `%s': %s\n" msgstr "Optionendatei `%s': %s\n" -#: src/dirmngr.c:412 +#: src/dirmngr.c:595 #, c-format msgid "reading options from `%s'\n" msgstr "Optionen werden von `%s' gelesen\n" -#: src/dirmngr.c:507 +#: src/dirmngr.c:701 #, c-format msgid "WARNING: running with faked system time %s\n" msgstr "WARNUNG: Prozess läuft mit getürkter Systemzeit %s\n" -#: src/dirmngr.c:586 +#: src/dirmngr.c:777 +msgid "colons are not allowed in the socket name\n" +msgstr "Doppelpunkte sind im Namen des Sockets nicht erlaubt\n" + +#: src/dirmngr.c:782 +msgid "name of socket too long\n" +msgstr "Name des Sockets ist zu lang\n" + +#: src/dirmngr.c:789 +#, c-format +msgid "can't create socket: %s\n" +msgstr "Fehler beim Erzeugen des Sockets: %s\n" + +#: src/dirmngr.c:808 +#, c-format +msgid "error binding socket to `%s': %s\n" +msgstr "Fehler beim Binden des Sockets an `%s': %s\n" + +#: src/dirmngr.c:817 +#, c-format +msgid "listen() failed: %s\n" +msgstr "listen() fehlgeschlagen: %s\n" + +#: src/dirmngr.c:823 +#, c-format +msgid "listening on socket `%s'\n" +msgstr "Anfragen werden auf Socket `%s' engegengenommen\n" + +#: src/dirmngr.c:829 +#, c-format +msgid "fork failed: %s\n" +msgstr "fork() fehlgeschlagen: %s\n" + +#: src/dirmngr.c:847 +msgid "out of core\n" +msgstr "Nicht genügend Hauptspeicher vorhanden\n" + +#: src/dirmngr.c:886 +#, c-format +msgid "setsid() failed: %s\n" +msgstr "setsid() fehlgeschlagen: %s\n" + +#: src/dirmngr.c:896 +#, c-format +msgid "chdir to / failed: %s\n" +msgstr "chdir nach / fehlgeschlagen: %s\n" + +#: src/dirmngr.c:945 #, c-format msgid "fetching CRL from `%s' failed: %s\n" msgstr "Holen der CRL von `%s' fehlgeschlagen: %s\n" -#: src/dirmngr.c:592 +#: src/dirmngr.c:951 #, c-format msgid "processing CRL from `%s' failed: %s\n" msgstr "Verarbeitung der CRL von `%s' fehlgeschlagen: %s\n" -#: src/dirmngr.c:714 +#: src/dirmngr.c:1095 #, c-format msgid "error opening `%s': %s\n" msgstr "Fehler beim Öffnen von `%s': %s\n" -#: src/dirmngr.c:731 +#: src/dirmngr.c:1112 #, c-format msgid "%s:%u: line too long - skipped\n" msgstr "%s:%u: Zeile ist zu lang - übergangen\n" -#: src/dirmngr.c:759 +#: src/dirmngr.c:1140 #, c-format msgid "%s:%u: no hostname given\n" msgstr "%s:%u: Kein Hostname angegeben\n" -#: src/dirmngr.c:778 +#: src/dirmngr.c:1159 #, c-format msgid "%s:%u: password given without user\n" msgstr "%s:%u: Passwort angegeben ohne Username\n" -#: src/dirmngr.c:799 +#: src/dirmngr.c:1180 #, c-format msgid "%s:%u: skipping this line\n" msgstr "%s:%u: Diese Zeile wird übersprungen\n" -#: src/http.c:467 +#: src/dirmngr.c:1280 +msgid "SIGHUP received - re-reading configuration and flushing caches\n" +msgstr "" +"SIGHUP empfangen - lese die Konfiguration erneut und lösche die Caches\n" + +#: src/dirmngr.c:1294 +msgid "SIGUSR2 received - no action defined\n" +msgstr "SIGUSR2 empfangen - keine Aktion definiert\n" + +#: src/dirmngr.c:1299 +msgid "SIGTERM received - shutting down ...\n" +msgstr "SIGTERM empfangen - wird heruntergefahren ...\n" + +#: src/dirmngr.c:1301 #, c-format -msgid "invalid %s: %s\n" -msgstr "Ungültiger %s: %s\n" +msgid "SIGTERM received - still %d active connections\n" +msgstr "SIGTERM empfangen - immer noch %d Verbindungen aktiv\n" -#: src/http.c:820 src/http.c:856 +#: src/dirmngr.c:1306 +msgid "shutdown forced\n" +msgstr "Herunterfahren wurde erzwungen\n" + +#: src/dirmngr.c:1314 +msgid "SIGINT received - immediate shutdown\n" +msgstr "SIGINT empfangen - wird sofort heruntergefahren\n" + +#: src/dirmngr.c:1321 +#, c-format +msgid "signal %d received - no action defined\n" +msgstr "Signal %d empfangen - keine Aktion definiert\n" + +#: src/dirmngr.c:1335 +#, c-format +msgid "handler for fd %d started\n" +msgstr "Routine für fd %d gestartet\n" + +#: src/dirmngr.c:1340 +#, c-format +msgid "handler for fd %d terminated\n" +msgstr "Routine für fd %d beendet\n" + +#: src/dirmngr.c:1396 +#, c-format +msgid "accept failed: %s - waiting 1s\n" +msgstr "accept() fehlgeschlagen: %s - warte 1s\n" + +#: src/dirmngr.c:1403 +#, c-format +msgid "error spawning connection handler: %s\n" +msgstr "Fehler beim Starten des Verbindungshandler: %s\n" + +#: src/http.c:475 +#, c-format +msgid "invalid HTTP proxy (%s): %s\n" +msgstr "Ungültiger HTTP Proxy (%s): %s\n" + +#: src/http.c:827 src/http.c:863 #, c-format msgid "error resolving `%s': host not found\n" msgstr "Fehler beim Auflösen von `%s': Host nicht gefunden\n" -#: src/http.c:833 src/http.c:864 +#: src/http.c:840 src/http.c:871 #, c-format msgid "error creating socket: %s\n" msgstr "Fehler beim Erzeugen des Scokets: %s\n" -#: src/http.c:919 +#: src/http.c:926 #, c-format msgid "network write failed: %s\n" msgstr "Schreiben auf dem Netzwerk fehlgeschlagen: %s\n" -#: src/ldap.c:72 src/ldap.c:183 +#: src/ldap.c:125 #, c-format -msgid "found attribute `%s'\n" -msgstr "Attribut `%s' gefunden\n" +msgid "invalid char 0x%02x in host name - not added\n" +msgstr "Ungültiges Zeichen 0x%02X im Hostnamen - nicht hinzugefügt\n" -#: src/ldap.c:95 src/ldap.c:206 +#: src/ldap.c:129 #, c-format -msgid "found attributes `%s' at second try\n" -msgstr "Attribute `%s' im zweiten Versuch gefunden\n" - -#: src/ldap.c:247 -msgid "timeout while waiting for ldap_search result\n" -msgstr "Timeout beim Warten auf das ldap_search Resultat\n" +msgid "adding `%s:%d' to the ldap server list\n" +msgstr "`%s:%d' wird der LDAP Serverliste hinzugefügt\n" -#: src/ldap.c:254 +#: src/ldap.c:132 src/misc.c:652 #, c-format -msgid "ldap_result for an ldap_search failed: %s\n" -msgstr "ldap_result für eine ldap_search fehlgeschlagen: %s\n" +msgid "malloc failed: %s\n" +msgstr "malloc() fehlgeschlagen: %s\n" -#: src/ldap.c:269 -msgid "ldap_parse_result failed\n" -msgstr "ldap_parse_result fehlgeschlagen\n" - -#: src/ldap.c:273 +#: src/ldap.c:207 #, c-format -msgid "ldap search result is: %s\n" -msgstr "Resultat der LDAP Suche ist: %s\n" +msgid "error printing log line: %s\n" +msgstr "Fehler beim Schreiben einer Logzeile: %s\n" -#: src/ldap.c:281 +#: src/ldap.c:253 #, c-format -msgid "unexpected message type %d returned for ldap_search\n" -msgstr "Unerwarteter Nachrichtentyp %d von ldap_search erhalten\n" +msgid "select failed: %s\n" +msgstr "select() fehlgeschlagen: %s\n" -#: src/ldap.c:342 +#: src/ldap.c:279 #, c-format -msgid "ldap_init failed for '%s:%d': %s\n" -msgstr "ldap_init für `%s:%d' fehlgeschlagen: %s\n" +msgid "error reading log from ldap wrapper %d: %s\n" +msgstr "Fehler beim Lesen des Logs vom LDAP Wrapper %d: %s\n" -#: src/ldap.c:352 +#: src/ldap.c:306 #, c-format -msgid "ldap_simple_bind failed for user '%s': %s\n" -msgstr "ldap_simple_bind für User `%s' fehlgeschlagen: %s\n" +msgid "waiting for ldap wrapper %d failed: %s\n" +msgstr "Warten auf den LDAP Wrapper %d fehlgeschlagen: %s\n" -#: src/ldap.c:353 src/ldap.c:761 src/ldap.c:776 -msgid "[none]" -msgstr "[nichts]" +#: src/ldap.c:311 +#, c-format +msgid "ldap wrapper %d ready: terminated\n" +msgstr "LDAP Wrapper %d fertig: abgebrochen\n" -#: src/ldap.c:368 +#: src/ldap.c:314 #, c-format -msgid "ldap_result for bind failed: %s\n" -msgstr "ldap_result für ldap_bind fehlgeschlagen: %s\n" +msgid "ldap wrapper %d ready: exit status %d\n" +msgstr "LDAP Wrapper %d fertig: Beendigunsstatus %d\n" -#: src/ldap.c:370 -msgid "timeout while waiting for ldap_bind to complete\n" -msgstr "Tiemout während des Wartens auf ldap_bind Ergebniss\n" +#: src/ldap.c:327 +#, c-format +msgid "ldap wrapper %d stalled - killing\n" +msgstr "LDAP Wrapper %d versackt - abgeschossen\n" -#: src/ldap.c:373 src/ldap.c:780 +#: src/ldap.c:380 src/ldap.c:401 #, c-format -msgid "unexpected message type %d returned for ldap_bind\n" -msgstr "Unerwarteter Nachrichtentyp %d von ldap_bind erhalten\n" +msgid "reading from ldap wrapper %d failed: %s\n" +msgstr "Lesen vom LDAP Wrapper %d fehlgeschlagen: %s\n" -#: src/ldap.c:389 src/ldap.c:931 +#: src/ldap.c:546 src/ldap.c:552 #, c-format -msgid "ldap_search failed: %s\n" -msgstr "ldap_search fehlgeschlagen: %s\n" +msgid "error creating a pipe: %s\n" +msgstr "Fehler beim Erzeugen einer Pipe: %s\n" -#: src/ldap.c:454 src/ldap.c:461 src/ldap.c:472 src/ldap.c:747 src/ldap.c:758 -#: src/ldap.c:773 +#: src/ldap.c:562 #, c-format -msgid "%s failed for `" -msgstr "%s fehlgeschlagen für '" +msgid "error forking process: %s\n" +msgstr "Fehler beim Forken eines Prozesses: %s\n" -#: src/ldap.c:510 +#: src/ldap.c:610 src/ldap.c:617 src/ldap.c:624 #, c-format -msgid "invalid char 0x%02x in host name - not added\n" -msgstr "Ungültiges Zeichen 0x%02X im Hostnamen - nicht hinzugefügt\n" +msgid "dup2 failed in child: %s\n" +msgstr "dup2() im Kindprozess fehlgeschlagen: %s\n" -#: src/ldap.c:515 +#: src/ldap.c:642 #, c-format -msgid "adding `%s:%d' to the ldap server list\n" -msgstr "`%s:%d' wird der LDAP Serverliste hinzugefügt\n" +msgid "error running `%s': %s\n" +msgstr "Fehler beim Ausführen von `%s': %s\n" -#: src/ldap.c:547 -msgid "' is not an LDAP URL\n" -msgstr "' ist kein LDAP URL\n" - -#: src/ldap.c:555 -msgid "' is an invalid LDAP URL\n" -msgstr "' ist ein ungültiger LDAP URL\n" +#: src/ldap.c:654 +#, c-format +msgid "error allocating memory: %s\n" +msgstr "Fehler beim Allozieren von Speicher: %s\n" -#: src/ldap.c:733 +#: src/ldap.c:1101 #, c-format msgid "start_cert_fetch: invalid pattern `%s'\n" msgstr "start_cert_fetch: Ungültiges Muster `%s'\n" -#: src/ldap.c:919 +#: src/ldap.c:1239 msgid "ldap_search hit the size limit of the server\n" msgstr "ldap_search erreichte die Größengrenze des Servers\n" -#: src/misc.c:426 +#: src/misc.c:428 msgid "invalid canonical S-expression found\n" msgstr "Ungültige kanonische S-Expression gefunden\n" -#: src/misc.c:450 +#: src/misc.c:452 #, c-format msgid "gcry_md_open failed: %s\n" msgstr "gcry_md_open fehlgeschlagen: %s\n" -#: src/misc.c:455 +#: src/misc.c:457 #, c-format msgid "oops: ksba_cert_hash failed: %s\n" msgstr "Nanu: ksba_cert_hash fehlgeschlagen: %s\n" -#: src/ocsp.c:65 +#: src/misc.c:491 +msgid "[none]" +msgstr "[nichts]" + +#: src/misc.c:668 +msgid "bad URL encoding detected\n" +msgstr "Fehlerhafte URL Kodierung erkannt\n" + +#: src/ocsp.c:67 #, c-format msgid "error reading from responder: %s\n" msgstr "Fehler beim Lesen vom Responder: %s\n" -#: src/ocsp.c:83 +#: src/ocsp.c:85 #, c-format msgid "response from server too large; limit is %d bytes\n" msgstr "Antwort vom Server zu lang; die Grenze sind %d Bytes\n" #: src/ocsp.c:120 +msgid "OCSP request not possible due to disabled HTTP\n" +msgstr "OCSP Anfrage nicht möglich da HTTP abgeschaltet ist\n" + +#: src/ocsp.c:127 #, c-format msgid "error setting OCSP target: %s\n" msgstr "Fehler beim Setzen des OCSP Ziels: %s\n" -#: src/ocsp.c:138 +#: src/ocsp.c:145 #, c-format msgid "error building OCSP request: %s\n" msgstr "Fehler beim Aufbauen der OCSP Anfrage: %s\n" -#: src/ocsp.c:145 +#: src/ocsp.c:154 #, c-format msgid "error connecting to `%s': %s\n" msgstr "Fehler beim Verbinden mit '%s': %s\n" -#: src/ocsp.c:169 src/ocsp.c:185 +#: src/ocsp.c:178 src/ocsp.c:194 #, c-format msgid "error reading HTTP response for `%s': %s\n" msgstr "Fehler beim Lesen der HTTP Antwort von `%s': %s\n" -#: src/ocsp.c:173 +#: src/ocsp.c:182 #, c-format msgid "error accessing `%s': http status %u\n" msgstr "Fehler beim Zugreifen auf `%s': HTTP Status %u\n" -#: src/ocsp.c:194 +#: src/ocsp.c:203 #, c-format msgid "error parsing OCSP response for `%s': %s\n" msgstr "Fehler beim Zerlegen der OCSP Antwort für `%s': %s\n" -#: src/ocsp.c:216 src/ocsp.c:226 +#: src/ocsp.c:225 src/ocsp.c:235 #, c-format msgid "OCSP responder at `%s' status: %s\n" msgstr "OCSP Responder `%s' Status: %s\n" -#: src/ocsp.c:221 +#: src/ocsp.c:230 #, c-format msgid "hashing the OCSP response for `%s' failed: %s\n" msgstr "Hashen der OCSP Antwort für `%s' fehlgeschlagen: %s\n" -#: src/ocsp.c:317 +#: src/ocsp.c:335 msgid "only SHA-1 is supported for OCSP responses\n" msgstr "Lediglich SHA-1 wird bei OCSP Antworten unterstützt\n" -#: src/ocsp.c:367 +#: src/ocsp.c:385 msgid "no suitable certificate found to verify the OCSP response\n" msgstr "" "Kein benutzbares Zertifikat zur Ãœberprüfung der OCSP Antwort gefunden\n" -#: src/ocsp.c:396 +#: src/ocsp.c:421 src/validate.c:419 #, c-format -msgid "failed to allocate OCSP context: %s\n" -msgstr "Fehler beim Bereitstellen eines OCSP Kontext: %s\n" +msgid "issuer certificate not found: %s\n" +msgstr "Herausgeberzertifikat nicht gefunden: %s\n" -#: src/ocsp.c:406 +#: src/ocsp.c:431 msgid "caller did not return the target certificate\n" msgstr "Aufrufer gab das Ziel Zertifikat nicht zurück\n" -#: src/ocsp.c:413 +#: src/ocsp.c:438 msgid "caller did not return the issuing certificate\n" msgstr "Aufrufer gab das Issuer Zertifikat nicht zurück\n" -#: src/ocsp.c:445 +#: src/ocsp.c:448 +#, c-format +msgid "failed to allocate OCSP context: %s\n" +msgstr "Fehler beim Bereitstellen eines OCSP Kontext: %s\n" + +#: src/ocsp.c:482 #, c-format msgid "can't get authorityInfoAccess: %s\n" msgstr "authorityInfoAccess kann nicht geholt werden: %s\n" -#: src/ocsp.c:452 +#: src/ocsp.c:489 msgid "no default OCSP responder defined\n" msgstr "Kein voreingestellter OCSP Responder definiert\n" -#: src/ocsp.c:458 +#: src/ocsp.c:495 msgid "no default OCSP signer defined\n" msgstr "Kein voreingestellter OCSP \"Signer\" definiert\n" -#: src/ocsp.c:465 +#: src/ocsp.c:502 #, c-format msgid "using default OCSP responder `%s'\n" msgstr "Der voreingestellte OCSP Responder `%s' wird benutzt\n" -#: src/ocsp.c:470 +#: src/ocsp.c:507 #, c-format msgid "using OCSP responder `%s'\n" msgstr "Der OCSP Responder `%s' wird benutzt\n" -#: src/ocsp.c:477 +#: src/ocsp.c:514 #, c-format msgid "failed to establish a hashing context for OCSP: %s\n" msgstr "Kontext zum Hashen von OCSP kann nicht erzeugt werden: %s\n" -#: src/ocsp.c:507 +#: src/ocsp.c:544 #, c-format msgid "error getting OCSP status for target certificate: %s\n" msgstr "Fehler beim Holen des OCSP Status für das Zielzertifikat: %s\n" -#: src/ocsp.c:514 +#: src/ocsp.c:551 #, c-format msgid "certificate status is: %s (this=%s next=%s)\n" msgstr "Zertifikatstatus ist: %s (this=%s next=%s)\n" -#: src/ocsp.c:515 +#: src/ocsp.c:552 msgid "good" msgstr "Gut" -#: src/ocsp.c:516 +#: src/ocsp.c:553 msgid "revoked" msgstr "Widerrufen" -#: src/ocsp.c:517 +#: src/ocsp.c:554 msgid "unknown" msgstr "Unbekannt" -#: src/ocsp.c:518 +#: src/ocsp.c:555 msgid "none" msgstr "Kein" -#: src/ocsp.c:521 +#: src/ocsp.c:558 #, c-format msgid "certificate has been revoked at: %s due to: %s\n" msgstr "Zertifikat wurde widerrufen am: %s wegen: %s\n" -#: src/ocsp.c:554 +#: src/ocsp.c:591 msgid "OCSP responder returned an too old status\n" msgstr "OCSP Responder gab einen zu alten Status zurück\n" -#: src/ocsp.c:564 +#: src/ocsp.c:601 msgid "OCSP responder returned a non-current status\n" msgstr "OCSP Responder gab einen nicht aktuellen Status zurück\n" -#: src/server.c:183 +#: src/server.c:131 src/server.c:438 src/server.c:520 src/server.c:771 +#: src/server.c:824 #, c-format msgid "assuan_inquire failed: %s\n" msgstr "assuan_inquire fehlgeschlagen: %s\n" -#: src/server.c:318 -#, c-format -msgid "crl_fetch via DP failed: %s\n" -msgstr "crl_fetch über den DP fehlgeschlagen: %s\n" - -#: src/server.c:326 -#, c-format -msgid "crl_cache_insert via DP failed: %s\n" -msgstr "crl_cache_insert über den DP fehlgeschlagen: %s\n" - -#: src/server.c:349 -#, c-format -msgid "crl_fetch via issuer failed: %s\n" -msgstr "crl_fetch über den Issuer fehlgeschlagen: %s\n" - -#: src/server.c:358 -#, c-format -msgid "crl_cache_insert via issuer failed: %s\n" -msgstr "crl_cache_insert über den Issuer fehlgeschlagen: %s\n" - -#: src/server.c:439 +#: src/server.c:301 msgid "serialno missing in cert ID" msgstr "Seriennummer fehlt in der Cert-ID" -#: src/server.c:490 src/server.c:628 src/server.c:656 src/server.c:681 +#: src/server.c:352 src/server.c:468 src/server.c:547 src/server.c:687 +#: src/server.c:715 src/server.c:739 src/server.c:792 src/server.c:845 #, c-format msgid "command %s failed: %s\n" msgstr "Kommando %s fehlgeschlagen: %s\n" -#: src/server.c:557 +#: src/server.c:615 #, c-format msgid "start_cert_fetch failed: %s\n" msgstr "start_cert_fetch fehlgeschlagen: %s\n" -#: src/server.c:583 +#: src/server.c:642 #, c-format msgid "fetch_next_cert failed: %s\n" msgstr "fetch_next_cert fehlgeschlagen: %s\n" -#: src/server.c:602 +#: src/server.c:661 #, c-format msgid "error sending data: %s\n" msgstr "Fehler beim Senden der Daten: %s\n" -#: src/server.c:611 +#: src/server.c:670 #, c-format msgid "max_replies %d exceeded\n" msgstr "max_replies %d überschritten\n" -#: src/server.c:677 +#: src/server.c:735 msgid "no data stream" msgstr "Kein Datenstrom" -#: src/server.c:735 +#: src/server.c:898 +#, c-format +msgid "can't allocate control structure: %s\n" +msgstr "Fehler beim Erzeugen der Kontrollstruktur: %s\n" + +#: src/server.c:921 #, c-format msgid "failed to initialize the server: %s\n" msgstr "Fehler beim Initialisieren des Servers: %s\n" -#: src/server.c:743 +#: src/server.c:929 #, c-format msgid "failed to the register commands with Assuan: %s\n" msgstr "Fehler beim Registrieren der Kommandos gegen Assuan: %s\n" -#: src/server.c:769 +#: src/server.c:949 #, c-format msgid "Assuan accept problem: %s\n" msgstr "Assuan accept Problem: %s\n" -#: src/server.c:776 +#: src/server.c:956 #, c-format msgid "Assuan processing failed: %s\n" msgstr "Assuan Verarbeitung fehlgeschlagen: %s\n" -#~ msgid "ldap_simple_bind failed: %s\n" -#~ msgstr "ldap_simple_bind fehlgeschlagen: %s\n" +#: src/validate.c:92 +#, c-format +msgid "critical certificate extension %s is not supported" +msgstr "Die kritische Zertifikaterweiterung %s wird nicht unterstützt" + +#: src/validate.c:152 +msgid "note: non-critical certificate policy not allowed" +msgstr "Notiz: Die unkritische Zertifikatrichtlinie ist nicht erlaubt" + +#: src/validate.c:157 +msgid "certificate policy not allowed" +msgstr "Die Zertifikatrichtlinie ist nicht erlaubt" + +#: src/validate.c:177 +msgid "issuer certificate is not marked as a CA" +msgstr "Das Herausgeberzertifikat ist nicht für eine CA gekennzeichnet" + +#: src/validate.c:302 +#, c-format +msgid "certificate with invalid validity: %s" +msgstr "Zertifikat mit unzulässiger Gültigkeit: %s" + +#: src/validate.c:320 +msgid "certificate not yet valid" +msgstr "Das Zertifikat ist noch nicht gültig" + +#: src/validate.c:331 +msgid "certificate has expired" +msgstr "Das Zertifikat ist abgelaufen" + +#: src/validate.c:360 +msgid "selfsigned certificate has a BAD signature" +msgstr "Das eigenbeglaubigte Zertifikat hat eine FALSCHE Signatur" + +#: src/validate.c:378 +msgid "root certificate is not marked trusted" +msgstr "Das Wurzelzertifikat ist nicht als vertrauenswürdig markiert" + +#: src/validate.c:380 +#, c-format +msgid "fingerprint=%s\n" +msgstr "Fingerprint=%s\n" + +#: src/validate.c:386 +#, c-format +msgid "checking trustworthiness of root certificate failed: %s\n" +msgstr "" +"Prüfung der Vertrauenswürdigkeit des Wurzelzertifikats fehlgeschlagen: %s\n" + +#: src/validate.c:401 +msgid "certificate chain too long\n" +msgstr "Der Zertifikatkette ist zu lang\n" + +#: src/validate.c:413 +msgid "issuer certificate not found" +msgstr "Herausgeberzertifikat nicht gefunden" + +#: src/validate.c:439 +msgid "certificate has a BAD signature" +msgstr "Das Zertifikat hat eine FALSCHE Signatur" + +#: src/validate.c:463 +msgid "found another possible matching CA certificate - trying again" +msgstr "" +"Eine anderes möglicherweise passendes CA-Zertifikat gefunden - versuche " +"nochmal" + +#: src/validate.c:488 +#, c-format +msgid "certificate chain longer than allowed by CA (%d)" +msgstr "Die Zertifikatkette ist länger als von der CA erlaubt (%d)" + +#: src/validate.c:725 +msgid "DSA requires the use of a 160 bit hash algorithm\n" +msgstr "DSA benötigt eine 160 Bit Hashmethode\n" + +#: src/validate.c:832 +msgid "no key usage specified - assuming all usages\n" +msgstr "" +"Schlüsselverwendungszweck nicht vorhanden - für alle Zwecke akzeptiert\n" + +#: src/validate.c:842 +#, c-format +msgid "error getting key usage information: %s\n" +msgstr "Fehler beim holen der Schlüsselbenutzungsinformationen: %s\n" + +#: src/validate.c:852 +msgid "certificate should have not been used for certification\n" +msgstr "Das Zertifikat hätte nicht zum Zertifizieren benutzt werden sollen\n" + +#: src/validate.c:864 +msgid "certificate should have not been used for OCSP response signing\n" +msgstr "" +"Das Zertifikat hätte nicht zum Signieren von OCSP Antworten benutzt werden " +"sollen\n" + +#: src/validate.c:875 +msgid "certificate should have not been used for encryption\n" +msgstr "Das Zertifikat hätte nicht zum Verschlüsseln benutzt werden sollen\n" + +#: src/validate.c:877 +msgid "certificate should have not been used for signing\n" +msgstr "Das Zertifikat hätte nicht zum Signieren benutzt werden sollen\n" + +#: src/validate.c:878 +msgid "certificate is not usable for encryption\n" +msgstr "Das Zertifikat kann nicht zum Verschlüsseln benutzt werden\n" + +#: src/validate.c:879 +msgid "certificate is not usable for signing\n" +msgstr "Das Zertifikat kann nicht zum Signieren benutzt werden\n" + +#: src/dirmngr-client.c:66 +msgid "use OCSP instead of CRLs" +msgstr "OCSP anstatt CRL benutzen" + +#: src/dirmngr-client.c:67 +msgid "check whether a dirmngr is running" +msgstr "Teste ob der dirmngr noch läuft" + +#: src/dirmngr-client.c:68 +msgid "add a certificate to the cache" +msgstr "Ein Zertifikat dem Cache zufügen" + +#: src/dirmngr-client.c:69 +msgid "validate a certificate" +msgstr "Zertifikat prüfen" + +#: src/dirmngr-client.c:70 +msgid "lookup a certificate" +msgstr "Zertifikat auffinden" + +#: src/dirmngr-client.c:130 +msgid "Usage: dirmngr-client [options] [certfile|pattern] (-h for help)\n" +msgstr "" +"Gebrauch: dirmngr-client [Optionen] [Zertdatei|Muster] (-h für Hilfe)\n" + +#: src/dirmngr-client.c:134 +msgid "" +"Syntax: dirmngr-client [options] [certfile|pattern]\n" +"Test an X.509 certificate against a CRL or do an OCSP check\n" +"The process returns 0 if the certificate is valid, 1 if it is\n" +"not valid and other error codes for general failures\n" +msgstr "" +"Gebrauch: dirmngr-client [Optionen] [Zertdatei|Muster]\n" +"Teste ein X.509 Zertifikat gegen eine CRL oder führe eine OCSP Prüfung " +"durch\n" +"The Prozess gibt 0 zurück wenn das Zertifikat gültig ist, 1 wenn es nicht\n" +"gültig ist und weitere Werte bei anderen Fehlern.\n" + +#: src/dirmngr-client.c:220 +#, c-format +msgid "error reading certificate from stdin: %s\n" +msgstr "Fehler beim Lesen des Zertifikats von der Standardeingabe: %s\n" + +#: src/dirmngr-client.c:227 +#, c-format +msgid "error reading certificate from `%s': %s\n" +msgstr "Fehler beim Lesen des Zertifikats von `%s': %s\n" + +#: src/dirmngr-client.c:241 +msgid "certificate too large to make any sense\n" +msgstr "Zertifikat ist zu groß um Sinnvoll zu sein\n" + +#: src/dirmngr-client.c:260 +#, c-format +msgid "lookup failed: %s\n" +msgstr "Aufsuchen fehlgeschlagen: %s\n" + +#: src/dirmngr-client.c:287 +msgid "a dirmngr daemon is up and running\n" +msgstr "Ein dirmngr ist vorhanden und aktiv\n" + +#: src/dirmngr-client.c:309 +#, c-format +msgid "validation of certificate failed: %s\n" +msgstr "Prüfung des Zertifikats fehlgeschlagen: %s\n" + +#: src/dirmngr-client.c:316 +msgid "certificate is valid\n" +msgstr "Zertifikat ist gültig\n" + +#: src/dirmngr-client.c:322 +msgid "certificate has been revoked\n" +msgstr "Zertifikat wurde widerrufen\n" + +#: src/dirmngr-client.c:327 +#, c-format +msgid "certificate check failed: %s\n" +msgstr "Zertifikatprüfung fehlgeschlagen: %s\n" + +#: src/dirmngr-client.c:338 +#, c-format +msgid "got status: `%s'\n" +msgstr "Erhielt Status: `%s'\n" + +#: src/dirmngr-client.c:353 +#, c-format +msgid "error writing base64 encoding: %s\n" +msgstr "Fehler beim Schreiben der Base-64 Darstellung: %s\n" + +#: src/dirmngr-client.c:385 +msgid "apparently no running dirmngr\n" +msgstr "Offensichtlich ist kein Dirmngr vorhanden\n" + +#: src/dirmngr-client.c:390 +msgid "no running dirmngr - starting one\n" +msgstr "Dirmngr läuft nicht - ein neuer wird gestartet\n" + +#: src/dirmngr-client.c:423 +msgid "malformed DIRMNGR_INFO environment variable\n" +msgstr "Fehlerhafte DIRMNGR_INFO Variable\n" + +#: src/dirmngr-client.c:438 +#, c-format +msgid "dirmngr protocol version %d is not supported\n" +msgstr "Dirmngr Protocol Version %d wird nicht unterstützt\n" + +#: src/dirmngr-client.c:454 +msgid "can't connect to the dirmngr - trying fall back\n" +msgstr "Verbindung zum Dirmngr nicht möglich - Rückfallmethode wird versucht\n" + +#: src/dirmngr-client.c:462 +#, c-format +msgid "can't connect to the dirmngr: %s\n" +msgstr "Verbindung zum Dirmngr nicht möglich: %s\n" + +#: src/dirmngr-client.c:545 +#, c-format +msgid "unsupported inquiry `%s'\n" +msgstr "Nicht unterstützte INQUIRY `%s'\n" + +#: src/dirmngr-client.c:626 +#, c-format +msgid "looking up `%s'\n" +msgstr "Auffinden von `%s'\n" + +#: src/no-libgcrypt.c:39 +#, c-format +msgid "error allocating enough memory: %s\n" +msgstr "Fehler beim Allozieren von genügend Speicher: %s\n" + +#: src/dirmngr_ldap.c:76 +msgid "return all values in a record oriented format" +msgstr "Alle Werte in einem Record Format zurückgeben" + +#: src/dirmngr_ldap.c:79 +msgid "|NAME|ignore host part and connect through NAME" +msgstr "|NAME|Host Teil ignorieren und über NAME verbinden" + +#: src/dirmngr_ldap.c:80 +msgid "|NAME|connect to host NAME" +msgstr "|NAME|Verbinde mit dem Host NAME" + +#: src/dirmngr_ldap.c:81 +msgid "|N|connect to port N" +msgstr "|N|Verbinde mit dem Port N" + +#: src/dirmngr_ldap.c:82 +msgid "|NAME|use user NAME for authentication" +msgstr "|NAME|Benutze NAME zur Authentifizierung" + +#: src/dirmngr_ldap.c:83 +msgid "|PASS|use password PASS for authentication" +msgstr "Benutze Passwort PASS zur Authentifizierung" + +#: src/dirmngr_ldap.c:85 +msgid "take password from $DIRMNGR_LDAP_PASS" +msgstr "Nimm das Passwort von $DIRMNGR_LDAP_PASS" + +#: src/dirmngr_ldap.c:86 +msgid "|STRING|query DN STRING" +msgstr "|STRING|Frage den DN STRING ab" + +#: src/dirmngr_ldap.c:87 +msgid "|STRING|use STRING as filter expression" +msgstr "|STRING|Benutze STRING als Filterausdruck" + +#: src/dirmngr_ldap.c:88 +msgid "|STRING|return the attribute STRING" +msgstr "|STRING|Gib das Attribut STRING zurück" + +#: src/dirmngr_ldap.c:138 +msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n" +msgstr "Gebrauch: dirmngr_ldap [Optionen] [URL] (-h für Hilfe)\n" + +#: src/dirmngr_ldap.c:141 +msgid "" +"Syntax: dirmngr_ldap [options] [URL]\n" +"Internal LDAP helper for Dirmngr.\n" +"Interface and options may change without notice.\n" +msgstr "" +"Gebrauch: dirmngr_ldap [Optionen] [URL] (-h für Hilfe)\n" +"Internes LDAP Hilfprogramm für Drimngr.\n" +"Interface und Optionen können sich mit jedem Release ändern.\n" + +#: src/dirmngr_ldap.c:230 +#, c-format +msgid "invalid port number %d\n" +msgstr "Ungültige Portnummer %d\n" + +#: src/dirmngr_ldap.c:261 +#, c-format +msgid "scanning result for attribute `%s'\n" +msgstr "Absuchen des Ergebnisses nach Attribut `%s'\n" + +#: src/dirmngr_ldap.c:268 src/dirmngr_ldap.c:328 src/dirmngr_ldap.c:352 +#: src/dirmngr_ldap.c:363 src/dirmngr_ldap.c:473 +#, c-format +msgid "error writing to stdout: %s\n" +msgstr "Fehler beim Schreiben auf Standardausgabe: %s\n" + +#: src/dirmngr_ldap.c:282 +#, c-format +msgid " available attribute `%s'\n" +msgstr " verfügbare Attribute `%s'\n" + +#: src/dirmngr_ldap.c:307 +#, c-format +msgid "attribute `%s' not found\n" +msgstr "Attribut `%s' nicht gefunden\n" + +#: src/dirmngr_ldap.c:313 +#, c-format +msgid "found attribute `%s'\n" +msgstr "Attribut `%s' gefunden\n" + +#: src/dirmngr_ldap.c:410 +#, c-format +msgid "processing url `%s'\n" +msgstr "Verarbeiten der URL `%s'\n" + +#: src/dirmngr_ldap.c:412 +#, c-format +msgid " user `%s'\n" +msgstr " Benutzer `%s'\n" + +#: src/dirmngr_ldap.c:414 +#, c-format +msgid " pass `%s'\n" +msgstr " Passwort `%s'\n" + +#: src/dirmngr_ldap.c:416 +#, c-format +msgid " host `%s'\n" +msgstr " Host `%s'\n" + +#: src/dirmngr_ldap.c:417 +#, c-format +msgid " port %d\n" +msgstr " Port %d\n" + +#: src/dirmngr_ldap.c:419 +#, c-format +msgid " DN `%s'\n" +msgstr " DN `%s'\n" + +#: src/dirmngr_ldap.c:421 +#, c-format +msgid " filter `%s'\n" +msgstr " Filter `%s'\n" + +#: src/dirmngr_ldap.c:426 src/dirmngr_ldap.c:429 +#, c-format +msgid " attr `%s'\n" +msgstr " Attribut `%s'\n" + +#: src/dirmngr_ldap.c:435 +#, c-format +msgid "no host name in `%s'\n" +msgstr "Kein Hostname in `%s'\n" + +#: src/dirmngr_ldap.c:440 +#, c-format +msgid "no attribute given for query `%s'\n" +msgstr "Kein Attribut für Abfrage `%s' angegeben\n" + +#: src/dirmngr_ldap.c:446 +msgid "WARNING: using first attribute only\n" +msgstr "WARNUNG: Es wird nur das erste Attribut benutzt\n" + +#: src/dirmngr_ldap.c:452 +#, c-format +msgid "LDAP init to `%s:%d' failed: %s\n" +msgstr "LDAP Initialisierung von `%s:%d' fehlgeschlagen: %s\n" + +#: src/dirmngr_ldap.c:458 +#, c-format +msgid "binding to `%s:%d' failed: %s\n" +msgstr "Anbindung an `%s:%d' fehlgeschlagen: %s\n" + +#: src/dirmngr_ldap.c:480 +#, c-format +msgid "searching `%s' failed: %s\n" +msgstr "Suche mit `%s' fehlgeschlagen: %s\n" + +#: src/dirmngr_ldap.c:508 +#, c-format +msgid "`%s' is not an LDAP URL\n" +msgstr "`%s' ist kein LDAP URL\n" + +#: src/dirmngr_ldap.c:514 +#, c-format +msgid "`%s' is an invalid LDAP URL\n" +msgstr "`%s' ist ein ungültiger LDAP URL\n" + +#~ msgid "can't open `/dev/null': %s\n" +#~ msgstr "`/dev/null' kann nicht geöffnet werden: %s\n" + +#~ msgid "failed to find issuer certificate: %s\n" +#~ msgstr "Herausgeberzertifikat nicht gefunden: %s\n" + +#~ msgid "Please report bugs to " +#~ msgstr "Berichte über Bugs (Programmfehler) bitte an " + +#~ msgid "no issuer found in certificate" +#~ msgstr "Im Zertifikat ist kein Herausgeber enthalten" + +#~ msgid "critical marked policy without configured policies" +#~ msgstr "kritische Richtlinie ohne konfigurierte Richtlinien" + +#~ msgid "looking up issuer at external location\n" +#~ msgstr "Der Herausgeber wird von einer externen Stelle gesucht\n" + +#~ msgid "number of issuers matching: %d\n" +#~ msgstr "Anzahl der übereinstimmenden Heruasgeber: %d\n" + +#~ msgid "certificate has been revoked" +#~ msgstr "Das Zertifikat wurde widerrufen" + +#~ msgid "no CRL found for certificate" +#~ msgstr "Keine CRL für das Zertifikat gefunden" + +#~ msgid "the available CRL is too old" +#~ msgstr "Die vorhandene CRL ist zu alt" + +#~ msgid "please make sure that the \"dirmngr\" is properly installed\n" +#~ msgstr "" +#~ "Bite vergewissern Sie sich das der \"dirmngr\" richtig installierrt ist\n" -#~ msgid "End CRL dump (retrieved via %s)\n" -#~ msgstr "Ende der CRL Ausgabe (erhalten via %s)\n" +#~ msgid "checking the CRL failed: %s" +#~ msgstr "Die CRL konnte nicht geprüft werden: %s" -#~ msgid "WARNING: only one OCSP responder currently supported\n" -#~ msgstr "WARNUNG: Zur Zeit wird nur ein OCSP Responder unterstützt\n" +#~ msgid "root certificate has now been marked as trusted\n" +#~ msgstr "Das Wurzelzertifikat wurde nun als vertrauenswürdig markiert\n" -#~ msgid "ocsp_responder at `%s' status: %s\n" -#~ msgstr "OCSP Responder `%s' Status: %s\n" +#~ msgid "checking the trust list failed: %s\n" +#~ msgstr "Fehler beim Prüfen der vertrauenswürdigen Zertifikate: %s\n" Index: dirmngr/po/dirmngr.pot diff -u dirmngr/po/dirmngr.pot:1.5 dirmngr/po/dirmngr.pot:1.6 --- dirmngr/po/dirmngr.pot:1.5 Wed Nov 3 18:48:03 2004 +++ dirmngr/po/dirmngr.pot Wed Nov 24 13:25:53 2004 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: gpa-dev@gnupg.org\n" -"POT-Creation-Date: 2004-10-04 13:52+0200\n" +"POT-Creation-Date: 2004-11-24 13:16+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,1020 +16,1659 @@ "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: jnlib/logging.c:555 +#: jnlib/logging.c:624 #, c-format msgid "you found a bug ... (%s:%d)\n" msgstr "" -#: src/crlcache.c:177 +#: src/certcache.c:87 +#, c-format +msgid "can't acquire read lock on the certificate cache: %s\n" +msgstr "" + +#: src/certcache.c:95 +#, c-format +msgid "can't acquire write lock on the certificate cache: %s\n" +msgstr "" + +#: src/certcache.c:103 +#, c-format +msgid "can't release lock on the certificate cache: %s\n" +msgstr "" + +#: src/certcache.c:220 +#, c-format +msgid "dropping %u certificates from the cache\n" +msgstr "" + +#: src/certcache.c:304 +#, c-format +msgid "can't access directory `%s': %s\n" +msgstr "" + +#: src/certcache.c:323 src/crlcache.c:2142 src/ldap.c:605 +#, c-format +msgid "can't open `%s': %s\n" +msgstr "" + +#: src/certcache.c:332 +#, c-format +msgid "can't setup KSBA reader: %s\n" +msgstr "" + +#: src/certcache.c:345 +#, c-format +msgid "can't parse certificate `%s': %s\n" +msgstr "" + +#: src/certcache.c:354 +#, c-format +msgid "certificate `%s' already cached\n" +msgstr "" + +#: src/certcache.c:356 +#, c-format +msgid "certificate `%s' loaded\n" +msgstr "" + +#: src/certcache.c:358 +#, c-format +msgid "error loading certificate `%s': %s\n" +msgstr "" + +#: src/certcache.c:432 +#, c-format +msgid "permanently loaded certificates: %u\n" +msgstr "" + +#: src/certcache.c:434 +#, c-format +msgid " runtime cached certificates: %u\n" +msgstr "" + +#: src/certcache.c:449 src/dirmngr-client.c:297 +msgid "certificate already cached\n" +msgstr "" + +#: src/certcache.c:451 +msgid "certificate cached\n" +msgstr "" + +#: src/certcache.c:453 src/dirmngr-client.c:301 +#, c-format +msgid "error caching certificate: %s\n" +msgstr "" + +#: src/certcache.c:563 src/crlcache.c:1396 +#, c-format +msgid "error fetching certificate for issuer: %s\n" +msgstr "" + +#: src/certcache.c:574 src/crlcache.c:1412 +#, c-format +msgid "invalid issuer certificate: %s\n" +msgstr "" + +#: src/certcache.c:655 src/validate.c:288 +msgid "no issuer found in certificate\n" +msgstr "" + +#: src/certcache.c:665 +#, c-format +msgid "error getting authorityKeyIdentifier: %s\n" +msgstr "" + +#: src/crlcache.c:201 #, c-format msgid "creating directory `%s'\n" msgstr "" -#: src/crlcache.c:181 +#: src/crlcache.c:205 #, c-format msgid "error creating directory `%s': %s\n" msgstr "" -#: src/crlcache.c:209 +#: src/crlcache.c:233 #, c-format msgid "ignoring database dir `%s'\n" msgstr "" -#: src/crlcache.c:218 +#: src/crlcache.c:242 #, c-format msgid "error reading directory `%s': %s\n" msgstr "" -#: src/crlcache.c:239 +#: src/crlcache.c:263 #, c-format msgid "removing cache file `%s'\n" msgstr "" -#: src/crlcache.c:248 +#: src/crlcache.c:272 #, c-format msgid "not removing file `%s'\n" msgstr "" -#: src/crlcache.c:317 src/crlcache.c:962 +#: src/crlcache.c:341 src/crlcache.c:986 #, c-format msgid "error closing cache file: %s\n" msgstr "" -#: src/crlcache.c:354 src/crlcache.c:678 +#: src/crlcache.c:378 src/crlcache.c:702 #, c-format msgid "failed to open cache dir file `%s': %s\n" msgstr "" -#: src/crlcache.c:364 +#: src/crlcache.c:388 #, c-format msgid "error creating new cache dir file `%s': %s\n" msgstr "" -#: src/crlcache.c:371 +#: src/crlcache.c:395 #, c-format msgid "error writing new cache dir file `%s': %s\n" msgstr "" -#: src/crlcache.c:378 +#: src/crlcache.c:402 #, c-format msgid "error closing new cache dir file `%s': %s\n" msgstr "" -#: src/crlcache.c:383 +#: src/crlcache.c:407 #, c-format msgid "new cache dir file `%s' created\n" msgstr "" -#: src/crlcache.c:388 +#: src/crlcache.c:412 #, c-format msgid "failed to re-open cache dir file `%s': %s\n" msgstr "" -#: src/crlcache.c:415 +#: src/crlcache.c:439 #, c-format msgid "first record of `%s' is not the version\n" msgstr "" -#: src/crlcache.c:426 +#: src/crlcache.c:450 msgid "old version of cache directory - cleaning up\n" msgstr "" -#: src/crlcache.c:442 +#: src/crlcache.c:466 msgid "old version of cache directory - giving up\n" msgstr "" -#: src/crlcache.c:530 +#: src/crlcache.c:554 #, c-format msgid "extra field detected in crl record of `%s' line %u\n" msgstr "" -#: src/crlcache.c:542 +#: src/crlcache.c:566 #, c-format msgid "unsupported record type in `%s' line %u skipped\n" msgstr "" -#: src/crlcache.c:550 src/crlcache.c:779 src/dirmngr.c:810 +#: src/crlcache.c:574 src/crlcache.c:803 src/dirmngr.c:1191 #, c-format msgid "error reading `%s': %s\n" msgstr "" -#: src/crlcache.c:562 +#: src/crlcache.c:586 #, c-format msgid "invalid issuer hash in `%s' line %u\n" msgstr "" -#: src/crlcache.c:568 +#: src/crlcache.c:592 #, c-format msgid "no issuer DN in `%s' line %u\n" msgstr "" -#: src/crlcache.c:575 +#: src/crlcache.c:599 #, c-format msgid "invalid timestamp in `%s' line %u\n" msgstr "" -#: src/crlcache.c:581 +#: src/crlcache.c:605 #, c-format msgid "WARNING: invalid cache file hash in `%s' line %u\n" msgstr "" -#: src/crlcache.c:587 +#: src/crlcache.c:611 msgid "detected errors in cache dir file\n" msgstr "" -#: src/crlcache.c:588 +#: src/crlcache.c:612 msgid "please check the reason and manually delete that file\n" msgstr "" -#: src/crlcache.c:711 +#: src/crlcache.c:735 #, c-format msgid "failed to create temporary cache dir file `%s': %s\n" msgstr "" -#: src/crlcache.c:784 +#: src/crlcache.c:808 #, c-format msgid "error writing `%s': %s\n" msgstr "" -#: src/crlcache.c:795 +#: src/crlcache.c:819 #, c-format msgid "error closing `%s': %s\n" msgstr "" -#: src/crlcache.c:803 +#: src/crlcache.c:827 #, c-format msgid "error renaming `%s' to `%s': %s\n" msgstr "" -#: src/crlcache.c:858 +#: src/crlcache.c:882 #, c-format msgid "can't hash `%s': %s\n" msgstr "" -#: src/crlcache.c:866 +#: src/crlcache.c:890 #, c-format msgid "error setting up MD5 hash context: %s\n" msgstr "" -#: src/crlcache.c:882 +#: src/crlcache.c:906 #, c-format msgid "error hashing `%s': %s\n" msgstr "" -#: src/crlcache.c:910 +#: src/crlcache.c:934 #, c-format msgid "invalid formatted checksum for `%s'\n" msgstr "" -#: src/crlcache.c:953 +#: src/crlcache.c:977 msgid "too many open cache files; can't open anymore\n" msgstr "" -#: src/crlcache.c:970 +#: src/crlcache.c:994 #, c-format msgid "opening cache file `%s'\n" msgstr "" -#: src/crlcache.c:989 +#: src/crlcache.c:1013 #, c-format msgid "error opening cache file `%s': %s\n" msgstr "" -#: src/crlcache.c:998 +#: src/crlcache.c:1022 #, c-format msgid "error initializing cache file `%s' for reading: %s\n" msgstr "" -#: src/crlcache.c:1020 +#: src/crlcache.c:1044 msgid "calling unlock_db_file on a closed file\n" msgstr "" -#: src/crlcache.c:1022 +#: src/crlcache.c:1046 msgid "calling unlock_db_file on an unlocked file\n" msgstr "" -#: src/crlcache.c:1070 +#: src/crlcache.c:1100 #, c-format msgid "failed to create a new cache object: %s\n" msgstr "" -#: src/crlcache.c:1123 +#: src/crlcache.c:1153 #, c-format msgid "no CRL available for issuer id %s\n" msgstr "" -#: src/crlcache.c:1130 +#: src/crlcache.c:1160 #, c-format msgid "cached CRL for issuer id %s too old; update required\n" msgstr "" -#: src/crlcache.c:1144 +#: src/crlcache.c:1174 #, c-format msgid "" "force-crl-refresh active and %d minutes passed for issuer id %s; update " "required\n" msgstr "" -#: src/crlcache.c:1152 +#: src/crlcache.c:1182 #, c-format msgid "force-crl-refresh active for issuer id %s; update required\n" msgstr "" -#: src/crlcache.c:1161 +#: src/crlcache.c:1191 #, c-format msgid "available CRL for issuer ID %s can't be used\n" msgstr "" -#: src/crlcache.c:1172 +#: src/crlcache.c:1202 #, c-format msgid "cached CRL for issuer id %s tampered; we need to update\n" msgstr "" -#: src/crlcache.c:1190 -#, c-format -msgid "WARNING: invalid cache record length for S/N %s\n" +#: src/crlcache.c:1214 +msgid "WARNING: invalid cache record length for S/N " msgstr "" -#: src/crlcache.c:1197 +#: src/crlcache.c:1223 #, c-format msgid "problem reading cache record for S/N %s: %s\n" msgstr "" -#: src/crlcache.c:1200 +#: src/crlcache.c:1226 #, c-format msgid "S/N %s is not valid; reason=%02X date=%.15s\n" msgstr "" -#: src/crlcache.c:1208 +#: src/crlcache.c:1237 #, c-format msgid "S/N %s is valid, it is not listed in the CRL\n" msgstr "" -#: src/crlcache.c:1214 +#: src/crlcache.c:1245 #, c-format msgid "error getting data from cache file: %s\n" msgstr "" -#: src/crlcache.c:1252 -#, c-format -msgid "error fetching certificate for issuer: %s\n" -msgstr "" - -#: src/crlcache.c:1275 -#, c-format -msgid "invalid issuer certificate: %s\n" -msgstr "" - -#: src/crlcache.c:1295 +#: src/crlcache.c:1435 src/validate.c:636 #, c-format msgid "unknown hash algorithm `%s'\n" msgstr "" -#: src/crlcache.c:1302 +#: src/crlcache.c:1442 #, c-format msgid "gcry_md_open for algorithm %d failed: %s\n" msgstr "" -#: src/crlcache.c:1336 src/crlcache.c:1353 +#: src/crlcache.c:1476 src/crlcache.c:1493 msgid "got an invalid S-expression from libksba\n" msgstr "" -#: src/crlcache.c:1343 src/crlcache.c:1360 src/misc.c:430 +#: src/crlcache.c:1483 src/crlcache.c:1500 src/misc.c:432 #, c-format msgid "converting S-expression failed: %s\n" msgstr "" -#: src/crlcache.c:1375 src/ocsp.c:325 +#: src/crlcache.c:1515 src/ocsp.c:343 #, c-format msgid "creating S-expression failed: %s\n" msgstr "" -#: src/crlcache.c:1427 +#: src/crlcache.c:1567 #, c-format msgid "ksba_crl_parse failed: %s\n" msgstr "" -#: src/crlcache.c:1443 +#: src/crlcache.c:1583 #, c-format msgid "no issuer found in CRL: %s\n" msgstr "" -#: src/crlcache.c:1461 +#: src/crlcache.c:1601 #, c-format msgid "error getting update times of CRL: %s\n" msgstr "" -#: src/crlcache.c:1468 +#: src/crlcache.c:1608 #, c-format msgid "update times of this CRL: this=%s next=%s\n" msgstr "" -#: src/crlcache.c:1487 +#: src/crlcache.c:1627 #, c-format msgid "error getting CRL item: %s\n" msgstr "" -#: src/crlcache.c:1502 +#: src/crlcache.c:1642 #, c-format msgid "error inserting item into temporary cache file: %s\n" msgstr "" -#: src/crlcache.c:1520 +#: src/crlcache.c:1660 #, c-format msgid "CRL signature verification failed: %s\n" msgstr "" -#: src/crlcache.c:1639 +#: src/crlcache.c:1668 #, c-format -msgid "ksba_crl_new failed: %s\n" +msgid "error checking validity of CRL signing certificate: %s\n" msgstr "" -#: src/crlcache.c:1648 +#: src/crlcache.c:1793 #, c-format -msgid "ksba_reader_set_file failed: %s\n" +msgid "ksba_crl_new failed: %s\n" msgstr "" -#: src/crlcache.c:1654 +#: src/crlcache.c:1800 #, c-format msgid "ksba_crl_set_reader failed: %s\n" msgstr "" -#: src/crlcache.c:1677 +#: src/crlcache.c:1823 #, c-format msgid "removed stale temporary cache file `%s'\n" msgstr "" -#: src/crlcache.c:1680 +#: src/crlcache.c:1826 #, c-format msgid "problem removing stale temporary cache file `%s': %s\n" msgstr "" -#: src/crlcache.c:1690 +#: src/crlcache.c:1836 #, c-format msgid "error creating temporary cache file `%s': %s\n" msgstr "" -#: src/crlcache.c:1700 +#: src/crlcache.c:1846 #, c-format msgid "crl_parse_insert failed: %s\n" msgstr "" -#: src/crlcache.c:1709 +#: src/crlcache.c:1855 #, c-format msgid "error finishing temporary cache file `%s': %s\n" msgstr "" -#: src/crlcache.c:1716 +#: src/crlcache.c:1862 #, c-format msgid "error closing temporary cache file `%s': %s\n" msgstr "" -#: src/crlcache.c:1741 +#: src/crlcache.c:1887 #, c-format msgid "WARNING: new CRL still too old; it expired on %s - loading anyway\n" msgstr "" -#: src/crlcache.c:1745 +#: src/crlcache.c:1891 #, c-format msgid "new CRL still too old; it expired on %s\n" msgstr "" -#: src/crlcache.c:1761 +#: src/crlcache.c:1907 #, c-format msgid "unknown crtical CRL extension %s\n" msgstr "" -#: src/crlcache.c:1771 +#: src/crlcache.c:1917 #, c-format msgid "error reading CRL extensions: %s\n" msgstr "" -#: src/crlcache.c:1805 +#: src/crlcache.c:1951 #, c-format msgid "creating cache file `%s'\n" msgstr "" -#: src/crlcache.c:1809 +#: src/crlcache.c:1955 #, c-format msgid "problem renaming `%s' to `%s': %s\n" msgstr "" -#: src/crlcache.c:1823 +#: src/crlcache.c:1969 msgid "" "updating the DIR file failed - cache entry will get lost with the next " "program start\n" msgstr "" -#: src/crlcache.c:1860 +#: src/crlcache.c:2005 #, c-format msgid "Begin CRL dump (retrieved via %s)\n" msgstr "" -#: src/crlcache.c:1880 +#: src/crlcache.c:2025 #, c-format msgid "" " ERROR: The CRL will not be used because it was still too old after an " "update!\n" msgstr "" -#: src/crlcache.c:1882 +#: src/crlcache.c:2027 #, c-format msgid "" " ERROR: The CRL will not be used due to an unknown critical extension!\n" msgstr "" -#: src/crlcache.c:1884 +#: src/crlcache.c:2029 #, c-format msgid " ERROR: The CRL will not be used\n" msgstr "" -#: src/crlcache.c:1891 +#: src/crlcache.c:2036 #, c-format msgid " ERROR: This cached CRL may has been tampered with!\n" msgstr "" -#: src/crlcache.c:1908 +#: src/crlcache.c:2053 msgid " WARNING: invalid cache record length\n" msgstr "" -#: src/crlcache.c:1915 +#: src/crlcache.c:2060 #, c-format msgid "problem reading cache record: %s\n" msgstr "" -#: src/crlcache.c:1926 +#: src/crlcache.c:2071 #, c-format msgid "problem reading cache key: %s\n" msgstr "" -#: src/crlcache.c:1957 +#: src/crlcache.c:2102 #, c-format msgid "error reading cache entry from db: %s\n" msgstr "" -#: src/crlcache.c:1960 +#: src/crlcache.c:2105 #, c-format msgid "End CRL dump\n" msgstr "" -#: src/crlcache.c:1996 +#: src/crlcache.c:2217 #, c-format -msgid "can't open `%s': %s\n" +msgid "crl_fetch via DP failed: %s\n" +msgstr "" + +#: src/crlcache.c:2224 +#, c-format +msgid "crl_cache_insert via DP failed: %s\n" +msgstr "" + +#: src/crlcache.c:2255 +#, c-format +msgid "crl_fetch via issuer failed: %s\n" msgstr "" -#: src/crlfetch.c:130 +#: src/crlcache.c:2263 +#, c-format +msgid "crl_cache_insert via issuer failed: %s\n" +msgstr "" + +#: src/crlfetch.c:61 msgid "using \"http\" instead of \"https\"\n" msgstr "" -#: src/crlfetch.c:141 +#: src/crlfetch.c:72 src/crlfetch.c:116 src/crlfetch.c:136 src/crlfetch.c:151 +#, c-format +msgid "CRL access not possible due to disabled %s\n" +msgstr "" + +#: src/crlfetch.c:82 #, c-format msgid "error retrieving `%s': %s\n" msgstr "" -#: src/crlfetch.c:144 +#: src/crlfetch.c:85 #, c-format msgid "error retrieving `%s': http status %u\n" msgstr "" -#: src/dirmngr.c:88 +#: src/crlfetch.c:97 src/ldap.c:673 +#, c-format +msgid "error initializing reader object: %s\n" +msgstr "" + +#: src/crlfetch.c:165 +#, c-format +msgid "Certificate search not possible due to disabled %s\n" +msgstr "" + +#: src/dirmngr.c:105 msgid "" "@Commands:\n" " " msgstr "" -#: src/dirmngr.c:90 -msgid "run in server mode" +#: src/dirmngr.c:107 +msgid "run in server mode (foreground)" +msgstr "" + +#: src/dirmngr.c:108 +msgid "run in daemon mode (background)" msgstr "" -#: src/dirmngr.c:91 +#: src/dirmngr.c:109 msgid "list the contents of the CRL cache" msgstr "" -#: src/dirmngr.c:92 +#: src/dirmngr.c:110 msgid "|FILE|load CRL from FILE into cache" msgstr "" -#: src/dirmngr.c:93 +#: src/dirmngr.c:111 msgid "|URL|fetch a CRL from URL" msgstr "" -#: src/dirmngr.c:94 +#: src/dirmngr.c:112 msgid "shutdown the dirmngr" msgstr "" -#: src/dirmngr.c:95 +#: src/dirmngr.c:113 msgid "flush the cache" msgstr "" -#: src/dirmngr.c:98 +#: src/dirmngr.c:116 msgid "" "@\n" "Options:\n" " " msgstr "" -#: src/dirmngr.c:100 +#: src/dirmngr.c:118 src/dirmngr-client.c:64 src/dirmngr_ldap.c:73 msgid "verbose" msgstr "" -#: src/dirmngr.c:101 +#: src/dirmngr.c:119 src/dirmngr-client.c:65 src/dirmngr_ldap.c:74 msgid "be somewhat more quiet" msgstr "" -#: src/dirmngr.c:102 +#: src/dirmngr.c:120 msgid "sh-style command output" msgstr "" -#: src/dirmngr.c:103 +#: src/dirmngr.c:121 msgid "csh-style command output" msgstr "" -#: src/dirmngr.c:104 +#: src/dirmngr.c:122 msgid "|FILE|read options from FILE" msgstr "" -#: src/dirmngr.c:106 +#: src/dirmngr.c:124 msgid "|LEVEL|set the debugging level to LEVEL" msgstr "" -#: src/dirmngr.c:107 +#: src/dirmngr.c:125 msgid "do not detach from the console" msgstr "" -#: src/dirmngr.c:108 +#: src/dirmngr.c:126 msgid "|FILE|write logs to FILE" msgstr "" -#: src/dirmngr.c:109 +#: src/dirmngr.c:127 msgid "run without asking a user" msgstr "" -#: src/dirmngr.c:110 +#: src/dirmngr.c:128 msgid "force loading of outdated CRLs" msgstr "" -#: src/dirmngr.c:111 +#: src/dirmngr.c:129 msgid "allow sending OCSP requests" msgstr "" -#: src/dirmngr.c:114 +#: src/dirmngr.c:130 +msgid "inhibit the use of HTTP" +msgstr "" + +#: src/dirmngr.c:131 +msgid "inhibit the use of LDAP" +msgstr "" + +#: src/dirmngr.c:133 +msgid "ignore HTTP CRL distribution points" +msgstr "" + +#: src/dirmngr.c:135 +msgid "ignore LDAP CRL distribution points" +msgstr "" + +#: src/dirmngr.c:137 +msgid "|URL|redirect all HTTP requests to URL" +msgstr "" + +#: src/dirmngr.c:139 +msgid "|HOST|use HOST for LDAP queries" +msgstr "" + +#: src/dirmngr.c:141 +msgid "do not use fallback hosts with --ldap-proxy" +msgstr "" + +#: src/dirmngr.c:144 msgid "|FILE|read LDAP server list from FILE" msgstr "" -#: src/dirmngr.c:116 +#: src/dirmngr.c:146 msgid "add new servers discovered in CRL distribution points to serverlist" msgstr "" -#: src/dirmngr.c:118 +#: src/dirmngr.c:148 src/dirmngr_ldap.c:75 msgid "|N|set LDAP timeout to N seconds" msgstr "" -#: src/dirmngr.c:120 +#: src/dirmngr.c:150 msgid "|URL|use OCSP responder at URL" msgstr "" -#: src/dirmngr.c:121 +#: src/dirmngr.c:151 msgid "|FPR|OCSP response signed by FPR" msgstr "" -#: src/dirmngr.c:124 +#: src/dirmngr.c:154 msgid "|N|do not return more than N items in one query" msgstr "" -#: src/dirmngr.c:153 +#: src/dirmngr.c:156 +msgid "|FILE|listen on socket FILE" +msgstr "" + +#: src/dirmngr.c:211 src/dirmngr-client.c:126 src/dirmngr_ldap.c:134 msgid "Please report bugs to .\n" msgstr "" -#: src/dirmngr.c:157 +#: src/dirmngr.c:215 msgid "Usage: dirmngr [options] (-h for help)" msgstr "" -#: src/dirmngr.c:160 +#: src/dirmngr.c:218 msgid "" "Syntax: dirmngr [options] [command [args]]\n" "LDAP and OCSP access for GnuPG\n" msgstr "" -#: src/dirmngr.c:231 +#: src/dirmngr.c:289 #, c-format msgid "invalid debug-level `%s' given\n" msgstr "" -#: src/dirmngr.c:232 +#: src/dirmngr.c:290 #, c-format msgid "valid debug levels are: %s\n" msgstr "" -#: src/dirmngr.c:269 +#: src/dirmngr.c:328 msgid "usage: dirmngr [options] " msgstr "" -#: src/dirmngr.c:310 src/dirmngr.c:320 +#: src/dirmngr.c:353 +#, c-format +msgid "error spawning ldap wrapper ripper thread: %s\n" +msgstr "" + +#: src/dirmngr.c:471 src/dirmngr.c:481 #, c-format msgid "%s is too old (need %s, have %s)\n" msgstr "" -#: src/dirmngr.c:399 +#: src/dirmngr.c:582 #, c-format msgid "NOTE: no default option file `%s'\n" msgstr "" -#: src/dirmngr.c:404 +#: src/dirmngr.c:587 src/dirmngr.c:1248 #, c-format msgid "option file `%s': %s\n" msgstr "" -#: src/dirmngr.c:412 +#: src/dirmngr.c:595 #, c-format msgid "reading options from `%s'\n" msgstr "" -#: src/dirmngr.c:507 +#: src/dirmngr.c:701 #, c-format msgid "WARNING: running with faked system time %s\n" msgstr "" -#: src/dirmngr.c:586 +#: src/dirmngr.c:777 +msgid "colons are not allowed in the socket name\n" +msgstr "" + +#: src/dirmngr.c:782 +msgid "name of socket too long\n" +msgstr "" + +#: src/dirmngr.c:789 +#, c-format +msgid "can't create socket: %s\n" +msgstr "" + +#: src/dirmngr.c:808 +#, c-format +msgid "error binding socket to `%s': %s\n" +msgstr "" + +#: src/dirmngr.c:817 +#, c-format +msgid "listen() failed: %s\n" +msgstr "" + +#: src/dirmngr.c:823 +#, c-format +msgid "listening on socket `%s'\n" +msgstr "" + +#: src/dirmngr.c:829 +#, c-format +msgid "fork failed: %s\n" +msgstr "" + +#: src/dirmngr.c:847 +msgid "out of core\n" +msgstr "" + +#: src/dirmngr.c:886 +#, c-format +msgid "setsid() failed: %s\n" +msgstr "" + +#: src/dirmngr.c:896 +#, c-format +msgid "chdir to / failed: %s\n" +msgstr "" + +#: src/dirmngr.c:945 #, c-format msgid "fetching CRL from `%s' failed: %s\n" msgstr "" -#: src/dirmngr.c:592 +#: src/dirmngr.c:951 #, c-format msgid "processing CRL from `%s' failed: %s\n" msgstr "" -#: src/dirmngr.c:714 +#: src/dirmngr.c:1095 #, c-format msgid "error opening `%s': %s\n" msgstr "" -#: src/dirmngr.c:731 +#: src/dirmngr.c:1112 #, c-format msgid "%s:%u: line too long - skipped\n" msgstr "" -#: src/dirmngr.c:759 +#: src/dirmngr.c:1140 #, c-format msgid "%s:%u: no hostname given\n" msgstr "" -#: src/dirmngr.c:778 +#: src/dirmngr.c:1159 #, c-format msgid "%s:%u: password given without user\n" msgstr "" -#: src/dirmngr.c:799 +#: src/dirmngr.c:1180 #, c-format msgid "%s:%u: skipping this line\n" msgstr "" -#: src/http.c:467 +#: src/dirmngr.c:1280 +msgid "SIGHUP received - re-reading configuration and flushing caches\n" +msgstr "" + +#: src/dirmngr.c:1294 +msgid "SIGUSR2 received - no action defined\n" +msgstr "" + +#: src/dirmngr.c:1299 +msgid "SIGTERM received - shutting down ...\n" +msgstr "" + +#: src/dirmngr.c:1301 #, c-format -msgid "invalid %s: %s\n" +msgid "SIGTERM received - still %d active connections\n" +msgstr "" + +#: src/dirmngr.c:1306 +msgid "shutdown forced\n" +msgstr "" + +#: src/dirmngr.c:1314 +msgid "SIGINT received - immediate shutdown\n" msgstr "" -#: src/http.c:820 src/http.c:856 +#: src/dirmngr.c:1321 #, c-format -msgid "error resolving `%s': host not found\n" +msgid "signal %d received - no action defined\n" msgstr "" -#: src/http.c:833 src/http.c:864 +#: src/dirmngr.c:1335 #, c-format -msgid "error creating socket: %s\n" +msgid "handler for fd %d started\n" msgstr "" -#: src/http.c:919 +#: src/dirmngr.c:1340 #, c-format -msgid "network write failed: %s\n" +msgid "handler for fd %d terminated\n" msgstr "" -#: src/ldap.c:72 src/ldap.c:183 +#: src/dirmngr.c:1396 #, c-format -msgid "found attribute `%s'\n" +msgid "accept failed: %s - waiting 1s\n" msgstr "" -#: src/ldap.c:95 src/ldap.c:206 +#: src/dirmngr.c:1403 #, c-format -msgid "found attributes `%s' at second try\n" +msgid "error spawning connection handler: %s\n" msgstr "" -#: src/ldap.c:247 -msgid "timeout while waiting for ldap_search result\n" +#: src/http.c:475 +#, c-format +msgid "invalid HTTP proxy (%s): %s\n" msgstr "" -#: src/ldap.c:254 +#: src/http.c:827 src/http.c:863 #, c-format -msgid "ldap_result for an ldap_search failed: %s\n" +msgid "error resolving `%s': host not found\n" msgstr "" -#: src/ldap.c:269 -msgid "ldap_parse_result failed\n" +#: src/http.c:840 src/http.c:871 +#, c-format +msgid "error creating socket: %s\n" msgstr "" -#: src/ldap.c:273 +#: src/http.c:926 #, c-format -msgid "ldap search result is: %s\n" +msgid "network write failed: %s\n" msgstr "" -#: src/ldap.c:281 +#: src/ldap.c:125 #, c-format -msgid "unexpected message type %d returned for ldap_search\n" +msgid "invalid char 0x%02x in host name - not added\n" msgstr "" -#: src/ldap.c:342 +#: src/ldap.c:129 #, c-format -msgid "ldap_init failed for '%s:%d': %s\n" +msgid "adding `%s:%d' to the ldap server list\n" msgstr "" -#: src/ldap.c:352 +#: src/ldap.c:132 src/misc.c:652 #, c-format -msgid "ldap_simple_bind failed for user '%s': %s\n" +msgid "malloc failed: %s\n" msgstr "" -#: src/ldap.c:353 src/ldap.c:761 src/ldap.c:776 -msgid "[none]" +#: src/ldap.c:207 +#, c-format +msgid "error printing log line: %s\n" +msgstr "" + +#: src/ldap.c:253 +#, c-format +msgid "select failed: %s\n" msgstr "" -#: src/ldap.c:368 +#: src/ldap.c:279 #, c-format -msgid "ldap_result for bind failed: %s\n" +msgid "error reading log from ldap wrapper %d: %s\n" msgstr "" -#: src/ldap.c:370 -msgid "timeout while waiting for ldap_bind to complete\n" +#: src/ldap.c:306 +#, c-format +msgid "waiting for ldap wrapper %d failed: %s\n" msgstr "" -#: src/ldap.c:373 src/ldap.c:780 +#: src/ldap.c:311 #, c-format -msgid "unexpected message type %d returned for ldap_bind\n" +msgid "ldap wrapper %d ready: terminated\n" msgstr "" -#: src/ldap.c:389 src/ldap.c:931 +#: src/ldap.c:314 #, c-format -msgid "ldap_search failed: %s\n" +msgid "ldap wrapper %d ready: exit status %d\n" msgstr "" -#: src/ldap.c:454 src/ldap.c:461 src/ldap.c:472 src/ldap.c:747 src/ldap.c:758 -#: src/ldap.c:773 +#: src/ldap.c:327 #, c-format -msgid "%s failed for `" +msgid "ldap wrapper %d stalled - killing\n" msgstr "" -#: src/ldap.c:510 +#: src/ldap.c:380 src/ldap.c:401 #, c-format -msgid "invalid char 0x%02x in host name - not added\n" +msgid "reading from ldap wrapper %d failed: %s\n" msgstr "" -#: src/ldap.c:515 +#: src/ldap.c:546 src/ldap.c:552 #, c-format -msgid "adding `%s:%d' to the ldap server list\n" +msgid "error creating a pipe: %s\n" msgstr "" -#: src/ldap.c:547 -msgid "' is not an LDAP URL\n" +#: src/ldap.c:562 +#, c-format +msgid "error forking process: %s\n" msgstr "" -#: src/ldap.c:555 -msgid "' is an invalid LDAP URL\n" +#: src/ldap.c:610 src/ldap.c:617 src/ldap.c:624 +#, c-format +msgid "dup2 failed in child: %s\n" msgstr "" -#: src/ldap.c:733 +#: src/ldap.c:642 +#, c-format +msgid "error running `%s': %s\n" +msgstr "" + +#: src/ldap.c:654 +#, c-format +msgid "error allocating memory: %s\n" +msgstr "" + +#: src/ldap.c:1101 #, c-format msgid "start_cert_fetch: invalid pattern `%s'\n" msgstr "" -#: src/ldap.c:919 +#: src/ldap.c:1239 msgid "ldap_search hit the size limit of the server\n" msgstr "" -#: src/misc.c:426 +#: src/misc.c:428 msgid "invalid canonical S-expression found\n" msgstr "" -#: src/misc.c:450 +#: src/misc.c:452 #, c-format msgid "gcry_md_open failed: %s\n" msgstr "" -#: src/misc.c:455 +#: src/misc.c:457 #, c-format msgid "oops: ksba_cert_hash failed: %s\n" msgstr "" -#: src/ocsp.c:65 +#: src/misc.c:491 +msgid "[none]" +msgstr "" + +#: src/misc.c:668 +msgid "bad URL encoding detected\n" +msgstr "" + +#: src/ocsp.c:67 #, c-format msgid "error reading from responder: %s\n" msgstr "" -#: src/ocsp.c:83 +#: src/ocsp.c:85 #, c-format msgid "response from server too large; limit is %d bytes\n" msgstr "" #: src/ocsp.c:120 +msgid "OCSP request not possible due to disabled HTTP\n" +msgstr "" + +#: src/ocsp.c:127 #, c-format msgid "error setting OCSP target: %s\n" msgstr "" -#: src/ocsp.c:138 +#: src/ocsp.c:145 #, c-format msgid "error building OCSP request: %s\n" msgstr "" -#: src/ocsp.c:145 +#: src/ocsp.c:154 #, c-format msgid "error connecting to `%s': %s\n" msgstr "" -#: src/ocsp.c:169 src/ocsp.c:185 +#: src/ocsp.c:178 src/ocsp.c:194 #, c-format msgid "error reading HTTP response for `%s': %s\n" msgstr "" -#: src/ocsp.c:173 +#: src/ocsp.c:182 #, c-format msgid "error accessing `%s': http status %u\n" msgstr "" -#: src/ocsp.c:194 +#: src/ocsp.c:203 #, c-format msgid "error parsing OCSP response for `%s': %s\n" msgstr "" -#: src/ocsp.c:216 src/ocsp.c:226 +#: src/ocsp.c:225 src/ocsp.c:235 #, c-format msgid "OCSP responder at `%s' status: %s\n" msgstr "" -#: src/ocsp.c:221 +#: src/ocsp.c:230 #, c-format msgid "hashing the OCSP response for `%s' failed: %s\n" msgstr "" -#: src/ocsp.c:317 +#: src/ocsp.c:335 msgid "only SHA-1 is supported for OCSP responses\n" msgstr "" -#: src/ocsp.c:367 +#: src/ocsp.c:385 msgid "no suitable certificate found to verify the OCSP response\n" msgstr "" -#: src/ocsp.c:396 +#: src/ocsp.c:421 src/validate.c:419 #, c-format -msgid "failed to allocate OCSP context: %s\n" +msgid "issuer certificate not found: %s\n" msgstr "" -#: src/ocsp.c:406 +#: src/ocsp.c:431 msgid "caller did not return the target certificate\n" msgstr "" -#: src/ocsp.c:413 +#: src/ocsp.c:438 msgid "caller did not return the issuing certificate\n" msgstr "" -#: src/ocsp.c:445 +#: src/ocsp.c:448 +#, c-format +msgid "failed to allocate OCSP context: %s\n" +msgstr "" + +#: src/ocsp.c:482 #, c-format msgid "can't get authorityInfoAccess: %s\n" msgstr "" -#: src/ocsp.c:452 +#: src/ocsp.c:489 msgid "no default OCSP responder defined\n" msgstr "" -#: src/ocsp.c:458 +#: src/ocsp.c:495 msgid "no default OCSP signer defined\n" msgstr "" -#: src/ocsp.c:465 +#: src/ocsp.c:502 #, c-format msgid "using default OCSP responder `%s'\n" msgstr "" -#: src/ocsp.c:470 +#: src/ocsp.c:507 #, c-format msgid "using OCSP responder `%s'\n" msgstr "" -#: src/ocsp.c:477 +#: src/ocsp.c:514 #, c-format msgid "failed to establish a hashing context for OCSP: %s\n" msgstr "" -#: src/ocsp.c:507 +#: src/ocsp.c:544 #, c-format msgid "error getting OCSP status for target certificate: %s\n" msgstr "" -#: src/ocsp.c:514 +#: src/ocsp.c:551 #, c-format msgid "certificate status is: %s (this=%s next=%s)\n" msgstr "" -#: src/ocsp.c:515 +#: src/ocsp.c:552 msgid "good" msgstr "" -#: src/ocsp.c:516 +#: src/ocsp.c:553 msgid "revoked" msgstr "" -#: src/ocsp.c:517 +#: src/ocsp.c:554 msgid "unknown" msgstr "" -#: src/ocsp.c:518 +#: src/ocsp.c:555 msgid "none" msgstr "" -#: src/ocsp.c:521 +#: src/ocsp.c:558 #, c-format msgid "certificate has been revoked at: %s due to: %s\n" msgstr "" -#: src/ocsp.c:554 +#: src/ocsp.c:591 msgid "OCSP responder returned an too old status\n" msgstr "" -#: src/ocsp.c:564 +#: src/ocsp.c:601 msgid "OCSP responder returned a non-current status\n" msgstr "" -#: src/server.c:183 +#: src/server.c:131 src/server.c:438 src/server.c:520 src/server.c:771 +#: src/server.c:824 #, c-format msgid "assuan_inquire failed: %s\n" msgstr "" -#: src/server.c:318 +#: src/server.c:301 +msgid "serialno missing in cert ID" +msgstr "" + +#: src/server.c:352 src/server.c:468 src/server.c:547 src/server.c:687 +#: src/server.c:715 src/server.c:739 src/server.c:792 src/server.c:845 #, c-format -msgid "crl_fetch via DP failed: %s\n" +msgid "command %s failed: %s\n" msgstr "" -#: src/server.c:326 +#: src/server.c:615 #, c-format -msgid "crl_cache_insert via DP failed: %s\n" +msgid "start_cert_fetch failed: %s\n" msgstr "" -#: src/server.c:349 +#: src/server.c:642 #, c-format -msgid "crl_fetch via issuer failed: %s\n" +msgid "fetch_next_cert failed: %s\n" msgstr "" -#: src/server.c:358 +#: src/server.c:661 #, c-format -msgid "crl_cache_insert via issuer failed: %s\n" +msgid "error sending data: %s\n" msgstr "" -#: src/server.c:439 -msgid "serialno missing in cert ID" +#: src/server.c:670 +#, c-format +msgid "max_replies %d exceeded\n" msgstr "" -#: src/server.c:490 src/server.c:628 src/server.c:656 src/server.c:681 +#: src/server.c:735 +msgid "no data stream" +msgstr "" + +#: src/server.c:898 #, c-format -msgid "command %s failed: %s\n" +msgid "can't allocate control structure: %s\n" msgstr "" -#: src/server.c:557 +#: src/server.c:921 #, c-format -msgid "start_cert_fetch failed: %s\n" +msgid "failed to initialize the server: %s\n" msgstr "" -#: src/server.c:583 +#: src/server.c:929 #, c-format -msgid "fetch_next_cert failed: %s\n" +msgid "failed to the register commands with Assuan: %s\n" msgstr "" -#: src/server.c:602 +#: src/server.c:949 #, c-format -msgid "error sending data: %s\n" +msgid "Assuan accept problem: %s\n" msgstr "" -#: src/server.c:611 +#: src/server.c:956 #, c-format -msgid "max_replies %d exceeded\n" +msgid "Assuan processing failed: %s\n" msgstr "" -#: src/server.c:677 -msgid "no data stream" +#: src/validate.c:92 +#, c-format +msgid "critical certificate extension %s is not supported" msgstr "" -#: src/server.c:735 +#: src/validate.c:152 +msgid "note: non-critical certificate policy not allowed" +msgstr "" + +#: src/validate.c:157 +msgid "certificate policy not allowed" +msgstr "" + +#: src/validate.c:177 +msgid "issuer certificate is not marked as a CA" +msgstr "" + +#: src/validate.c:302 #, c-format -msgid "failed to initialize the server: %s\n" +msgid "certificate with invalid validity: %s" +msgstr "" + +#: src/validate.c:320 +msgid "certificate not yet valid" msgstr "" -#: src/server.c:743 +#: src/validate.c:331 +msgid "certificate has expired" +msgstr "" + +#: src/validate.c:360 +msgid "selfsigned certificate has a BAD signature" +msgstr "" + +#: src/validate.c:378 +msgid "root certificate is not marked trusted" +msgstr "" + +#: src/validate.c:380 #, c-format -msgid "failed to the register commands with Assuan: %s\n" +msgid "fingerprint=%s\n" msgstr "" -#: src/server.c:769 +#: src/validate.c:386 #, c-format -msgid "Assuan accept problem: %s\n" +msgid "checking trustworthiness of root certificate failed: %s\n" +msgstr "" + +#: src/validate.c:401 +msgid "certificate chain too long\n" +msgstr "" + +#: src/validate.c:413 +msgid "issuer certificate not found" +msgstr "" + +#: src/validate.c:439 +msgid "certificate has a BAD signature" msgstr "" -#: src/server.c:776 +#: src/validate.c:463 +msgid "found another possible matching CA certificate - trying again" +msgstr "" + +#: src/validate.c:488 #, c-format -msgid "Assuan processing failed: %s\n" +msgid "certificate chain longer than allowed by CA (%d)" +msgstr "" + +#: src/validate.c:725 +msgid "DSA requires the use of a 160 bit hash algorithm\n" +msgstr "" + +#: src/validate.c:832 +msgid "no key usage specified - assuming all usages\n" +msgstr "" + +#: src/validate.c:842 +#, c-format +msgid "error getting key usage information: %s\n" +msgstr "" + +#: src/validate.c:852 +msgid "certificate should have not been used for certification\n" +msgstr "" + +#: src/validate.c:864 +msgid "certificate should have not been used for OCSP response signing\n" +msgstr "" + +#: src/validate.c:875 +msgid "certificate should have not been used for encryption\n" +msgstr "" + +#: src/validate.c:877 +msgid "certificate should have not been used for signing\n" +msgstr "" + +#: src/validate.c:878 +msgid "certificate is not usable for encryption\n" +msgstr "" + +#: src/validate.c:879 +msgid "certificate is not usable for signing\n" +msgstr "" + +#: src/dirmngr-client.c:66 +msgid "use OCSP instead of CRLs" +msgstr "" + +#: src/dirmngr-client.c:67 +msgid "check whether a dirmngr is running" +msgstr "" + +#: src/dirmngr-client.c:68 +msgid "add a certificate to the cache" +msgstr "" + +#: src/dirmngr-client.c:69 +msgid "validate a certificate" +msgstr "" + +#: src/dirmngr-client.c:70 +msgid "lookup a certificate" +msgstr "" + +#: src/dirmngr-client.c:130 +msgid "Usage: dirmngr-client [options] [certfile|pattern] (-h for help)\n" +msgstr "" + +#: src/dirmngr-client.c:134 +msgid "" +"Syntax: dirmngr-client [options] [certfile|pattern]\n" +"Test an X.509 certificate against a CRL or do an OCSP check\n" +"The process returns 0 if the certificate is valid, 1 if it is\n" +"not valid and other error codes for general failures\n" +msgstr "" + +#: src/dirmngr-client.c:220 +#, c-format +msgid "error reading certificate from stdin: %s\n" +msgstr "" + +#: src/dirmngr-client.c:227 +#, c-format +msgid "error reading certificate from `%s': %s\n" +msgstr "" + +#: src/dirmngr-client.c:241 +msgid "certificate too large to make any sense\n" +msgstr "" + +#: src/dirmngr-client.c:260 +#, c-format +msgid "lookup failed: %s\n" +msgstr "" + +#: src/dirmngr-client.c:287 +msgid "a dirmngr daemon is up and running\n" +msgstr "" + +#: src/dirmngr-client.c:309 +#, c-format +msgid "validation of certificate failed: %s\n" +msgstr "" + +#: src/dirmngr-client.c:316 +msgid "certificate is valid\n" +msgstr "" + +#: src/dirmngr-client.c:322 +msgid "certificate has been revoked\n" +msgstr "" + +#: src/dirmngr-client.c:327 +#, c-format +msgid "certificate check failed: %s\n" +msgstr "" + +#: src/dirmngr-client.c:338 +#, c-format +msgid "got status: `%s'\n" +msgstr "" + +#: src/dirmngr-client.c:353 +#, c-format +msgid "error writing base64 encoding: %s\n" +msgstr "" + +#: src/dirmngr-client.c:385 +msgid "apparently no running dirmngr\n" +msgstr "" + +#: src/dirmngr-client.c:390 +msgid "no running dirmngr - starting one\n" +msgstr "" + +#: src/dirmngr-client.c:423 +msgid "malformed DIRMNGR_INFO environment variable\n" +msgstr "" + +#: src/dirmngr-client.c:438 +#, c-format +msgid "dirmngr protocol version %d is not supported\n" +msgstr "" + +#: src/dirmngr-client.c:454 +msgid "can't connect to the dirmngr - trying fall back\n" +msgstr "" + +#: src/dirmngr-client.c:462 +#, c-format +msgid "can't connect to the dirmngr: %s\n" +msgstr "" + +#: src/dirmngr-client.c:545 +#, c-format +msgid "unsupported inquiry `%s'\n" +msgstr "" + +#: src/dirmngr-client.c:626 +#, c-format +msgid "looking up `%s'\n" +msgstr "" + +#: src/no-libgcrypt.c:39 +#, c-format +msgid "error allocating enough memory: %s\n" +msgstr "" + +#: src/dirmngr_ldap.c:76 +msgid "return all values in a record oriented format" +msgstr "" + +#: src/dirmngr_ldap.c:79 +msgid "|NAME|ignore host part and connect through NAME" +msgstr "" + +#: src/dirmngr_ldap.c:80 +msgid "|NAME|connect to host NAME" +msgstr "" + +#: src/dirmngr_ldap.c:81 +msgid "|N|connect to port N" +msgstr "" + +#: src/dirmngr_ldap.c:82 +msgid "|NAME|use user NAME for authentication" +msgstr "" + +#: src/dirmngr_ldap.c:83 +msgid "|PASS|use password PASS for authentication" +msgstr "" + +#: src/dirmngr_ldap.c:85 +msgid "take password from $DIRMNGR_LDAP_PASS" +msgstr "" + +#: src/dirmngr_ldap.c:86 +msgid "|STRING|query DN STRING" +msgstr "" + +#: src/dirmngr_ldap.c:87 +msgid "|STRING|use STRING as filter expression" +msgstr "" + +#: src/dirmngr_ldap.c:88 +msgid "|STRING|return the attribute STRING" +msgstr "" + +#: src/dirmngr_ldap.c:138 +msgid "Usage: dirmngr_ldap [options] [URL] (-h for help)\n" +msgstr "" + +#: src/dirmngr_ldap.c:141 +msgid "" +"Syntax: dirmngr_ldap [options] [URL]\n" +"Internal LDAP helper for Dirmngr.\n" +"Interface and options may change without notice.\n" +msgstr "" + +#: src/dirmngr_ldap.c:230 +#, c-format +msgid "invalid port number %d\n" +msgstr "" + +#: src/dirmngr_ldap.c:261 +#, c-format +msgid "scanning result for attribute `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:268 src/dirmngr_ldap.c:328 src/dirmngr_ldap.c:352 +#: src/dirmngr_ldap.c:363 src/dirmngr_ldap.c:473 +#, c-format +msgid "error writing to stdout: %s\n" +msgstr "" + +#: src/dirmngr_ldap.c:282 +#, c-format +msgid " available attribute `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:307 +#, c-format +msgid "attribute `%s' not found\n" +msgstr "" + +#: src/dirmngr_ldap.c:313 +#, c-format +msgid "found attribute `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:410 +#, c-format +msgid "processing url `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:412 +#, c-format +msgid " user `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:414 +#, c-format +msgid " pass `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:416 +#, c-format +msgid " host `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:417 +#, c-format +msgid " port %d\n" +msgstr "" + +#: src/dirmngr_ldap.c:419 +#, c-format +msgid " DN `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:421 +#, c-format +msgid " filter `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:426 src/dirmngr_ldap.c:429 +#, c-format +msgid " attr `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:435 +#, c-format +msgid "no host name in `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:440 +#, c-format +msgid "no attribute given for query `%s'\n" +msgstr "" + +#: src/dirmngr_ldap.c:446 +msgid "WARNING: using first attribute only\n" +msgstr "" + +#: src/dirmngr_ldap.c:452 +#, c-format +msgid "LDAP init to `%s:%d' failed: %s\n" +msgstr "" + +#: src/dirmngr_ldap.c:458 +#, c-format +msgid "binding to `%s:%d' failed: %s\n" +msgstr "" + +#: src/dirmngr_ldap.c:480 +#, c-format +msgid "searching `%s' failed: %s\n" +msgstr "" + +#: src/dirmngr_ldap.c:508 +#, c-format +msgid "`%s' is not an LDAP URL\n" +msgstr "" + +#: src/dirmngr_ldap.c:514 +#, c-format +msgid "`%s' is an invalid LDAP URL\n" msgstr "" Index: dirmngr/src/ChangeLog diff -u dirmngr/src/ChangeLog:1.26 dirmngr/src/ChangeLog:1.27 --- dirmngr/src/ChangeLog:1.26 Tue Nov 23 14:20:44 2004 +++ dirmngr/src/ChangeLog Wed Nov 24 13:25:53 2004 @@ -1,5 +1,14 @@ +2004-11-24 Werner Koch + + * dirmngr.c: New options --ignore-http-dp and --ignore-ldap-dp. + * crlcache.c (crl_cache_reload_crl): Implement them. + 2004-11-23 Werner Koch + * ldap.c (ldap_wrapper_thread, reader_callback, ldap_wrapper): + Keep a timestamp and terminate the wrapper after some time of + inactivity. + * dirmngr-client.c (do_lookup): New. (main): New option --lookup. (data_cb): New. @@ -19,7 +28,6 @@ (url_fetch_ldap): Call it here and try all configured servers in case of a a failed lookup. (fetch_next_cert_ldap): Detect the truncation error flag. - * misc.c (host_and_port_from_url, remove_percent_escapes): New. 2004-11-22 Werner Koch Index: dirmngr/src/certcache.c diff -u dirmngr/src/certcache.c:1.6 dirmngr/src/certcache.c:1.7 --- dirmngr/src/certcache.c:1.6 Tue Nov 23 14:20:44 2004 +++ dirmngr/src/certcache.c Wed Nov 24 13:25:53 2004 @@ -652,7 +652,7 @@ issuer_dn = ksba_cert_get_issuer (cert, 0); if (!issuer_dn) { - log_error (_("no issuer found in certificate")); + log_error (_("no issuer found in certificate\n")); err = gpg_error (GPG_ERR_BAD_CERT); goto leave; } Index: dirmngr/src/crlcache.c diff -u dirmngr/src/crlcache.c:1.49 dirmngr/src/crlcache.c:1.50 --- dirmngr/src/crlcache.c:1.49 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/crlcache.c Wed Nov 24 13:25:53 2004 @@ -2190,6 +2190,25 @@ issuername_uri = ksba_name_get_uri (issuername, 0); ksba_name_release (distpoint); distpoint = NULL; ksba_name_release (issuername); issuername = NULL; + + if (!distpoint_uri) + continue; + + if (!strncmp (distpoint_uri, "ldap:", 5) + || !strncmp (distpoint_uri, "ldaps:", 6)) + { + if (opt.ignore_ldap_dp) + continue; + } + else if (!strncmp (distpoint_uri, "http:", 5) + || !strncmp (distpoint_uri, "https:", 6)) + { + if (opt.ignore_http_dp) + continue; + } + else + continue; /* Skip unknown schemes. */ + any_dist_point = 1; err = crl_fetch (ctrl, distpoint_uri, &reader); Index: dirmngr/src/dirmngr-client.c diff -u dirmngr/src/dirmngr-client.c:1.4 dirmngr/src/dirmngr-client.c:1.5 --- dirmngr/src/dirmngr-client.c:1.4 Tue Nov 23 14:20:44 2004 +++ dirmngr/src/dirmngr-client.c Wed Nov 24 13:25:53 2004 @@ -55,7 +55,6 @@ oCacheCert, oValidate, oLookup, - oUseDaemon, oDummy }; @@ -64,7 +63,6 @@ static ARGPARSE_OPTS opts[] = { { oVerbose, "verbose", 0, N_("verbose") }, { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, - { oUseDaemon,"use-daemon",0, N_("force use of the daemon")}, { oOCSP, "ocsp", 0, N_("use OCSP instead of CRLs") }, { oPing, "ping", 0, N_("check whether a dirmngr is running")}, { oCacheCert,"cache-cert",0, N_("add a certificate to the cache")}, Index: dirmngr/src/dirmngr.c diff -u dirmngr/src/dirmngr.c:1.45 dirmngr/src/dirmngr.c:1.46 --- dirmngr/src/dirmngr.c:1.45 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/dirmngr.c Wed Nov 24 13:25:53 2004 @@ -78,6 +78,8 @@ oBatch, oDisableHTTP, oDisableLDAP, + oIgnoreLDAPDP, + oIgnoreHTTPDP, oHonorHTTPProxy, oHTTPProxy, oLDAPProxy, @@ -127,6 +129,10 @@ { oAllowOCSP, "allow-ocsp",0,N_("allow sending OCSP requests")}, { oDisableHTTP, "disable-http", 0, N_("inhibit the use of HTTP")}, { oDisableLDAP, "disable-ldap", 0, N_("inhibit the use of LDAP")}, + { oIgnoreHTTPDP,"ignore-http-dp",0, + N_("ignore HTTP CRL distribution points")}, + { oIgnoreLDAPDP,"ignore-ldap-dp",0, + N_("ignore LDAP CRL distribution points")}, { oHTTPProxy, "http-proxy", 2, N_("|URL|redirect all HTTP requests to URL")}, { oLDAPProxy, "ldap-proxy", 2, @@ -372,6 +378,8 @@ opt.http_proxy = NULL; opt.ldap_proxy = NULL; opt.only_ldap_proxy = 0; + opt.ignore_http_dp = 0; + opt.ignore_ldap_dp = 0; return 1; } @@ -408,6 +416,8 @@ case oHTTPProxy: opt.http_proxy = pargs->r.ret_str; break; case oLDAPProxy: opt.ldap_proxy = pargs->r.ret_str; break; case oOnlyLDAPProxy: opt.only_ldap_proxy = 1; break; + case oIgnoreHTTPDP: opt.ignore_http_dp = 1; break; + case oIgnoreLDAPDP: opt.ignore_ldap_dp = 1; break; default: return 0; /* Not handled. */ @@ -1012,6 +1022,8 @@ printf ("http-proxy:%lu:\n", GC_OPT_FLAG_NONE); printf ("ldap-proxy:%lu:\n", GC_OPT_FLAG_NONE); printf ("only-ldap-proxy:%lu:\n", GC_OPT_FLAG_NONE); + printf ("ignore-ldap-dp:%lu:\n", GC_OPT_FLAG_NONE); + printf ("ignore-http-dp:%lu:\n", GC_OPT_FLAG_NONE); } cleanup (); Index: dirmngr/src/dirmngr.h diff -u dirmngr/src/dirmngr.h:1.21 dirmngr/src/dirmngr.h:1.22 --- dirmngr/src/dirmngr.h:1.21 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/dirmngr.h Wed Nov 24 13:25:53 2004 @@ -87,6 +87,8 @@ const char *http_proxy; /* Use given HTTP proxy. */ const char *ldap_proxy; /* Use given LDAP proxy. */ int only_ldap_proxy; /* Only use the LDAP proxy; no fallback. */ + int ignore_http_dp; /* Ignore HTTP CRL distribution points. */ + int ignore_ldap_dp; /* Ignore LDAP CRL distribution points. */ int allow_ocsp; /* Allow using OCSP. */ Index: dirmngr/src/dirmngr_ldap.c diff -u dirmngr/src/dirmngr_ldap.c:1.4 dirmngr/src/dirmngr_ldap.c:1.5 --- dirmngr/src/dirmngr_ldap.c:1.4 Tue Nov 23 14:20:44 2004 +++ dirmngr/src/dirmngr_ldap.c Wed Nov 24 13:25:53 2004 @@ -131,7 +131,7 @@ case 14: p = "Copyright (C) 2004 g10 Code GmbH"; break; case 17: p = PRINTABLE_OS_NAME; break; case 19: p = - _("Please report bugs to " PACKAGE_BUGREPORT ".\n"); + _("Please report bugs to .\n"); break; case 1: case 40: p = @@ -484,7 +484,6 @@ return -1; } - rc = print_ldap_entries (ld, msg, opt.multi? NULL:attr); ldap_msgfree (msg); Index: dirmngr/src/ldap.c diff -u dirmngr/src/ldap.c:1.37 dirmngr/src/ldap.c:1.38 --- dirmngr/src/ldap.c:1.37 Tue Nov 23 14:20:44 2004 +++ dirmngr/src/ldap.c Wed Nov 24 13:25:53 2004 @@ -43,6 +43,7 @@ #define MAX_OPEN_FDS 20 #endif +#define INACTIVITY_TIMEOUT (60*5) /* seconds */ #define UNENCODED_URL_CHARS "abcdefghijklmnopqrstuvwxyz" \ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ @@ -80,6 +81,7 @@ 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. */ }; @@ -226,6 +228,7 @@ struct timeval tv; struct wrapper_context_s *ctx, *ctx_prev; char line[256]; + time_t current_time; for (;;) { @@ -251,6 +254,11 @@ pth_sleep (10); continue; } + + current_time = time (NULL); + if (current_time > INACTIVITY_TIMEOUT) + current_time -= INACTIVITY_TIMEOUT; + /* Note that there is no need to lock the list because we always add entries at the head and thus traversing the list will even work if we have a context switch in waitpid (which should @@ -281,6 +289,8 @@ { line[n] = 0; print_log_line (ctx, line); + if (ctx->stamp != (time_t)(-1)) + ctx->stamp = time (NULL); } } @@ -309,6 +319,14 @@ } /* Check whether we should terminate the process. */ + if (ctx->pid != (pid_t)(-1) + && ctx->stamp != (time_t)(-1) && ctx->stamp < current_time) + { + if (!kill (ctx->pid, SIGTERM)) + ctx->stamp = (time_t)(-1); + log_info (_("ldap wrapper %d stalled - killing\n"), + (int)ctx->pid); + } } /* Use a separate loop to check whether ready marked wrappers @@ -459,6 +477,8 @@ buffer += n; if (evt) pth_event_free (evt, PTH_FREE_THIS); + if (n > 0 && ctx->stamp != (time_t)(-1)) + ctx->stamp = time (NULL); } *nread = count - nleft; @@ -582,7 +602,7 @@ fd = open ("/dev/null", O_RDONLY); if (fd == -1) { - log_error (_("can't open `/dev/null': %s\n"), strerror (errno)); + log_error (_("can't open `%s': %s\n"), "/dev/null",strerror (errno)); _exit (4); } if (fd != STDIN_FILENO && dup2 (fd, STDIN_FILENO) == -1) @@ -643,6 +663,7 @@ ctx->log_fd = rp2[0]; ctx->ctrl = ctrl; ctrl->refcount++; + ctx->stamp = time (NULL); err = ksba_reader_new (reader); if (!err) Index: dirmngr/src/validate.c diff -u dirmngr/src/validate.c:1.4 dirmngr/src/validate.c:1.5 --- dirmngr/src/validate.c:1.4 Mon Nov 22 22:30:50 2004 +++ dirmngr/src/validate.c Wed Nov 24 13:25:53 2004 @@ -285,7 +285,7 @@ if (!issuer) { - log_error (_("no issuer found in certificate")); + log_error (_("no issuer found in certificate\n")); err = gpg_error (GPG_ERR_BAD_CERT); goto leave; } @@ -416,7 +416,7 @@ log_printf ("\n"); } else - log_error (_("failed to find issuer certificate: %s\n"), + log_error (_("issuer certificate not found: %s\n"), gpg_strerror (err)); /* Use a better understandable error code. */ err = gpg_error (GPG_ERR_MISSING_CERT);