From fbe4ac37f6d3e7870e26caffb0d21c3c77198297 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 23 May 2006 16:19:43 +0000 Subject: [PATCH] g10/ does build again. --- ChangeLog | 9 ++ TODO | 7 ++ common/ChangeLog | 27 +++++ common/Makefile.am | 4 +- common/gettime.c | 28 ++++- common/iobuf.h | 2 + common/miscellaneous.c | 24 +++- common/pka.c | 252 ++++++++++++++++++++++++++++++++++++++++ common/pka.h | 27 +++++ common/ttyio.c | 49 +++++++- common/ttyio.h | 16 +++ common/util.h | 3 + common/yesno.c | 142 ++++++++++++++-------- configure.ac | 57 ++++++++- g10/ChangeLog | 40 +++++++ g10/Makefile.am | 2 +- g10/armor.c | 2 +- g10/call-agent.c | 24 +++- g10/call-agent.h | 17 ++- g10/card-util.c | 18 ++- g10/gpg.c | 27 +++-- g10/gpgv.c | 20 ---- g10/import.c | 6 +- g10/keydb.h | 1 + g10/keygen.c | 7 +- g10/keyserver.c | 9 +- g10/main.h | 1 + g10/mainproc.c | 1 + g10/misc.c | 19 ++- g10/options.h | 1 - g10/passphrase.c | 4 +- g10/pkclist.c | 8 +- g10/plaintext.c | 18 +-- g10/pubkey-enc.c | 6 +- g10/sign.c | 2 +- g10/skclist.c | 13 +++ jnlib/ChangeLog | 19 +++ jnlib/dotlock.c | 83 +++++++++---- jnlib/dotlock.h | 1 + jnlib/libjnlib-config.h | 26 ++--- jnlib/stringhelp.c | 99 +++++++++++++--- jnlib/stringhelp.h | 6 + jnlib/strlist.c | 24 ++-- jnlib/strlist.h | 4 +- scd/app-p15.c | 10 ++ sm/ChangeLog | 10 ++ sm/Makefile.am | 2 +- sm/keydb.c | 27 ----- sm/keylist.c | 4 +- tools/ChangeLog | 8 ++ tools/gpgconf-comp.c | 28 ----- tools/gpgparsemail.c | 6 +- 52 files changed, 989 insertions(+), 261 deletions(-) create mode 100644 common/pka.c create mode 100644 common/pka.h diff --git a/ChangeLog b/ChangeLog index 6e5228817..711cd4751 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2006-05-23 Werner Koch + + * configure.ac (ZLIBS): New for zlib link commands. Add bzip2 + support. + +2006-05-22 Werner Koch + + * configure.ac (EXEEXT): New. + 2006-04-18 Werner Koch * configure.ac (PK_UID_CACHE_SIZE): New. diff --git a/TODO b/TODO index af3a42605..7958ed18e 100644 --- a/TODO +++ b/TODO @@ -110,4 +110,11 @@ might want to have an agent context for each service request We can't do that right now because it is only defined by newer versions of libgcrypt. Changes this if we require libgcrypt 1.3 anyway. +** skclist.c:random_is_faked + Remove the whole stuff? +* common/ +** ttyio + Add completion support. +** yesno + Update to gpg 1.4.3 version \ No newline at end of file diff --git a/common/ChangeLog b/common/ChangeLog index f1b11fc57..36a733a7f 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,30 @@ +2006-05-23 Werner Koch + + * gettime.c (isotimestamp): New. + + * ttyio.c (tty_get_ttyname): Posixly correct usage of ctermid. + + * dns-cert.c: New. Taken from 1.4.3's util/cert.c. + * dns-cert.h: New. + +2006-05-22 Werner Koch + + * pka.c: New. Taked from 1.4.3. + * pka.h: New. + * Makefile.am: Added pka. + +2006-05-19 Werner Koch + + * yesno.c (answer_is_yes_no_default, answer_is_yes_no_quit): + Updated from 1.4.3. + (answer_is_okay_cancel): new. From 1.4.3. + + * miscellaneous.c (match_multistr): New. Taken from 1.4.3. + + * ttyio.c (tty_enable_completion, tty_disable_completion): New + dummy functions. + * ttyio.h: Add prototypes and stubs. + 2006-04-19 Werner Koch * iobuf.c (iobuf_get_fd): New. Taken from 1.4.3. diff --git a/common/Makefile.am b/common/Makefile.am index 3056be6bc..34819e93f 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -49,7 +49,9 @@ libcommon_a_SOURCES = \ w32reg.c \ signal.c \ dynload.h \ - estream.c estream.h + estream.c estream.h \ + dns-cert.c dns-cert.h \ + pka.c pka.h libsimple_pwquery_a_SOURCES = \ diff --git a/common/gettime.c b/common/gettime.c index 93e4ba113..ecdc7df95 100644 --- a/common/gettime.c +++ b/common/gettime.c @@ -201,7 +201,7 @@ strtimevalue( u32 value ) } -/**************** +/* * Note: this function returns GMT */ const char * @@ -222,6 +222,32 @@ strtimestamp( u32 stamp ) return buffer; } + +/* + * Note: this function returns GMT + */ +const char * +isotimestamp (u32 stamp) +{ + static char buffer[25+5]; + struct tm *tp; + time_t atime = stamp; + + if (atime < 0) + { + strcpy (buffer, "????" "-??" "-??" " " "??" ":" "??" ":" "??"); + } + else + { + tp = gmtime ( &atime ); + sprintf (buffer,"%04d-%02d-%02d %02d:%02d:%02d", + 1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec); + } + return buffer; +} + + /**************** * Note: this function returns local time */ diff --git a/common/iobuf.h b/common/iobuf.h index 431d573a1..3b8f4b572 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -145,6 +145,8 @@ void iobuf_set_partial_block_mode (iobuf_t a, size_t len); int iobuf_translate_file_handle (int fd, int for_write); +void iobuf_skip_rest (iobuf_t a, unsigned long n, int partial); + /* get a byte form the iobuf; must check for eof prior to this function * this function returns values in the range 0 .. 255 or -1 to indicate EOF diff --git a/common/miscellaneous.c b/common/miscellaneous.c index 14d6f020d..e9f8ed27f 100644 --- a/common/miscellaneous.c +++ b/common/miscellaneous.c @@ -1,5 +1,5 @@ /* miscellaneous.c - Stuff not fitting elsewhere - * Copyright (C) 2003 Free Software Foundation, Inc. + * Copyright (C) 2003, 2006 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -47,6 +47,7 @@ print_fname_stdin (const char *s) return s; } +/* fixme: Globally replace it by print_sanitized_buffer. */ void print_string( FILE *fp, const byte *p, size_t n, int delim ) { @@ -125,4 +126,25 @@ leave: } +/* Try match against each substring of multistr, delimited by | */ +int +match_multistr (const char *multistr,const char *match) +{ + do + { + size_t seglen = strcspn (multistr,"|"); + if (!seglen) + break; + /* Using the localized strncasecmp! */ + if (strncasecmp(multistr,match,seglen)==0) + return 1; + multistr += seglen; + if (*multistr == '|') + multistr++; + } + while (*multistr); + + return 0; +} + diff --git a/common/pka.c b/common/pka.c new file mode 100644 index 000000000..3d442d16a --- /dev/null +++ b/common/pka.c @@ -0,0 +1,252 @@ +/* pka.c - DNS Public Key Association RR access + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include + +#include +#include +#include + +#ifdef USE_DNS_PKA +#include +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif +#endif /* USE_DNS_PKA */ + +#include "util.h" +#include "pka.h" + +#ifdef USE_DNS_PKA +/* Parse the TXT resource record. Format is: + + v=pka1;fpr=a4d94e92b0986ab5ee9dcd755de249965b0358a2;uri=string + + For simplicity white spaces are not allowed. Because we expect to + use a new RRTYPE for this in the future we define the TXT really + strict for simplicity: No white spaces, case sensitivity of the + names, order must be as given above. Only URI is optional. + + This function modifies BUFFER. On success 0 is returned, the 20 + byte fingerprint stored at FPR and BUFFER contains the URI or an + empty string. +*/ +static int +parse_txt_record (char *buffer, unsigned char *fpr) +{ + char *p, *pend; + int i; + + p = buffer; + pend = strchr (p, ';'); + if (!pend) + return -1; + *pend++ = 0; + if (strcmp (p, "v=pka1")) + return -1; /* Wrong or missing version. */ + + p = pend; + pend = strchr (p, ';'); + if (pend) + *pend++ = 0; + if (strncmp (p, "fpr=", 4)) + return -1; /* Missing fingerprint part. */ + p += 4; + for (i=0; i < 20 && hexdigitp (p) && hexdigitp (p+1); i++, p += 2) + fpr[i] = xtoi_2 (p); + if (i != 20) + return -1; /* Fingerprint consists not of exactly 40 hexbytes. */ + + p = pend; + if (!p || !*p) + { + *buffer = 0; + return 0; /* Success (no URI given). */ + } + if (strncmp (p, "uri=", 4)) + return -1; /* Unknown part. */ + p += 4; + /* There is an URI, copy it to the start of the buffer. */ + while (*p) + *buffer++ = *p++; + *buffer = 0; + return 0; +} + + +/* For the given email ADDRESS lookup the PKA information in the DNS. + + On success the 20 byte SHA-1 fingerprint is stored at FPR and the + URI will be returned in an allocated buffer. Note that the URI + might be an zero length string as this information is optiobnal. + Caller must xfree the returned string. + + On error NULL is returned and the 20 bytes at FPR are not + defined. */ +char * +get_pka_info (const char *address, unsigned char *fpr) +{ + unsigned char answer[PACKETSZ]; + int anslen; + int qdcount, ancount, nscount, arcount; + int rc; + unsigned char *p, *pend; + const char *domain; + char *name; + + + domain = strrchr (address, '@'); + if (!domain || domain == address || !domain[1]) + return NULL; /* invalid mail address given. */ + + name = malloc (strlen (address) + 5 + 1); + memcpy (name, address, domain - address); + strcpy (stpcpy (name + (domain-address), "._pka."), domain+1); + + anslen = res_query (name, C_IN, T_TXT, answer, PACKETSZ); + xfree (name); + if (anslen < sizeof(HEADER)) + return NULL; /* DNS resolver returned a too short answer. */ + if ( (rc=((HEADER*)answer)->rcode) != NOERROR ) + return NULL; /* DNS resolver returned an error. */ + + /* We assume that PACKETSZ is large enough and don't do dynmically + expansion of the buffer. */ + if (anslen > PACKETSZ) + return NULL; /* DNS resolver returned a too long answer */ + + qdcount = ntohs (((HEADER*)answer)->qdcount); + ancount = ntohs (((HEADER*)answer)->ancount); + nscount = ntohs (((HEADER*)answer)->nscount); + arcount = ntohs (((HEADER*)answer)->arcount); + + if (!ancount) + return NULL; /* Got no answer. */ + + p = answer + sizeof (HEADER); + pend = answer + anslen; /* Actually points directly behind the buffer. */ + + while (qdcount-- && p < pend) + { + rc = dn_skipname (p, pend); + if (rc == -1) + return NULL; + p += rc + QFIXEDSZ; + } + + if (ancount > 1) + return NULL; /* more than one possible gpg trustdns record - none used. */ + + while (ancount-- && p <= pend) + { + unsigned int type, class, txtlen, n; + char *buffer, *bufp; + + rc = dn_skipname (p, pend); + if (rc == -1) + return NULL; + p += rc; + if (p >= pend - 10) + return NULL; /* RR too short. */ + + type = *p++ << 8; + type |= *p++; + class = *p++ << 8; + class |= *p++; + p += 4; + txtlen = *p++ << 8; + txtlen |= *p++; + if (type != T_TXT || class != C_IN) + return NULL; /* Answer does not match the query. */ + + buffer = bufp = xmalloc (txtlen + 1); + while (txtlen && p < pend) + { + for (n = *p++, txtlen--; txtlen && n && p < pend; txtlen--, n--) + *bufp++ = *p++; + } + *bufp = 0; + if (parse_txt_record (buffer, fpr)) + { + xfree (buffer); + return NULL; /* Not a valid gpg trustdns RR. */ + } + return buffer; + } + + return NULL; +} +#else /* !USE_DNS_PKA */ + +/* Dummy version of the function if we can't use the resolver + functions. */ +char * +get_pka_info (const char *address, unsigned char *fpr) +{ + return NULL; +} +#endif /* !USE_DNS_PKA */ + + +#ifdef TEST +int +main(int argc,char *argv[]) +{ + unsigned char fpr[20]; + char *uri; + int i; + + if (argc < 2) + { + fprintf (stderr, "usage: pka mail-addresses\n"); + return 1; + } + argc--; + argv++; + + for (; argc; argc--, argv++) + { + uri = get_pka_info ( *argv, fpr ); + printf ("%s", *argv); + if (uri) + { + putchar (' '); + for (i=0; i < 20; i++) + printf ("%02X", fpr[i]); + if (*uri) + printf (" %s", uri); + xfree (uri); + } + putchar ('\n'); + } + return 0; +} +#endif /* TEST */ + +/* +Local Variables: +compile-command: "cc -DUSE_DNS_PKA -DTEST -I.. -I../include -Wall -g -o pka pka.c -lresolv libutil.a" +End: +*/ diff --git a/common/pka.h b/common/pka.h new file mode 100644 index 000000000..d0b977d0f --- /dev/null +++ b/common/pka.h @@ -0,0 +1,27 @@ +/* pka.h - DNS Public Key Association RR access definitions + * Copyright (C) 2006 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ +#ifndef GNUPG_COMMON_PKA_H +#define GNUPG_COMMON_PKA_H + +char *get_pka_info (const char *address, unsigned char *fpr); + + +#endif /*GNUPG_COMMON_PKA_H*/ diff --git a/common/ttyio.c b/common/ttyio.c index 5749c59fe..c9f41c626 100644 --- a/common/ttyio.c +++ b/common/ttyio.c @@ -1,5 +1,6 @@ /* ttyio.c - tty i/O functions - * Copyright (C) 1998,1999,2000,2001,2002,2003 Free Software Foundation, Inc. + * Copyright (C) 1998,1999,2000,2001,2002,2003, + * 2004, 2006 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -45,6 +46,12 @@ #endif #include #include +#ifdef HAVE_LIBREADLINE +#include +#include +#endif + + #include "util.h" #include "memory.h" #include "ttyio.h" @@ -93,13 +100,21 @@ tty_get_ttyname (void) if (!got_name) { const char *s; + /* Note that despite our checks for these macros the function is + not necessarily thread save. We mainly do this for + portability reasons, in case L_ctermid is not defined. */ +# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_POSIX_TRHEADS) + char buffer[L_ctermid]; + s = ctermid (buffer); +# else s = ctermid (NULL); +# endif if (s) name = strdup (s); got_name = 1; } -#endif - /* Assume the staandrd tty on memory error or when tehre is no +#endif /*HAVE_CTERMID*/ + /* Assume the standard tty on memory error or when tehre is no certmid. */ return name? name : "/dev/tty"; } @@ -165,6 +180,34 @@ init_ttyfp(void) } +#ifdef HAVE_LIBREADLINE +void +tty_enable_completion(rl_completion_func_t *completer) +{ +/* if( no_terminal ) */ +/* return; */ + +/* if( !initialized ) */ +/* init_ttyfp(); */ + +/* rl_attempted_completion_function=completer; */ +/* rl_inhibit_completion=0; */ +} + +void +tty_disable_completion(void) +{ +/* if( no_terminal ) */ +/* return; */ + +/* if( !initialized ) */ +/* init_ttyfp(); */ + +/* rl_inhibit_completion=1; */ +} +#endif /*HAVE_LIBREADLINE*/ + + int tty_batchmode( int onoff ) { diff --git a/common/ttyio.h b/common/ttyio.h index 6fa7400a9..6148d644a 100644 --- a/common/ttyio.h +++ b/common/ttyio.h @@ -20,6 +20,11 @@ #ifndef GNUPG_COMMON_TTYIO_H #define GNUPG_COMMON_TTYIO_H +#ifdef HAVE_LIBREADLINE +#include +#include +#endif + const char *tty_get_ttyname (void); int tty_batchmode (int onoff); #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5 ) @@ -40,5 +45,16 @@ void tty_kill_prompt (void); int tty_get_answer_is_yes (const char *prompt); int tty_no_terminal (int onoff); +#ifdef HAVE_LIBREADLINE +void tty_enable_completion(rl_completion_func_t *completer); +void tty_disable_completion(void); +#else +/* Use a macro to stub out these functions since a macro has no need + to typedef a "rl_completion_func_t" which would be undefined + without readline. */ +#define tty_enable_completion(x) +#define tty_disable_completion() +#endif + #endif /*GNUPG_COMMON_TTYIO_H*/ diff --git a/common/util.h b/common/util.h index 68f5222b5..295d785c5 100644 --- a/common/util.h +++ b/common/util.h @@ -84,6 +84,7 @@ u32 scan_isodatestr (const char *string); u32 add_days_to_timestamp (u32 stamp, u16 days); const char *strtimevalue (u32 stamp); const char *strtimestamp (u32 stamp); /* GMT */ +const char *isotimestamp (u32 stamp); /* GMT */ const char *asctimestamp (u32 stamp); /* localized */ @@ -108,6 +109,7 @@ void gnupg_unblock_all_signals (void); int answer_is_yes (const char *s); int answer_is_yes_no_default (const char *s, int def_answer); int answer_is_yes_no_quit (const char *s); +int answer_is_okay_cancel (const char *s, int def_answer); /*-- xreadline.c --*/ ssize_t read_line (FILE *fp, @@ -161,6 +163,7 @@ char *make_printable_string (const void *p, size_t n, int delim); int is_file_compressed (const char *s, int *ret_rc); +int match_multistr (const char *multistr,const char *match); /*-- Simple replacement functions. */ diff --git a/common/yesno.c b/common/yesno.c index 2a96b4e5d..737071691 100644 --- a/common/yesno.c +++ b/common/yesno.c @@ -28,31 +28,33 @@ int answer_is_yes_no_default( const char *s, int def_answer ) { - const char *long_yes = _("yes"); - const char *short_yes = _("yY"); - const char *long_no = _("no"); - const char *short_no = _("nN"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_yes = _("yes"); + const char *short_yes = _("yY"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_no = _("no"); + const char *short_no = _("nN"); - /* Note: we have to use the local dependent strcasecmp here */ - if( !strcasecmp(s, long_yes ) ) - return 1; - if( *s && strchr( short_yes, *s ) && !s[1] ) - return 1; - /* test for no strings to catch ambiguities for the next test */ - if( !strcasecmp(s, long_no ) ) - return 0; - if( *s && strchr( short_no, *s ) && !s[1] ) - return 0; - /* test for the english version (for those who are used to type yes) */ - if( !ascii_strcasecmp(s, "yes" ) ) - return 1; - if( *s && strchr( "yY", *s ) && !s[1] ) - return 1; - return def_answer; + /* Note: we have to use the local dependent compare here. */ + if ( match_multistr(long_yes,s) ) + return 1; + if ( *s && strchr( short_yes, *s ) && !s[1] ) + return 1; + /* Test for "no" strings to catch ambiguities for the next test. */ + if ( match_multistr(long_no,s) ) + return 0; + if ( *s && strchr( short_no, *s ) && !s[1] ) + return 0; + /* Test for the english version (for those who are used to type yes). */ + if ( !ascii_strcasecmp(s, "yes" ) ) + return 1; + if ( *s && strchr( "yY", *s ) && !s[1] ) + return 1; + return def_answer; } int -answer_is_yes( const char *s ) +answer_is_yes ( const char *s ) { return answer_is_yes_no_default(s,0); } @@ -61,36 +63,76 @@ answer_is_yes( const char *s ) * Return 1 for yes, -1 for quit, or 0 for no */ int -answer_is_yes_no_quit( const char *s ) +answer_is_yes_no_quit ( const char *s ) { - const char *long_yes = _("yes"); - const char *long_no = _("no"); - const char *long_quit = _("quit"); - const char *short_yes = _("yY"); - const char *short_no = _("nN"); - const char *short_quit = _("qQ"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_yes = _("yes"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_no = _("no"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_quit = _("quit"); + const char *short_yes = _("yY"); + const char *short_no = _("nN"); + const char *short_quit = _("qQ"); - /* Note: We have to use the locale dependent strcasecmp */ - if( !strcasecmp(s, long_no ) ) - return 0; - if( !strcasecmp(s, long_yes ) ) - return 1; - if( !strcasecmp(s, long_quit ) ) - return -1; - if( *s && strchr( short_no, *s ) && !s[1] ) - return 0; - if( *s && strchr( short_yes, *s ) && !s[1] ) - return 1; - if( *s && strchr( short_quit, *s ) && !s[1] ) - return -1; - /* but not here */ - if( !ascii_strcasecmp(s, "yes" ) ) - return 1; - if( !ascii_strcasecmp(s, "quit" ) ) - return -1; - if( *s && strchr( "yY", *s ) && !s[1] ) - return 1; - if( *s && strchr( "qQ", *s ) && !s[1] ) - return -1; + /* Note: we have to use a local dependent compare here. */ + if ( match_multistr(long_no,s) ) return 0; + if ( match_multistr(long_yes,s) ) + return 1; + if ( match_multistr(long_quit,s) ) + return -1; + if ( *s && strchr( short_no, *s ) && !s[1] ) + return 0; + if ( *s && strchr( short_yes, *s ) && !s[1] ) + return 1; + if ( *s && strchr( short_quit, *s ) && !s[1] ) + return -1; + /* but not here. */ + if ( !ascii_strcasecmp(s, "yes" ) ) + return 1; + if ( !ascii_strcasecmp(s, "quit" ) ) + return -1; + if ( *s && strchr( "yY", *s ) && !s[1] ) + return 1; + if ( *s && strchr( "qQ", *s ) && !s[1] ) + return -1; + return 0; } + +/* + Return 1 for okay, 0 for for cancel or DEF_ANSWER for default. + */ +int +answer_is_okay_cancel (const char *s, int def_answer) +{ + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_okay = _("okay|okay"); + /* TRANSLATORS: See doc/TRANSLATE about this string. */ + const char *long_cancel = _("cancel|cancel"); + const char *short_okay = _("oO"); + const char *short_cancel = _("cC"); + + /* Note: We have to use the locale dependent compare. */ + if ( match_multistr(long_okay,s) ) + return 1; + if ( match_multistr(long_cancel,s) ) + return 0; + if ( *s && strchr( short_okay, *s ) && !s[1] ) + return 1; + if ( *s && strchr( short_cancel, *s ) && !s[1] ) + return 0; + /* Always test for the English values (not locale here). */ + if ( !ascii_strcasecmp(s, "okay" ) ) + return 1; + if ( !ascii_strcasecmp(s, "ok" ) ) + return 1; + if ( !ascii_strcasecmp(s, "cancel" ) ) + return 0; + if ( *s && strchr( "oO", *s ) && !s[1] ) + return 1; + if ( *s && strchr( "cC", *s ) && !s[1] ) + return 0; + return def_answer; +} + diff --git a/configure.ac b/configure.ac index 53cbc38fc..05882c2c9 100644 --- a/configure.ac +++ b/configure.ac @@ -147,6 +147,16 @@ AC_ARG_ENABLE(agent-only, build_agent_only=$enableval) +# Allow disabling of bzib2 support. +# It is defined only after we confirm the library is available later +use_bzip2=yes +AC_MSG_CHECKING([whether to enable the BZIP2 compression algorithm]) +AC_ARG_ENABLE(bzip2, + AC_HELP_STRING([--disable-bzip2],[disable the BZIP2 compression algorithm]), + use_bzip2=$enableval) +AC_MSG_RESULT($use_bzip2) + + # Configure option to allow or disallow execution of external # programs, like a photo viewer. AC_MSG_CHECKING([whether to enable external program execution]) @@ -462,6 +472,8 @@ if test "$have_w32_system" = yes; then fi AM_CONDITIONAL(HAVE_W32_SYSTEM, test "$have_w32_system" = yes) +# These need to go after AC_PROG_CC so that $EXEEXT is defined +AC_DEFINE_UNQUOTED(EXEEXT,"$EXEEXT",[The executable file extension, if any]) # @@ -969,11 +981,13 @@ else AC_DEFINE(DISABLE_REGEX,1,[ Define to disable regular expression support ]) fi -dnl Do we have zlib? Must do it here because Solaris failed -dnl when compiling a conftest (due to the "-lz" from LIBS). +# +# Do we have zlib? Must do it here because Solaris failed +# when compiling a conftest (due to the "-lz" from LIBS). +# Note that we combine zlib and bzlib2 in ZLIBS. +# _cppflags="${CPPFLAGS}" _ldflags="${LDFLAGS}" - AC_ARG_WITH(zlib, [ --with-zlib=DIR use libz in DIR],[ if test -d "$withval"; then @@ -984,10 +998,43 @@ AC_ARG_WITH(zlib, AC_CHECK_HEADER(zlib.h, AC_CHECK_LIB(z, deflateInit2_, - LIBS="$LIBS -lz", + ZLIBS="-lz", CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}), CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}) - + +# +# Check whether we can support bzip2 +# +if test "$use_bzip2" = yes ; then + _cppflags="${CPPFLAGS}" + _ldflags="${LDFLAGS}" + AC_ARG_WITH(bzip2, + AC_HELP_STRING([--with-bzip2=DIR],[look for bzip2 in DIR]), + [ + if test -d "$withval" ; then + CPPFLAGS="${CPPFLAGS} -I$withval/include" + LDFLAGS="${LDFLAGS} -L$withval/lib" + fi + ],withval="") + + # Checking alongside stdio.h as an early version of bzip2 (1.0) + # required stdio.h to be included before bzlib.h, and Solaris 9 is + # woefully out of date. + if test "$withval" != no ; then + AC_CHECK_HEADER(bzlib.h, + AC_CHECK_LIB(bz2,BZ2_bzCompressInit, + [ + have_bz2=yes + ZLIBS="$ZLIBS -lbz2" + AC_DEFINE(HAVE_BZIP2,1, + [Defined if the bz2 compression library is available]) + ], + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags}), + CPPFLAGS=${_cppflags} LDFLAGS=${_ldflags},[#include ]) + fi +fi +AM_CONDITIONAL(ENABLE_BZIP2_SUPPORT,test x"$have_bz2" = "xyes") +AC_SUBST(ZLIBS) # See wether we want to run the long test suite. diff --git a/g10/ChangeLog b/g10/ChangeLog index b8f789e8b..6018bbe13 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,43 @@ +2006-05-23 Werner Koch + + * card-util.c (generate_card_keys): Removed temporary kludge for + generate_keypair. + + * call-agent.c (agent_scd_setattr): Add arg SERIALNO. + (agent_scd_genkey): Ditto. + (agent_scd_change_pin): Ditto. + + * call-agent.h (struct agent_card_info_s): Updated to match the + one of 1.4.3. + + * Makefile.am (LDADD): Include ZLIBS. + + * gpgv.c: Removed stubs not anymore useful due to libgcrypt. + +2006-05-22 Werner Koch + + * keyserver.c (keyidlist): Replaced mpi_get_keyid by v3_keyid. + * keydb.h (v3_keyid): Added. + + * import.c (import): Better initialize KEYBLOCK as to quiet + compiler warning. + + * skclist.c (random_is_faked): New. + + * mainproc.c: Include pka.h. + +2006-05-19 Werner Koch + + * misc.c (openpgp_pk_test_algo2): Need to use gcry_pk_algo_info + directly. + (string_count_chr): New. + + * armor.c (parse_header_line): Use renamed function + length_sans_trailing_ws. + + * options.h, gpg.c: Option --strict is not used thus removed code + but kept option. + 2006-04-28 David Shaw (wk) * keyserver.c (direct_uri_map): New. diff --git a/g10/Makefile.am b/g10/Makefile.am index 1deacb9f8..aeb24d7b3 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -107,7 +107,7 @@ gpgv2_SOURCES = gpgv.c \ # ks-db.h \ # $(common_source) -LDADD = $(needed_libs) @LIBINTL@ @CAPLIBS@ @W32LIBS@ +LDADD = $(needed_libs) $(ZLIBS) @LIBINTL@ @CAPLIBS@ @W32LIBS@ gpg2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error gpgv2_LDADD = $(LIBGCRYPT_LIBS) $(LDADD) -lassuan -lgpg-error diff --git a/g10/armor.c b/g10/armor.c index e02591372..2336ff6f9 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -336,7 +336,7 @@ parse_header_line( armor_filter_context_t *afx, byte *line, unsigned int len ) int hashes=0; unsigned int len2; - len2 = check_trailing_ws( line, len ); + len2 = length_sans_trailing_ws ( line, len ); if( !len2 ) { afx->buffer_pos = len2; /* (it is not the fine way to do it here) */ return 0; /* WS only: same as empty line */ diff --git a/g10/call-agent.c b/g10/call-agent.c index 31c43cf13..55fc62569 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -626,10 +626,13 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info) } -/* Send an setattr command to the SCdaemon. */ +/* Send an setattr command to the SCdaemon. SERIALNO is not actually + used here but required by gpg 1.4's implementation of this code in + cardglue.c. */ int agent_scd_setattr (const char *name, - const unsigned char *value, size_t valuelen) + const unsigned char *value, size_t valuelen, + const char *serialno) { int rc; char line[ASSUAN_LINELENGTH]; @@ -719,9 +722,11 @@ scd_genkey_cb (void *opaque, const char *line) return 0; } -/* Send a GENKEY command to the SCdaemon. */ +/* Send a GENKEY command to the SCdaemon. SERIALNO is not used in + this implementation. */ int -agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force) +agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force, + const char *serialno) { int rc; char line[ASSUAN_LINELENGTH]; @@ -865,9 +870,10 @@ agent_scd_pkdecrypt (const char *serialno, 3: Change the admin PIN 101: Set a new PIN and reset the retry counter 102: Same as 101 + SERIALNO is not used. */ int -agent_scd_change_pin (int chvno) +agent_scd_change_pin (int chvno, const char *serialno) { int rc; char line[ASSUAN_LINELENGTH]; @@ -890,7 +896,7 @@ agent_scd_change_pin (int chvno) /* Perform a CHECKPIN operation. SERIALNO should be the serial - number of the card - optioanlly followed by the fingerprint; + number of the card - optionally followed by the fingerprint; however the fingerprint is ignored here. */ int agent_scd_checkpin (const char *serialno) @@ -910,3 +916,9 @@ agent_scd_checkpin (const char *serialno) } +/* Dummy function, only used by the gpg 1.4 implementation. */ +void +agent_clear_pin_cache (const char *sn) +{ + +} diff --git a/g10/call-agent.h b/g10/call-agent.h index 3d9f4f9bf..71044e38b 100644 --- a/g10/call-agent.h +++ b/g10/call-agent.h @@ -21,7 +21,8 @@ #define GNUPG_G10_CALL_AGENT_H -struct agent_card_info_s { +struct agent_card_info_s +{ int error; /* private. */ char *serialno; /* malloced hex string. */ char *disp_name; /* malloced. */ @@ -29,6 +30,7 @@ struct agent_card_info_s { int disp_sex; /* 0 = unspecified, 1 = male, 2 = female */ char *pubkey_url; /* malloced. */ char *login_data; /* malloced. */ + char *private_do[4]; /* malloced. */ char cafpr1valid; char cafpr2valid; char cafpr3valid; @@ -41,6 +43,9 @@ struct agent_card_info_s { char fpr1[20]; char fpr2[20]; char fpr3[20]; + u32 fpr1time; + u32 fpr2time; + u32 fpr3time; unsigned long sig_counter; int chv1_cached; /* True if a PIN is not required for each signing. Note that the gpg-agent might cache @@ -73,10 +78,12 @@ int agent_havekey (const char *hexkeygrip); /* Send a SETATTR command to the SCdaemon. */ int agent_scd_setattr (const char *name, - const unsigned char *value, size_t valuelen); + const unsigned char *value, size_t valuelen, + const char *serialno); /* Send a GENKEY command to the SCdaemon. */ -int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force); +int agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force, + const char *serialno); /* Send a PKSIGN command to the SCdaemon. */ int agent_scd_pksign (const char *keyid, int hashalgo, @@ -89,11 +96,13 @@ int agent_scd_pkdecrypt (const char *serialno, char **r_buf, size_t *r_buflen); /* Change the PIN of an OpenPGP card or reset the retry counter. */ -int agent_scd_change_pin (int chvno); +int agent_scd_change_pin (int chvno, const char *serialno); /* Send the CHECKPIN command to the SCdaemon. */ int agent_scd_checkpin (const char *serialno); +/* Dummy function, only implemented by gpg 1.4. */ +void agent_clear_pin_cache (const char *sn); #endif /*GNUPG_G10_CALL_AGENT_H*/ diff --git a/g10/card-util.c b/g10/card-util.c index 0c8365405..b5a036e54 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -27,7 +27,7 @@ #include #if GNUPG_MAJOR_VERSION != 1 -#include "gpg.h" +# include "gpg.h" #endif /*GNUPG_MAJOR_VERSION != 1*/ #include "util.h" #include "i18n.h" @@ -37,13 +37,13 @@ #include "main.h" #include "keyserver-internal.h" #if GNUPG_MAJOR_VERSION == 1 -#ifdef HAVE_LIBREADLINE -#include -#include -#endif /*HAVE_LIBREADLINE*/ -#include "cardglue.h" +# ifdef HAVE_LIBREADLINE +# include +# include +# endif /*HAVE_LIBREADLINE*/ +# include "cardglue.h" #else /*GNUPG_MAJOR_VERSION!=1*/ -#include "call-agent.h" +# include "call-agent.h" #endif /*GNUPG_MAJOR_VERSION!=1*/ #define CONTROL_D ('D' - 'A' + 1) @@ -1091,12 +1091,8 @@ generate_card_keys (const char *serialno) if (check_pin_for_key_operation (&info, &forced_chv1)) goto leave; -#if GNUPG_MAJOR_VERSION == 1 generate_keypair (NULL, info.serialno, want_backup? opt.homedir:NULL); -#else - generate_keypair (NULL, info.serialno); -#endif leave: agent_release_card_info (&info); diff --git a/g10/gpg.c b/g10/gpg.c index 25b55b705..cc00ff3b5 100644 --- a/g10/gpg.c +++ b/g10/gpg.c @@ -1376,7 +1376,7 @@ list_config(char *items) for(sl=iter->values;sl;sl=sl->next) { - print_string2(stdout,sl->d,strlen(sl->d),':',';'); + print_sanitized_string2 (stdout, sl->d, ':',';'); if(sl->next) printf(";"); } @@ -1782,13 +1782,11 @@ main (int argc, char **argv ) opt.no_perm_warn=1; else if (pargs.r_opt == oStrict ) { - opt.strict=1; - log_set_strict(1); + /* Not used */ } else if (pargs.r_opt == oNoStrict ) { - opt.strict=0; - log_set_strict(0); + /* Not used */ } } @@ -2360,8 +2358,14 @@ main (int argc, char **argv ) compress_algo_string = xstrdup(pargs.r.ret_str); } break; - case oCertDigestAlgo: cert_digest_string = xstrdup(pargs.r.ret_str); break; - case oNoSecmemWarn: secmem_set_flags( secmem_get_flags() | 1 ); break; + case oCertDigestAlgo: + cert_digest_string = xstrdup(pargs.r.ret_str); + break; + + case oNoSecmemWarn: + gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); + break; + case oRequireSecmem: require_secmem=1; break; case oNoRequireSecmem: require_secmem=0; break; case oNoPermissionWarn: opt.no_perm_warn=1; break; @@ -2604,8 +2608,12 @@ main (int argc, char **argv ) xfree(iter); } break; - case oStrict: opt.strict=1; log_set_strict(1); break; - case oNoStrict: opt.strict=0; log_set_strict(0); break; + + case oStrict: + case oNoStrict: + /* Not used */ + break; + case oMangleDosFilenames: opt.mangle_dos_filenames = 1; break; case oNoMangleDosFilenames: opt.mangle_dos_filenames = 0; break; case oEnableProgressFilter: opt.enable_progress_filter = 1; break; @@ -3035,7 +3043,6 @@ main (int argc, char **argv ) /* Set the random seed file. */ if( use_random_seed ) { char *p = make_filename(opt.homedir, "random_seed", NULL ); - set_random_seed_file(p); gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p); if (!access (p, F_OK)) register_secured_file (p); diff --git a/g10/gpgv.c b/g10/gpgv.c index 9b17b8ad3..579e58a29 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -387,26 +387,6 @@ void cipher_decrypt( gcry_cipher_hd_t c, byte *outbuf, byte *inbuf, unsigned nbytes ) {} void cipher_sync( gcry_cipher_hd_t c ) {} -/* Stubs to avoid linking to ../cipher/random.c */ -void random_dump_stats(void) {} -int quick_random_gen( int onoff ) { return -1;} -void randomize_buffer( byte *buffer, size_t length, int level ) {} -int random_is_faked() { return -1;} -byte *get_random_bits( size_t nbits, int level, int secure ) { return NULL;} -void set_random_seed_file( const char *name ) {} -void update_random_seed_file() {} -void fast_random_poll() {} - -/* Stubs to avoid linking of ../cipher/primegen.c */ -void register_primegen_progress ( void (*cb)( void *, int), void *cb_data ) {} -MPI generate_secret_prime( unsigned nbits ) { return NULL;} -MPI generate_public_prime( unsigned nbits ) { return NULL;} -MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits, - gcry_mpi_t g, gcry_mpi_t **ret_factors ) { return NULL;} - -/* Do not link to ../cipher/rndlinux.c */ -void rndlinux_constructor(void) {} - /* Stubs to avoid linking to ../util/ttyio.c */ int tty_batchmode( int onoff ) { return 0; } diff --git a/g10/import.c b/g10/import.c index ee4ea95da..4526d84d7 100644 --- a/g10/import.c +++ b/g10/import.c @@ -243,7 +243,9 @@ import( IOBUF inp, const char* fname,struct stats_s *stats, unsigned char **fpr,size_t *fpr_len,unsigned int options ) { PACKET *pending_pkt = NULL; - KBNODE keyblock; + KBNODE keyblock = NULL; /* Need to initialize because gcc can't + grasp the return semantics of + read_block. */ int rc = 0; getkey_disable_caches(); @@ -596,7 +598,7 @@ check_prefs(KBNODE keyblock) if(prefs->type==PREFTYPE_SYM) { - if (openpgp_cipher_algo_test (prefs->value)) + if (openpgp_cipher_test_algo (prefs->value)) { const char *algo = gcry_cipher_algo_name (prefs->value); if(!problem) diff --git a/g10/keydb.h b/g10/keydb.h index 4923a842c..f8be6efb9 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -254,6 +254,7 @@ int parse_auto_key_locate(char *options); /*-- keyid.c --*/ int pubkey_letter( int algo ); +u32 v3_keyid (gcry_mpi_t a, u32 *ki); void hash_public_key( gcry_md_hd_t md, PKT_public_key *pk ); size_t keystrlen(void); const char *keystr(u32 *keyid); diff --git a/g10/keygen.c b/g10/keygen.c index c7a97a0fc..9c2fd6fb8 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1911,8 +1911,9 @@ ask_user_id( int mode ) /* append a warning if we do not have dev/random * or it is switched into quick testmode */ - if( quick_random_gen(-1) ) - strcpy(p, " (INSECURE!)" ); + /* FIXME: see skclist.c:random_is_faked */ + /* if( quick_random_gen(-1) ) */ + /* strcpy(p, " (INSECURE!)" ); */ /* print a note in case that UTF8 mapping has to be done */ for(p=uid; *p; p++ ) { @@ -2648,7 +2649,7 @@ read_parameter_file( const char *fname ) /* * Generate a keypair (fname is only used in batch mode) If - * CARD_SERIALNO is not NULL the fucntion will create the keys on an + * CARD_SERIALNO is not NULL the function will create the keys on an * OpenPGP Card. If BACKUP_ENCRYPTION_DIR has been set and * CARD_SERIALNO is NOT NULL, the encryption key for the card gets * generate in software, imported to the card and a backup file diff --git a/g10/keyserver.c b/g10/keyserver.c index 3127a4795..bf1bf6cdc 100644 --- a/g10/keyserver.c +++ b/g10/keyserver.c @@ -42,6 +42,9 @@ #include "trustdb.h" #include "keyserver-internal.h" #include "util.h" +#include "dns-cert.h" +#include "pka.h" + struct keyrec { @@ -1730,8 +1733,8 @@ keyidlist(STRLIST users,KEYDB_SEARCH_DESC **klist,int *count,int fakev3) node->pkt->pkt.public_key->version>=4) { (*klist)[*count].mode=KEYDB_SEARCH_MODE_LONG_KID; - mpi_get_keyid(node->pkt->pkt.public_key->pkey[0], - (*klist)[*count].u.kid); + v3_keyid (node->pkt->pkt.public_key->pkey[0], + (*klist)[*count].u.kid); (*count)++; if(*count==num) @@ -1982,7 +1985,7 @@ keyserver_import_cert(const char *name,unsigned char **fpr,size_t *fpr_len) if(domain) *domain='.'; - type=get_cert(look,max_cert_size,&key,fpr,fpr_len,&url); + type=get_dns_cert(look,max_cert_size,&key,fpr,fpr_len,&url); if(type==1) { int armor_status=opt.no_armor; diff --git a/g10/main.h b/g10/main.h index cd6926b69..18d11b567 100644 --- a/g10/main.h +++ b/g10/main.h @@ -84,6 +84,7 @@ u32 buffer_to_u32( const byte *buffer ); const byte *get_session_marker( size_t *rlen ); int openpgp_cipher_test_algo( int algo ); int openpgp_pk_test_algo( int algo ); +int openpgp_pk_test_algo2 ( int algo, unsigned int use ); int openpgp_pk_algo_usage ( int algo ); int openpgp_md_test_algo( int algo ); diff --git a/g10/mainproc.c b/g10/mainproc.c index 1f91c8ca6..67ac784dc 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -41,6 +41,7 @@ #include "trustdb.h" #include "keyserver-internal.h" #include "photoid.h" +#include "pka.h" struct kidlist_item { diff --git a/g10/misc.c b/g10/misc.c index a26aa740d..12aa6c689 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -67,6 +67,18 @@ #include "i18n.h" +static int +string_count_chr (const char *string, int c) +{ + int count; + + for (count=0; *string; string++ ) + if ( *string == c ) + count++; + return count; +} + + #ifdef ENABLE_SELINUX_HACKS /* A object and a global variable to keep track of files marked as @@ -416,12 +428,17 @@ openpgp_pk_test_algo( int algo ) int openpgp_pk_test_algo2( int algo, unsigned int use ) { + int use_buf = use; + size_t sizeof_use_buf = sizeof (use_buf); + if (algo == GCRY_PK_ELG_E) algo = GCRY_PK_ELG; if (algo < 0 || algo > 110) return gpg_error (GPG_ERR_PUBKEY_ALGO); - return gcry_pk_test_algo2 (algo, use); + + return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, + &use_buf, &sizeof_use_buf); } int diff --git a/g10/options.h b/g10/options.h index de5fa7920..b97b2f3f9 100644 --- a/g10/options.h +++ b/g10/options.h @@ -193,7 +193,6 @@ struct int preserve_permissions; int no_homedir_creation; struct groupitem *grouplist; - int strict; int mangle_dos_filenames; int enable_progress_filter; unsigned int screen_columns; diff --git a/g10/passphrase.c b/g10/passphrase.c index c1cdf12ae..1c5cf3b27 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -1017,7 +1017,7 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ) int pwlen = strlen(pw); assert( s2k->hash_algo ); - dek->keylen = gcry_cipher_algo_get_keylen (dek->algo ); + dek->keylen = gcry_cipher_get_algo_keylen (dek->algo); if( !(dek->keylen > 0 && dek->keylen <= DIM(dek->key)) ) BUG(); @@ -1065,7 +1065,7 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ) i = gcry_md_get_algo_dlen ( s2k->hash_algo ); if( i > dek->keylen - used ) i = dek->keylen - used; - memcpy( dek->key+used, md_read(md, s2k->hash_algo), i ); + memcpy (dek->key+used, gcry_md_read (md, s2k->hash_algo), i); used += i; } gcry_md_close(md); diff --git a/g10/pkclist.c b/g10/pkclist.c index 4a12083d3..4516f6769 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -363,7 +363,7 @@ do_edit_ownertrust (PKT_public_key *pk, int mode, int edit_ownertrust (PKT_public_key *pk, int mode ) { - unsigned int trust; + unsigned int trust = 0; int no_help = 0; for(;;) @@ -897,7 +897,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) else if (backlog) { /* This is part of our trick to expand and display groups. */ - answer = pop_strlist (&backlog); + answer = strlist_pop (&backlog); } else { @@ -1032,7 +1032,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) rc = get_pubkey_byname (pk, def_rec, NULL, NULL, 1); if (rc) log_error(_("unknown default recipient \"%s\"\n"), def_rec ); - else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) + else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use)) ) { /* Mark any_recipients here since the default recipient would have been used if it wasn't already there. It @@ -1079,7 +1079,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned int use ) -1); goto fail; } - else if ( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) + else if ( !(rc=openpgp_pk_test_algo2(pk->pubkey_algo, use )) ) { /* Key found and usable. Check validity. */ int trustlevel; diff --git a/g10/plaintext.c b/g10/plaintext.c index c0a6c3e11..8032f15f0 100644 --- a/g10/plaintext.c +++ b/g10/plaintext.c @@ -282,7 +282,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, rc = gpg_error_from_errno (errno); else rc = gpg_error (GPG_ERR_EOF); - log_error("Error writing to `%s': %s\n", + log_error("error writing to `%s': %s\n", fname, strerror(errno) ); goto leave; } @@ -310,7 +310,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, { if(opt.max_output && (count+=len)>opt.max_output) { - log_error("Error writing to `%s': %s\n", + log_error("error writing to `%s': %s\n", fname,"exceeded --max-output limit\n"); rc = gpg_error (GPG_ERR_TOO_LARGE); xfree( buffer ); @@ -319,7 +319,7 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, else if( fwrite( buffer, 1, len, fp ) != len ) { rc = (errno? gpg_error_from_errno (errno) : gpg_error (GPG_ERR_INTERNAL)); - log_error("Error writing to `%s': %s\n", + log_error ("error writing to `%s': %s\n", fname, strerror(errno) ); xfree( buffer ); goto leave; @@ -338,16 +338,17 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, { if(opt.max_output && (++count)>opt.max_output) { - log_error("Error writing to `%s': %s\n", + log_error ("error writing to `%s': %s\n", fname,"exceeded --max-output limit\n"); rc = gpg_error (GPG_ERR_TOO_LARGE); goto leave; } else if( putc( c, fp ) == EOF ) { - log_error("Error writing to `%s': %s\n", + rc = (errno? gpg_error_from_errno (errno) + : gpg_error (GPG_ERR_INTERNAL)); + log_error ("error writing to `%s': %s\n", fname, strerror(errno) ); - rc = G10ERR_WRITE_FILE; goto leave; } } @@ -384,9 +385,10 @@ handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx, } if( fp && fp != stdout && fclose(fp) ) { - log_error("Error closing `%s': %s\n", fname, strerror(errno) ); + rc = (errno? gpg_error_from_errno (errno) + : gpg_error (GPG_ERR_INTERNAL)); + log_error ("error closing `%s': %s\n", fname, strerror(errno) ); fp = NULL; - rc = G10ERR_WRITE_FILE; goto leave; } fp = NULL; diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 5af0d5f1d..dc0124bd4 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -214,8 +214,8 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid ) * DEK is the encryption key (session key) with length k * CSUM */ - if( DBG_CIPHER ) - log_hexdump("DEK frame:", frame, nframe ); + if (DBG_CIPHER) + log_printhex ("DEK frame:", frame, nframe ); n=0; if (!card) { @@ -267,7 +267,7 @@ get_it( PKT_pubkey_enc *enc, DEK *dek, PKT_secret_key *sk, u32 *keyid ) goto leave; } if( DBG_CIPHER ) - log_hexdump("DEK is:", dek->key, dek->keylen ); + log_printhex ("DEK is:", dek->key, dek->keylen ); /* check that the algo is in the preferences and whether it has expired */ { PKT_public_key *pk = NULL; diff --git a/g10/sign.c b/g10/sign.c index fa3796758..3e1d7bc53 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -458,7 +458,7 @@ hash_for(PKT_secret_key *sk) else { for (prefs=opt.personal_digest_prefs; prefs->type; prefs++) - if (gcry_md-get_algo_dlen (prefs->value) == qbytes) + if (gcry_md_get_algo_dlen (prefs->value) == qbytes) return prefs->value; } } diff --git a/g10/skclist.c b/g10/skclist.c index afaa73814..d8f3b2dc1 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -36,6 +36,19 @@ #include "cipher.h" +/* There is currently no way to get the status of the quick random + generator flag from libgcrypt and it is not clear whether this + faked RNG is really a good idea. Thus for now we use this stub + function but we should consider to entirely remove this fake RNG + stuff. */ +static int +random_is_faked (void) +{ + return 0; +} + + + void release_sk_list( SK_LIST sk_list ) { diff --git a/jnlib/ChangeLog b/jnlib/ChangeLog index f3074c6af..61d12d580 100644 --- a/jnlib/ChangeLog +++ b/jnlib/ChangeLog @@ -1,3 +1,22 @@ +2006-05-23 Werner Koch + + * libjnlib-config.h (JNLIB_NEED_UTF8CONV): Fixed typo in name. + + * dotlock.c (release_dotlock): Don't act if we don't have any + locks at all. + (destroy_dotlock): New. From 1.4.3. + (dotlock_remove_lockfiles): Make use of destroy function. + +2006-05-19 Werner Koch + + * strlist.c (append_to_strlist2): Enabled. + + * stringhelp.c (print_sanitized_buffer2): New. Changed the rules + to match the behaviour of print_string2 from gnupg 1.4.3. + (print_sanitized_buffer): Use the new function. + (print_sanitized_string2): New. + (hextobyte): New. Taken from gpg 1.4.3. + 2006-04-28 Werner Koch * stringhelp.c (print_sanitized_buffer): Fix bug where the count diff --git a/jnlib/dotlock.c b/jnlib/dotlock.c index a50a0ee99..b7f892717 100644 --- a/jnlib/dotlock.c +++ b/jnlib/dotlock.c @@ -1,5 +1,6 @@ /* dotlock.c - dotfile locking - * Copyright (C) 1998,2000,2001,2003 Free Software Foundation, Inc. + * Copyright (C) 1998, 2000, 2001, 2003, 2004, + * 2005 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -149,9 +150,9 @@ create_dotlock( const char *file_to_lock ) dirpart = file_to_lock; } - #ifdef _REENTRANT +#ifdef _REENTRANT /* fixme: aquire mutex on all_lockfiles */ - #endif +#endif h->next = all_lockfiles; all_lockfiles = h; @@ -202,15 +203,54 @@ create_dotlock( const char *file_to_lock ) return NULL; } - #ifdef _REENTRANT +# ifdef _REENTRANT /* release mutex */ - #endif +# endif #endif /* !HAVE_DOSISH_SYSTEM */ h->lockname = jnlib_xmalloc( strlen(file_to_lock) + 6 ); strcpy(stpcpy(h->lockname, file_to_lock), EXTSEP_S "lock"); return h; } + +void +destroy_dotlock ( DOTLOCK h ) +{ +#if !defined (HAVE_DOSISH_SYSTEM) + if ( h ) + { + DOTLOCK hprev, htmp; + + /* First remove the handle from our global list of all locks. */ + for (hprev=NULL, htmp=all_lockfiles; htmp; hprev=htmp, htmp=htmp->next) + if (htmp == h) + { + if (hprev) + hprev->next = htmp->next; + else + all_lockfiles = htmp->next; + h->next = NULL; + break; + } + + /* Second destroy the lock. */ + if (!h->disable) + { + if (h->locked && h->lockname) + unlink (h->lockname); + if (h->tname) + unlink (h->tname); + jnlib_free (h->tname); + jnlib_free (h->lockname); + } + jnlib_free(h); + + } +#endif +} + + + static int maybe_deadlock( DOTLOCK h ) { @@ -331,6 +371,13 @@ release_dotlock( DOTLOCK h ) #else int pid; + /* To avoid atexit race conditions we first check whether there + are any locks left. It might happen that another atexit + handler tries to release the lock while the atexit handler of + this module already ran and thus H is undefined. */ + if(!all_lockfiles) + return 0; + if( h->disable ) { return 0; } @@ -414,22 +461,16 @@ void dotlock_remove_lockfiles() { #ifndef HAVE_DOSISH_SYSTEM - DOTLOCK h, h2; - - h = all_lockfiles; - all_lockfiles = NULL; - - while( h ) { - h2 = h->next; - if (!h->disable ) { - if( h->locked ) - unlink( h->lockname ); - unlink(h->tname); - jnlib_free(h->tname); - jnlib_free(h->lockname); - } - jnlib_free(h); - h = h2; + DOTLOCK h, h2; + + h = all_lockfiles; + all_lockfiles = NULL; + + while ( h ) + { + h2 = h->next; + destroy_dotlock (h); + h = h2; } #endif } diff --git a/jnlib/dotlock.h b/jnlib/dotlock.h index 9235687df..2cb39008a 100644 --- a/jnlib/dotlock.h +++ b/jnlib/dotlock.h @@ -26,6 +26,7 @@ typedef struct dotlock_handle *DOTLOCK; void disable_dotlock (void); DOTLOCK create_dotlock(const char *file_to_lock); +void destroy_dotlock ( DOTLOCK h ); int make_dotlock (DOTLOCK h, long timeout); int release_dotlock (DOTLOCK h); void dotlock_remove_lockfiles (void); diff --git a/jnlib/libjnlib-config.h b/jnlib/libjnlib-config.h index 8ae2a9ce9..da3991432 100644 --- a/jnlib/libjnlib-config.h +++ b/jnlib/libjnlib-config.h @@ -30,31 +30,31 @@ #include "logging.h" /* We require support for utf-8 conversion. */ -#define JNLIB_NEED_UTF8CONF 1 +#define JNLIB_NEED_UTF8CONV 1 #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) +# define _(a) gettext (a) +# define N_(a) (a) #else #ifdef HAVE_LOCALE_H - #include +# 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 +# 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) +# define _(a) (a) +# define N_(a) (a) #endif #endif /* !USE_SIMPLE_GETTEXT */ diff --git a/jnlib/stringhelp.c b/jnlib/stringhelp.c index d5a2c29b6..27b8a25e8 100644 --- a/jnlib/stringhelp.c +++ b/jnlib/stringhelp.c @@ -218,8 +218,8 @@ length_sans_trailing_chars (const unsigned char *line, size_t len, return len; } -/**************** - * remove trailing white spaces and return the length of the buffer +/* + * Return the length of line ignoring trailing white-space. */ size_t length_sans_trailing_ws (const unsigned char *line, size_t len) @@ -336,34 +336,86 @@ compare_filenames( const char *a, const char *b ) #endif } + +/* Convert 2 hex characters at S to a byte value. Return this value + or -1 if there is an error. */ +int +hextobyte (const char *s) +{ + int c; + + if ( *s >= '0' && *s <= '9' ) + c = 16 * (*s - '0'); + else if ( *s >= 'A' && *s <= 'F' ) + c = 16 * (10 + *s - 'A'); + else if ( *s >= 'a' && *s <= 'f' ) + c = 16 * (10 + *s - 'a'); + else + return -1; + s++; + if ( *s >= '0' && *s <= '9' ) + c += *s - '0'; + else if ( *s >= 'A' && *s <= 'F' ) + c += 10 + *s - 'A'; + else if ( *s >= 'a' && *s <= 'f' ) + c += 10 + *s - 'a'; + else + return -1; + return c; +} + + /* Print a BUFFER to stream FP while replacing all control characters - and the character DELIM with standard C escape sequences. Returns - the number of characters printed. */ + and the characters DELIM and DELIM2 with standard C escape + sequences. Returns the number of characters printed. */ size_t -print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, - int delim) +print_sanitized_buffer2 (FILE *fp, const void *buffer, size_t length, + int delim, int delim2) { const unsigned char *p = buffer; size_t count = 0; for (; length; length--, p++, count++) { - if (*p < 0x20 || *p == 0x7f || *p == delim) + /* Fixme: Check whether *p < 0xa0 is correct for utf8 encoding. */ + if (*p < 0x20 + || (*p >= 0x7f && *p < 0xa0) + || *p == delim + || *p == delim2 + || ((delim || delim2) && *p=='\\')) { putc ('\\', fp); count++; if (*p == '\n') - putc ('n', fp); + { + putc ('n', fp); + count++; + } else if (*p == '\r') - putc ('r', fp); + { + putc ('r', fp); + count++; + } else if (*p == '\f') - putc ('f', fp); + { + putc ('f', fp); + count++; + } else if (*p == '\v') - putc ('v', fp); + { + putc ('v', fp); + count++; + } else if (*p == '\b') - putc ('b', fp); + { + putc ('b', fp); + count++; + } else if (!*p) - putc('0', fp); + { + putc('0', fp); + count++; + } else { fprintf (fp, "x%02x", *p); @@ -371,12 +423,24 @@ print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, } } else - putc (*p, fp); + { + putc (*p, fp); + count++; + } } return count; } +/* Same as print_sanitized_buffer2 but with just one delimiter. */ +size_t +print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, + int delim) +{ + return print_sanitized_buffer2 (fp, buffer, length, delim, 0); +} + + size_t print_sanitized_utf8_buffer (FILE *fp, const void *buffer, size_t length, int delim) @@ -404,6 +468,13 @@ print_sanitized_utf8_buffer (FILE *fp, const void *buffer, } +size_t +print_sanitized_string2 (FILE *fp, const char *string, int delim, int delim2) +{ + return string? print_sanitized_buffer2 (fp, string, strlen (string), + delim, delim2):0; +} + size_t print_sanitized_string (FILE *fp, const char *string, int delim) { diff --git a/jnlib/stringhelp.h b/jnlib/stringhelp.h index 4c9e66452..405d6dbc4 100644 --- a/jnlib/stringhelp.h +++ b/jnlib/stringhelp.h @@ -40,11 +40,17 @@ char *make_dirname(const char *filepath); char *make_filename( const char *first_part, ... ); int compare_filenames( const char *a, const char *b ); +int hextobyte (const char *s); + size_t print_sanitized_buffer (FILE *fp, const void *buffer, size_t length, int delim); +size_t print_sanitized_buffer2 (FILE *fp, const void *buffer, size_t length, + int delim, int delim2); size_t print_sanitized_utf8_buffer (FILE *fp, const void *buffer, size_t length, int delim); size_t print_sanitized_string (FILE *fp, const char *string, int delim); +size_t print_sanitized_string2 (FILE *fp, const char *string, + int delim, int delim2); size_t print_sanitized_utf8_string (FILE *fp, const char *string, int delim); char *sanitize_buffer (const void *p, size_t n, int delim); diff --git a/jnlib/strlist.c b/jnlib/strlist.c index d1924c102..52b4d5869 100644 --- a/jnlib/strlist.c +++ b/jnlib/strlist.c @@ -95,22 +95,24 @@ append_to_strlist( strlist_t *list, const char *string ) return sl; } -#if 0 + +#ifdef JNLIB_NEED_UTF8CONV strlist_t append_to_strlist2( strlist_t *list, const char *string, int is_utf8 ) { - strlist_t sl; - - if( is_utf8 ) - sl = append_to_strlist( list, string ); - else { - char *p = native_to_utf8( string ); - sl = append_to_strlist( list, p ); - m_free( p ); + strlist_t sl; + + if( is_utf8 ) + sl = append_to_strlist( list, string ); + else + { + char *p = native_to_utf8 (string); + sl = append_to_strlist( list, p ); + jnlib_free( p ); } - return sl; + return sl; } -#endif +#endif /* JNLIB_NEED_UTF8CONV */ /* Return a copy of LIST. */ diff --git a/jnlib/strlist.h b/jnlib/strlist.h index 47ac5bd4e..3c1252a44 100644 --- a/jnlib/strlist.h +++ b/jnlib/strlist.h @@ -35,11 +35,11 @@ strlist_t add_to_strlist (strlist_t *list, const char *string); strlist_t add_to_strlist2( strlist_t *list, const char *string, int is_utf8); strlist_t append_to_strlist (strlist_t *list, const char *string); +strlist_t append_to_strlist2 (strlist_t *list, const char *string, + int is_utf8); strlist_t strlist_copy (strlist_t list); -/*strlist_t append_to_strlist2( strlist_t *list, const char *string, - int is_utf8);*/ strlist_t strlist_prev (strlist_t head, strlist_t node); strlist_t strlist_last (strlist_t node); char * strlist_pop (strlist_t *list); diff --git a/scd/app-p15.c b/scd/app-p15.c index 8bb94cfcd..4203a6840 100644 --- a/scd/app-p15.c +++ b/scd/app-p15.c @@ -18,6 +18,16 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ +/* Information pertaining to the BELPIC developer card samples: + + Unblock PUK: "222222111111" + Reset PIN: "333333111111") + + e.g. the APDUs 00:20:00:02:08:2C:33:33:33:11:11:11:FF + and 00:24:01:01:08:24:12:34:FF:FF:FF:FF:FF + should change the PIN into 1234. +*/ + #include #include #include diff --git a/sm/ChangeLog b/sm/ChangeLog index f161d444c..48e8473fa 100644 --- a/sm/ChangeLog +++ b/sm/ChangeLog @@ -1,3 +1,9 @@ +2006-05-23 Werner Koch + + * keydb.c (hextobyte): Deleted as it is now defined in jnlib. + + * Makefile.am (gpgsm_LDADD): Include ZLIBS. + 2006-05-19 Marcus Brinkmann * keydb.c (keydb_insert_cert): Do not lock here, but only check if @@ -9,6 +15,10 @@ * delete.c (delete_one): Add new argument to invocation of keydb_delete. +2006-05-15 Werner Koch + + * keylist.c (print_names_raw): Sanitize URI. + 2006-03-21 Werner Koch * certchain.c (get_regtp_ca_info): New. diff --git a/sm/Makefile.am b/sm/Makefile.am index aba2081f8..b5882ae1d 100644 --- a/sm/Makefile.am +++ b/sm/Makefile.am @@ -56,6 +56,6 @@ gpgsm_SOURCES = \ gpgsm_LDADD = ../jnlib/libjnlib.a ../kbx/libkeybox.a \ ../common/libcommon.a ../gl/libgnu.a \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) -lgpg-error \ - $(LIBINTL) $(PTH_LIBS) + $(LIBINTL) $(PTH_LIBS) $(ZLIBS) diff --git a/sm/keydb.c b/sm/keydb.c index 15f5dbdac..d5932135d 100644 --- a/sm/keydb.c +++ b/sm/keydb.c @@ -1009,33 +1009,6 @@ keydb_search_subject (KEYDB_HANDLE hd, const char *name) } -static int -hextobyte (const char *string) -{ - const unsigned char *s = (const unsigned char *)string; - int c; - - if( *s >= '0' && *s <= '9' ) - c = 16 * (*s - '0'); - else if ( *s >= 'A' && *s <= 'F' ) - c = 16 * (10 + *s - 'A'); - else if ( *s >= 'a' && *s <= 'f' ) - c = 16 * (10 + *s - 'a'); - else - return -1; - s++; - if ( *s >= '0' && *s <= '9' ) - c += *s - '0'; - else if ( *s >= 'A' && *s <= 'F' ) - c += 10 + *s - 'A'; - else if ( *s >= 'a' && *s <= 'f' ) - c += 10 + *s - 'a'; - else - return -1; - return c; -} - - static int classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc, diff --git a/sm/keylist.c b/sm/keylist.c index 51a066dab..b744a157f 100644 --- a/sm/keylist.c +++ b/sm/keylist.c @@ -529,7 +529,9 @@ print_names_raw (FILE *fp, int indent, ksba_name_t name) for (idx=0; (s = ksba_name_enum (name, idx)); idx++) { char *p = ksba_name_get_uri (name, idx); - printf ("%*s%s\n", idx||indent_all?indent:0, "", p?p:s); + printf ("%*s", idx||indent_all?indent:0, ""); + print_sanitized_string (fp, p?p:s, 0); + putc ('\n', fp); xfree (p); } } diff --git a/tools/ChangeLog b/tools/ChangeLog index 67dcbd860..4ac20ae0b 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,11 @@ +2006-05-23 Werner Koch + + * gpgparsemail.c: Include config.h if available + (stpcpy): Conditional include it. + + * gpgconf-comp.c (hextobyte): Removed as it is now availble in + jnlib. + 2005-12-20 Werner Koch * gpgconf-comp.c (gc_options_gpg): Add allow-pka-lookup. diff --git a/tools/gpgconf-comp.c b/tools/gpgconf-comp.c index a27da3941..2da88bc49 100644 --- a/tools/gpgconf-comp.c +++ b/tools/gpgconf-comp.c @@ -998,34 +998,6 @@ percent_escape (const char *src) } -/* Convert two hexadecimal digits from STR to the value they - represent. Returns -1 if one of the characters is not a - hexadecimal digit. */ -static int -hextobyte (const char *str) -{ - int val = 0; - int i; - -#define NROFHEXDIGITS 2 - for (i = 0; i < NROFHEXDIGITS; i++) - { - if (*str >= '0' && *str <= '9') - val += *str - '0'; - else if (*str >= 'A' && *str <= 'F') - val += 10 + *str - 'A'; - else if (*str >= 'a' && *str <= 'f') - val += 10 + *str - 'a'; - else - return -1; - if (i < NROFHEXDIGITS - 1) - val *= 16; - str++; - } - return val; -} - - /* Percent-Deescape special characters. The string is valid until the next invocation of the function. */ diff --git a/tools/gpgparsemail.c b/tools/gpgparsemail.c index da56093c3..566f5747f 100644 --- a/tools/gpgparsemail.c +++ b/tools/gpgparsemail.c @@ -24,6 +24,9 @@ for the content of the line. Several options are available to scrutinize the message. S/MIME and OpenPGP support is included. */ +#ifdef HAVE_CONFIG_H +#include +#endif #include #include @@ -145,6 +148,7 @@ xstrdup (const char *string) return p; } +#ifndef HAVE_STPCPY static char * stpcpy (char *a,const char *b) { @@ -154,7 +158,7 @@ stpcpy (char *a,const char *b) return (char*)a; } - +#endif static int run_gnupg (int smime, int sig_fd, int data_fd, int *close_list)