From cvs at cvs.gnupg.org Wed Jul 1 12:53:03 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 01 Jul 2009 12:53:03 +0200 Subject: [svn] GnuPG - r5060 - trunk/scd Message-ID: Author: wk Date: 2009-07-01 12:53:02 +0200 (Wed, 01 Jul 2009) New Revision: 5060 Modified: trunk/scd/ccid-driver.c Log: Add comment about Cherry. Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2009-06-30 11:29:03 UTC (rev 5059) +++ trunk/scd/ccid-driver.c 2009-07-01 10:53:02 UTC (rev 5060) @@ -2615,7 +2615,11 @@ /* We employ a hack for Omnikey readers which are able to send TPDUs using an escape sequence. There is no documentation but the Windows driver does it this way. Tested using a - CM6121. */ + CM6121. This method works also for the Cherry XX44 + keyboards; however there are problems with the + ccid_tranceive_secure which leads to a loss of sync on the + CCID level. If Cherry wants to make their keyboard work + again, they should hand over some docs. */ if ((handle->id_vendor == VENDOR_OMNIKEY || (!handle->idev && handle->id_product == TRANSPORT_CM4040)) && handle->apdu_level < 2 @@ -3154,7 +3158,7 @@ } } else - { /* This is a S-bl Author: wk Date: 2009-07-01 16:42:34 +0200 (Wed, 01 Jul 2009) New Revision: 308 Modified: trunk/NEWS trunk/src/ChangeLog trunk/src/dn.c Log: Handle BER encoded DNs. Those are not very useful but in some context allowed. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-06-29 13:40:07 UTC (rev 307) +++ trunk/src/ChangeLog 2009-07-01 14:42:34 UTC (rev 308) @@ -1,3 +1,8 @@ +2009-07-01 Werner Koch + + * dn.c (oid_name_tbl): Add dotted string representation of OIDs. + (append_atv): Try to match BER encoded OIDs. + 2009-06-29 Werner Koch * oid.c (ksba_oid_to_str): Add an overflow check so that we can Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-06-29 13:40:07 UTC (rev 307) +++ trunk/NEWS 2009-07-01 14:42:34 UTC (rev 308) @@ -1,7 +1,8 @@ Noteworthy changes in version 1.0.7 ------------------------------------------------ - * Detect overflow while parsing OIDs. + * Detect overflow while parsing OIDs. Map BER encoded OIDs to well + known names. Noteworthy changes in version 1.0.6 (2009-06-05) Modified: trunk/src/dn.c =================================================================== --- trunk/src/dn.c 2009-06-29 13:40:07 UTC (rev 307) +++ trunk/src/dn.c 2009-07-01 14:42:34 UTC (rev 308) @@ -40,37 +40,31 @@ */ const char *description; size_t oidlen; - const unsigned char *oid; + const unsigned char *oid; /* DER encoded OID. */ + const char *oidstr; /* OID as dotted string. */ } oid_name_tbl[] = { -{"CN", 1, "CommonName", 3, "\x55\x04\x03"}, /* 2.5.4.3 */ -{"SN", 2, "Surname", 3, "\x55\x04\x04"}, /* 2.5.4.4 */ -{"SERIALNUMBER", 2, "SerialNumber",3, "\x55\x04\x05"}, /* 2.5.4.5 */ -{"C", 1, "CountryName", 3, "\x55\x04\x06"}, /* 2.5.4.6 */ -{"L" , 1, "LocalityName", 3, "\x55\x04\x07"}, /* 2.5.4.7 */ -{"ST", 1, "StateOrProvince", 3, "\x55\x04\x08"}, /* 2.5.4.8 */ -{"STREET", 1, "StreetAddress", 3, "\x55\x04\x09"}, /* 2.5.4.9 */ -{"O", 1, "OrganizationName", 3, "\x55\x04\x0a"}, /* 2.5.4.10 */ -{"OU", 1, "OrganizationalUnit", 3, "\x55\x04\x0b"}, /* 2.5.4.11 */ -{"T", 2, "Title", 3, "\x55\x04\x0c"}, /* 2.5.4.12 */ -{"D", - 3, "Description", 3, "\x55\x04\x0d"}, /* 2.5.4.13 */ -{"BC", - 3, "BusinessCategory", 3, "\x55\x04\x0f"}, /* 2.5.4.15 */ -{"ADDR", - 2, "PostalAddress", 3, "\x55\x04\x11"}, /* 2.5.4.16 */ -{"POSTALCODE" , 0, "PostalCode", 3, "\x55\x04\x11"}, /* 2.5.4.17 */ -{"GN", 2, "GivenName", 3, "\x55\x04\x2a"}, /* 2.5.4.42 */ -{"PSEUDO", 2, "Pseudonym", 3, "\x55\x04\x41"}, /* 2.5.4.65 */ +{"CN", 1, "CommonName", 3, "\x55\x04\x03", "2.5.4.3" }, +{"SN", 2, "Surname", 3, "\x55\x04\x04", "2.5.4.4" }, +{"SERIALNUMBER", 2, "SerialNumber",3, "\x55\x04\x05", "2.5.4.5" }, +{"C", 1, "CountryName", 3, "\x55\x04\x06", "2.5.4.6" }, +{"L" , 1, "LocalityName", 3, "\x55\x04\x07", "2.5.4.7" }, +{"ST", 1, "StateOrProvince", 3, "\x55\x04\x08", "2.5.4.8" }, +{"STREET", 1, "StreetAddress", 3, "\x55\x04\x09", "2.5.4.9" }, +{"O", 1, "OrganizationName", 3, "\x55\x04\x0a", "2.5.4.10" }, +{"OU", 1, "OrganizationalUnit", 3, "\x55\x04\x0b", "2.5.4.11" }, +{"T", 2, "Title", 3, "\x55\x04\x0c", "2.5.4.12" }, +{"D", 3, "Description", 3, "\x55\x04\x0d", "2.5.4.13" }, +{"BC", 3, "BusinessCategory", 3, "\x55\x04\x0f", "2.5.4.15" }, +{"ADDR", 2, "PostalAddress", 3, "\x55\x04\x11", "2.5.4.16" }, +{"POSTALCODE" , 0, "PostalCode", 3, "\x55\x04\x11", "2.5.4.17" }, +{"GN", 2, "GivenName", 3, "\x55\x04\x2a", "2.5.4.42" }, +{"PSEUDO", 2, "Pseudonym", 3, "\x55\x04\x41", "2.5.4.65" }, {"DC", 1, "domainComponent", 10, - "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19"}, - /* 0.9.2342.19200300.100.1.25 */ + "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x19", "0.9.2342.19200300.100.1.25" }, {"UID", 1, "userid", 10, - "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x01"}, - /* 0.9.2342.19200300.100.1.1 */ - -{"EMAIL", 3, "emailAddress", 9, - "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01" }, /* 1.2.840.113549.1.9.1 */ - + "\x09\x92\x26\x89\x93\xF2\x2C\x64\x01\x01", "0.9.2342.19200300.100.1.1 " }, +{"EMAIL", 3, "emailAddress", 9, + "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01", "1.2.840.113549.1.9.1" }, { NULL } }; @@ -555,13 +549,32 @@ if (name) put_stringbuf (sb, name); else - { /* No name in table: use the oid */ - char *p = ksba_oid_to_str (image+node->off+node->nhdr, node->len); + { /* No name for the OID in the table; at least not DER encoded. + Now convert the OID to a string, try to find it in the table + again and use the string as last resort. */ + char *p; + + p = ksba_oid_to_str (image+node->off+node->nhdr, node->len); if (!p) return gpg_error (GPG_ERR_ENOMEM); - put_stringbuf (sb, p); + + for (i=0; *p && oid_name_tbl[i].name; i++) + { + if (oid_name_tbl[i].source == 1 + && !strcmp (p, oid_name_tbl[i].oidstr)) + { + name = oid_name_tbl[i].name; + break; + } + } + if (name) + put_stringbuf (sb, name); + else + { + put_stringbuf (sb, p); + use_hex = 1; + } xfree (p); - use_hex = 1; } put_stringbuf (sb, "="); node = node->right; From cvs at cvs.gnupg.org Wed Jul 1 20:30:33 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 01 Jul 2009 20:30:33 +0200 Subject: [svn] GnuPG - r5061 - in trunk: . common doc sm tools Message-ID: Author: wk Date: 2009-07-01 20:30:33 +0200 (Wed, 01 Jul 2009) New Revision: 5061 Modified: trunk/NEWS trunk/common/ChangeLog trunk/common/sexputil.c trunk/common/util.h trunk/doc/gpgsm.texi trunk/sm/ChangeLog trunk/sm/certreqgen-ui.c trunk/sm/gpgsm.c trunk/tools/ChangeLog trunk/tools/ccidmon.c Log: Alow batch ode for gpgsm --gen-key. Allow CSR generation using an existing key with gpgsm. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-07-01 10:53:02 UTC (rev 5060) +++ trunk/common/ChangeLog 2009-07-01 18:30:33 UTC (rev 5061) @@ -1,3 +1,7 @@ +2009-07-01 Werner Koch + + * sexputil.c (get_pk_algo_from_canon_sexp): New. + 2009-06-29 Werner Koch * estream.c (BUFFER_ROUND_TO_BLOCK): Remove unused macro. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-07-01 10:53:02 UTC (rev 5060) +++ trunk/sm/ChangeLog 2009-07-01 18:30:33 UTC (rev 5061) @@ -1,3 +1,11 @@ +2009-07-01 Werner Koch + + * certreqgen-ui.c (check_keygrip): New. + (gpgsm_gencertreq_tty): Allow using an existing key. + + * gpgsm.c (open_es_fread): New. + (main) : Implement --batch mode. + 2009-06-24 Werner Koch * call-dirmngr.c (pattern_from_strlist): Remove dead assignment of N. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2009-07-01 10:53:02 UTC (rev 5060) +++ trunk/tools/ChangeLog 2009-07-01 18:30:33 UTC (rev 5061) @@ -1,3 +1,7 @@ +2009-06-30 Werner Koch + + * ccidmon.c (parse_line_sniffusb): Take also TAB as delimiter. + 2009-06-29 Werner Koch * ccidmon.c (parse_line_sniffusb): New. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-07-01 10:53:02 UTC (rev 5060) +++ trunk/NEWS 2009-07-01 18:30:33 UTC (rev 5061) @@ -3,9 +3,11 @@ This is a BETA version! - * + * Minor bnug fixes + * gpgsm --gen-key now implements a --batch mode. + Noteworthy changes in version 2.0.12 (2009-06-17) ------------------------------------------------- Modified: trunk/common/sexputil.c =================================================================== --- trunk/common/sexputil.c 2009-07-01 10:53:02 UTC (rev 5060) +++ trunk/common/sexputil.c 2009-07-01 18:30:33 UTC (rev 5061) @@ -292,14 +292,8 @@ } -/* Return the so called "keygrip" which is the SHA-1 hash of the - public key parameters expressed in a way depended on the algorithm. - - KEY is expected to be an canonical encoded S-expression with a - public or private key. KEYLEN is the length of that buffer. - - GRIP must be at least 20 bytes long. On success 0 is returned, on - error an error code. */ +/* Return the so parameters of a public RSA key expressed as an + canonical encoded S-expression. */ gpg_error_t get_rsa_pk_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, unsigned char const **r_n, size_t *r_nlen, @@ -389,3 +383,47 @@ *r_elen = rsa_e_len; return 0; } + + +/* Return the algo of a public RSA expressed as an canonical encoded + S-expression. On error the algo is set to 0. */ +gpg_error_t +get_pk_algo_from_canon_sexp (const unsigned char *keydata, size_t keydatalen, + int *r_algo) +{ + gpg_error_t err; + const unsigned char *buf, *tok; + size_t buflen, toklen; + int depth; + + *r_algo = 0; + + buf = keydata; + buflen = keydatalen; + depth = 0; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (!tok || toklen != 10 || memcmp ("public-key", tok, toklen)) + return gpg_error (GPG_ERR_BAD_PUBKEY); + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if ((err = parse_sexp (&buf, &buflen, &depth, &tok, &toklen))) + return err; + if (!tok) + return gpg_error (GPG_ERR_BAD_PUBKEY); + + if (toklen == 3 && !memcmp ("rsa", tok, toklen)) + *r_algo = GCRY_PK_RSA; + else if (toklen == 3 && !memcmp ("dsa", tok, toklen)) + *r_algo = GCRY_PK_DSA; + else if (toklen == 3 && !memcmp ("elg", tok, toklen)) + *r_algo = GCRY_PK_ELG; + else if (toklen == 5 && !memcmp ("ecdsa", tok, toklen)) + *r_algo = GCRY_PK_ECDSA; + else + return gpg_error (GPG_ERR_PUBKEY_ALGO); + + return 0; +} Modified: trunk/common/util.h =================================================================== --- trunk/common/util.h 2009-07-01 10:53:02 UTC (rev 5060) +++ trunk/common/util.h 2009-07-01 18:30:33 UTC (rev 5061) @@ -201,6 +201,9 @@ size_t *r_nlen, unsigned char const **r_e, size_t *r_elen); +gpg_error_t get_pk_algo_from_canon_sexp (const unsigned char *keydata, + size_t keydatalen, + int *r_algo); /*-- convert.c --*/ int hex2bin (const char *string, void *buffer, size_t length); Modified: trunk/doc/gpgsm.texi =================================================================== --- trunk/doc/gpgsm.texi 2009-07-01 10:53:02 UTC (rev 5060) +++ trunk/doc/gpgsm.texi 2009-07-01 18:30:33 UTC (rev 5061) @@ -165,9 +165,10 @@ @table @gnupgtabopt @item --gen-key @opindex gen-key -This command allows the interactive creation of a certifcate signing -request. It is commonly used along with the @option{--output} option to -save the created CSR into a file. +This command allows the creation of a certificate signing request. It +is commonly used along with the @option{--output} option to save the +created CSR into a file. If used with the @option{--batch} the signing +is requested from a parameter file. @item --list-keys @itemx -k Modified: trunk/sm/certreqgen-ui.c =================================================================== --- trunk/sm/certreqgen-ui.c 2009-07-01 10:53:02 UTC (rev 5060) +++ trunk/sm/certreqgen-ui.c 2009-07-01 18:30:33 UTC (rev 5061) @@ -86,6 +86,39 @@ } +/* Chech whether we have a key for the key with HEXGRIP. Returns NULL + if not or a string describing the type of the key (RSA, ELG, DSA, + etc..). */ +static const char * +check_keygrip (ctrl_t ctrl, const char *hexgrip) +{ + gpg_error_t err; + ksba_sexp_t public; + size_t publiclen; + int algo; + + if (hexgrip[0] == '0' && hexgrip[1] == 'x') + hexgrip += 2; + + err = gpgsm_agent_readkey (ctrl, 0, hexgrip, &public); + if (err) + return NULL; + publiclen = gcry_sexp_canon_len (public, 0, NULL, NULL); + + get_pk_algo_from_canon_sexp (public, publiclen, &algo); + xfree (public); + + switch (algo) + { + case GCRY_PK_RSA: return "RSA"; + case GCRY_PK_DSA: return "DSA"; + case GCRY_PK_ELG: return "ELG"; + case GCRY_PK_ECDSA: return "ECDSA"; + default: return NULL; + } +} + + /* This function is used to create a certificate request from the command line. In the past the similar gpgsm-gencert.sh script has been used for it; however that scripts requires a full Unix shell @@ -99,7 +132,7 @@ int selection; estream_t fp = NULL; int method; - char *keytype; + const char *keytype; char *keygrip = NULL; unsigned int nbits; int minbits = 1024; @@ -112,11 +145,13 @@ int i; const char *s, *s2; + answer = NULL; init_membuf (&mb_email, 100); init_membuf (&mb_dns, 100); init_membuf (&mb_uri, 100); init_membuf (&mb_result, 512); + again: /* Get the type of the key. */ tty_printf (_("Please select what kind of key you want:\n")); tty_printf (_(" (%d) RSA\n"), 1 ); @@ -125,10 +160,10 @@ do { + xfree (answer); answer = tty_get (_("Your selection? ")); tty_kill_prompt (); selection = *answer? atoi (answer): 1; - xfree (answer); } while (!(selection >= 1 && selection <= 3)); method = selection; @@ -136,13 +171,14 @@ /* Get size of the key. */ if (method == 1) { - keytype = xstrdup ("RSA"); + keytype = "RSA"; for (;;) { + xfree (answer); answer = tty_getf (_("What keysize do you want? (%u) "), defbits); tty_kill_prompt (); + trim_spaces (answer); nbits = *answer? atoi (answer): defbits; - xfree (answer); if (nbits < minbits || nbits > maxbits) tty_printf(_("%s keysizes must be in the range %u-%u\n"), "RSA", minbits, maxbits); @@ -159,17 +195,34 @@ } else if (method == 2) { - tty_printf ("Not yet supported; " - "use the gpgsm-gencert.sh script instead\n"); - keytype = xstrdup ("RSA"); - nbits = defbits; /* We need a dummy value. */ + for (;;) + { + xfree (answer); + answer = tty_get (_("Enter the keygrip: ")); + tty_kill_prompt (); + trim_spaces (answer); + + if (!*answer) + goto again; + else if (strlen (answer) != 40 && + !(answer[0] == '0' && answer[1] == 'x' + && strlen (answer+2) == 40)) + tty_printf (_("Not a valid keygrip (expecting 40 hex digits)\n")); + else if (!(keytype = check_keygrip (ctrl, answer)) ) + tty_printf (_("No key with this keygrip\n")); + else + break; /* Okay. */ + } + nbits = 1024; /* A dummy value is sufficient. */ + xfree (keygrip); + keygrip = answer; + answer = NULL; } else /* method == 3 */ { tty_printf ("Not yet supported; " "use the gpgsm-gencert.sh script instead\n"); - keytype = xstrdup ("card:foobar"); - nbits = defbits; /* We need a dummy value. */ + goto again; } /* Ask for the key usage. */ @@ -179,10 +232,11 @@ tty_printf (_(" (%d) encrypt\n"), 3 ); do { + xfree (answer); answer = tty_get (_("Your selection? ")); tty_kill_prompt (); + trim_spaces (answer); selection = *answer? atoi (answer): 1; - xfree (answer); switch (selection) { case 1: keyusage = "sign, encrypt"; break; @@ -194,7 +248,6 @@ while (!keyusage); /* Get the subject name. */ - answer = NULL; do { size_t erroff, errlen; @@ -303,7 +356,7 @@ log_error (_("resource problem: out of core\n")); leave: es_fclose (fp); - xfree (keytype); + xfree (answer); xfree (subject_name); xfree (keygrip); xfree (get_membuf (&mb_email, NULL)); Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2009-07-01 10:53:02 UTC (rev 5060) +++ trunk/sm/gpgsm.c 2009-07-01 18:30:33 UTC (rev 5061) @@ -417,6 +417,7 @@ static void emergency_cleanup (void); static int check_special_filename (const char *fname, int for_write); static int open_read (const char *filename); +static estream_t open_es_fread (const char *filename); static FILE *open_fwrite (const char *filename); static estream_t open_es_fwrite (const char *filename); static void run_protect_tool (int argc, char **argv); @@ -1770,10 +1771,28 @@ case aKeygen: /* Generate a key; well kind of. */ { - FILE *fp = open_fwrite (opt.outfile?opt.outfile:"-"); - gpgsm_gencertreq_tty (&ctrl, fp); - if (fp != stdout) - fclose (fp); + estream_t fpin = NULL; + FILE *fpout; + + if (opt.batch) + { + if (!argc) /* Create from stdin. */ + fpin = open_es_fread ("-"); + else if (argc == 1) /* From file. */ + fpin = open_es_fread (*argv); + else + wrong_args ("--gen-key --batch [parmfile]"); + } + + fpout = open_fwrite (opt.outfile?opt.outfile:"-"); + + if (fpin) + gpgsm_genkey (&ctrl, fpin, fpout); + else + gpgsm_gencertreq_tty (&ctrl, fpout); + + if (fpout != stdout) + fclose (fpout); } break; @@ -1976,6 +1995,37 @@ return fd; } +/* Same as open_read but return an estream_t. */ +static estream_t +open_es_fread (const char *filename) +{ + int fd; + estream_t fp; + + if (filename[0] == '-' && !filename[1]) + fd = fileno (stdin); + else + fd = check_special_filename (filename, 0); + if (fd != -1) + { + fp = es_fdopen_nc (fd, "rb"); + if (!fp) + { + log_error ("es_fdopen(%d) failed: %s\n", fd, strerror (errno)); + gpgsm_exit (2); + } + return fp; + } + fp = es_fopen (filename, "rb"); + if (!fp) + { + log_error (_("can't open `%s': %s\n"), filename, strerror (errno)); + gpgsm_exit (2); + } + return fp; +} + + /* Open FILENAME for fwrite and return the stream. Stop with an error message in case of problems. "-" denotes stdout and if special filenames are allowed the given fd is opened instead. Caller must Modified: trunk/tools/ccidmon.c =================================================================== --- trunk/tools/ccidmon.c 2009-07-01 10:53:02 UTC (rev 5060) +++ trunk/tools/ccidmon.c 2009-07-01 18:30:33 UTC (rev 5061) @@ -702,13 +702,13 @@ if (debug) printf ("line[%u] =`%s'\n", lineno, line); - p = strtok (line, " "); + p = strtok (line, " \t"); if (!p) return; - p = strtok (NULL, " "); + p = strtok (NULL, " \t"); if (!p) return; - p = strtok (NULL, " "); + p = strtok (NULL, " \t"); if (!p) return; @@ -720,7 +720,7 @@ unsigned int value; length = databuffer.count; - while ((p=strtok (NULL, " "))) + while ((p=strtok (NULL, " \t"))) { if (!hexdigitp (p[0]) || !hexdigitp (p[1])) { @@ -745,7 +745,7 @@ flush_data (); *databuffer.address = 0; - while ((p=strtok (NULL, " (,)"))) + while ((p=strtok (NULL, " \t(,)"))) { if (!strcmp (p, "USBD_TRANSFER_DIRECTION_IN")) { From cvs at cvs.gnupg.org Thu Jul 2 10:15:41 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 02 Jul 2009 10:15:41 +0200 Subject: [svn] ksba - r309 - in trunk: . src Message-ID: Author: wk Date: 2009-07-02 10:15:41 +0200 (Thu, 02 Jul 2009) New Revision: 309 Modified: trunk/NEWS trunk/src/ChangeLog trunk/src/dn.c trunk/src/util.c trunk/src/util.h Log: Allow mixed cased names in DNs. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-07-01 14:42:34 UTC (rev 308) +++ trunk/src/ChangeLog 2009-07-02 08:15:41 UTC (rev 309) @@ -1,3 +1,8 @@ +2009-07-02 Werner Koch + + * util.c (_ksba_ascii_memcasecmp, ascii_toupper): New. + * dn.c (parse_rdn): Use it + 2009-07-01 Werner Koch * dn.c (oid_name_tbl): Add dotted string representation of OIDs. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-07-01 14:42:34 UTC (rev 308) +++ trunk/NEWS 2009-07-02 08:15:41 UTC (rev 309) @@ -4,7 +4,9 @@ * Detect overflow while parsing OIDs. Map BER encoded OIDs to well known names. + * Allow mixed case names in DNs. + Noteworthy changes in version 1.0.6 (2009-06-05) ------------------------------------------------ Modified: trunk/src/dn.c =================================================================== --- trunk/src/dn.c 2009-07-01 14:42:34 UTC (rev 308) +++ trunk/src/dn.c 2009-07-02 08:15:41 UTC (rev 309) @@ -984,7 +984,7 @@ for (i=0; oid_name_tbl[i].name; i++) { if ( n == strlen (oid_name_tbl[i].name) - && !memcmp (string, oid_name_tbl[i].name, n)) + && !ascii_memcasecmp (string, oid_name_tbl[i].name, n)) break; } if (!oid_name_tbl[i].name) Modified: trunk/src/util.c =================================================================== --- trunk/src/util.c 2009-07-01 14:42:34 UTC (rev 308) +++ trunk/src/util.c 2009-07-02 08:15:41 UTC (rev 309) @@ -1,5 +1,5 @@ /* util.c - * Copyright (C) 2001 g10 Code GmbH + * Copyright (C) 2001, 2009 g10 Code GmbH * * This file is part of KSBA. * @@ -222,3 +222,29 @@ } #endif + +static inline int +ascii_toupper (int c) +{ + if (c >= 'a' && c <= 'z') + c &= ~0x20; + return c; +} + + +int +_ksba_ascii_memcasecmp (const void *a_arg, const void *b_arg, size_t n) +{ + const char *a = a_arg; + const char *b = b_arg; + + if (a == b) + return 0; + for ( ; n; n--, a++, b++ ) + { + if (*a != *b && ascii_toupper (*a) != ascii_toupper (*b)) + return *a == *b? 0 : (ascii_toupper (*a) - ascii_toupper (*b)); + } + return 0; +} + Modified: trunk/src/util.h =================================================================== --- trunk/src/util.h 2009-07-01 14:42:34 UTC (rev 308) +++ trunk/src/util.h 2009-07-02 08:15:41 UTC (rev 309) @@ -1,5 +1,5 @@ /* util.h - * Copyright (C) 2001 g10 Code GmbH + * Copyright (C) 2001, 2009 g10 Code GmbH * * This file is part of KSBA. * @@ -84,6 +84,9 @@ #define stpcpy(a,b) _ksba_stpcpy ((a), (b)) #endif +int _ksba_ascii_memcasecmp (const void *a_arg, const void *b_arg, size_t n); +#define ascii_memcasecmp(a,b,n) _ksba_ascii_memcasecmp ((a),(b),(n)) + /* some macros to replace ctype ones and avoid locale problems */ #define spacep(p) (*(p) == ' ' || *(p) == '\t') #define digitp(p) (*(p) >= '0' && *(p) <= '9') From cvs at cvs.gnupg.org Thu Jul 2 11:49:32 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 02 Jul 2009 11:49:32 +0200 Subject: [svn] GnuPG - r5062 - in trunk: . sm tools Message-ID: Author: wk Date: 2009-07-02 11:49:31 +0200 (Thu, 02 Jul 2009) New Revision: 5062 Modified: trunk/NEWS trunk/sm/ChangeLog trunk/sm/call-agent.c trunk/sm/certreqgen-ui.c trunk/sm/gpgsm.h trunk/tools/gpgsm-gencert.sh Log: Create a pkcs#10 request directly from a card. Deprecate gpgsm-gencert.sh script. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-07-01 18:30:33 UTC (rev 5061) +++ trunk/sm/ChangeLog 2009-07-02 09:49:31 UTC (rev 5062) @@ -1,3 +1,11 @@ +2009-07-02 Werner Koch + + * certreqgen-ui.c (gpgsm_gencertreq_tty): Allow using a key from a + card. + * call-agent.c (gpgsm_agent_scd_serialno) + (scd_serialno_status_cb, store_serialno): New. + (scd_keypairinfo_status_cb, gpgsm_agent_scd_keypairinfo): New. + 2009-07-01 Werner Koch * certreqgen-ui.c (check_keygrip): New. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-07-01 18:30:33 UTC (rev 5061) +++ trunk/NEWS 2009-07-02 09:49:31 UTC (rev 5062) @@ -3,11 +3,13 @@ This is a BETA version! - * Minor bnug fixes + * Minor bug fixes. - * gpgsm --gen-key now implements a --batch mode. + * gpgsm --gen-key implements a --batch mode. + * gpgsm --gen-key implements all features of gpgsm-gencert.sh. + Noteworthy changes in version 2.0.12 (2009-06-17) ------------------------------------------------- Modified: trunk/sm/call-agent.c =================================================================== --- trunk/sm/call-agent.c 2009-07-01 18:30:33 UTC (rev 5061) +++ trunk/sm/call-agent.c 2009-07-02 09:49:31 UTC (rev 5062) @@ -538,9 +538,151 @@ return 0; } + +/* Take the serial number from LINE and return it verbatim in a newly + allocated string. We make sure that only hex characters are + returned. */ +static char * +store_serialno (const char *line) +{ + const char *s; + char *p; + for (s=line; hexdigitp (s); s++) + ; + p = xtrymalloc (s + 1 - line); + if (p) + { + memcpy (p, line, s-line); + p[s-line] = 0; + } + return p; +} + + +/* Callback for the gpgsm_agent_serialno fucntion. */ static int +scd_serialno_status_cb (void *opaque, const char *line) +{ + char **r_serialno = opaque; + const char *keyword = line; + int keywordlen; + + for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) + ; + while (spacep (line)) + line++; + + if (keywordlen == 8 && !memcmp (keyword, "SERIALNO", keywordlen)) + { + xfree (*r_serialno); + *r_serialno = store_serialno (line); + } + + return 0; +} + + +/* Call the agent to read the serial number of the current card. */ +int +gpgsm_agent_scd_serialno (ctrl_t ctrl, char **r_serialno) +{ + int rc; + char *serialno = NULL; + + *r_serialno = NULL; + rc = start_agent (ctrl); + if (rc) + return rc; + + rc = assuan_transact (agent_ctx, "SCD SERIALNO", + NULL, NULL, + default_inq_cb, ctrl, + scd_serialno_status_cb, &serialno); + if (!rc && !serialno) + rc = gpg_error (GPG_ERR_INTERNAL); + if (rc) + { + xfree (serialno); + return rc; + } + *r_serialno = serialno; + return 0; +} + + + +/* Callback for the gpgsm_agent_serialno fucntion. */ +static int +scd_keypairinfo_status_cb (void *opaque, const char *line) +{ + strlist_t *listaddr = opaque; + const char *keyword = line; + int keywordlen; + strlist_t sl; + char *p; + + for (keywordlen=0; *line && !spacep (line); line++, keywordlen++) + ; + while (spacep (line)) + line++; + + if (keywordlen == 11 && !memcmp (keyword, "KEYPAIRINFO", keywordlen)) + { + sl = append_to_strlist (listaddr, line); + p = sl->d; + /* Make sure that we only have two tokes so that future + extensions of the format won't change the format expected by + the caller. */ + while (*p && !spacep (p)) + p++; + if (*p) + { + while (spacep (p)) + p++; + while (*p && !spacep (p)) + p++; + *p = 0; + } + } + + return 0; +} + + +/* Call the agent to read the keypairinfo lines of the current card. + The list is returned as a string made up of the keygrip, a space + and the keyid. */ +int +gpgsm_agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list) +{ + int rc; + strlist_t list = NULL; + + *r_list = NULL; + rc = start_agent (ctrl); + if (rc) + return rc; + + rc = assuan_transact (agent_ctx, "SCD LEARN --force", + NULL, NULL, + default_inq_cb, ctrl, + scd_keypairinfo_status_cb, &list); + if (!rc && !list) + rc = gpg_error (GPG_ERR_NO_DATA); + if (rc) + { + free_strlist (list); + return rc; + } + *r_list = list; + return 0; +} + + + +static int istrusted_status_cb (void *opaque, const char *line) { struct rootca_flags_s *flags = opaque; Modified: trunk/sm/certreqgen-ui.c =================================================================== --- trunk/sm/certreqgen-ui.c 2009-07-01 18:30:33 UTC (rev 5061) +++ trunk/sm/certreqgen-ui.c 2009-07-02 09:49:31 UTC (rev 5062) @@ -97,8 +97,8 @@ size_t publiclen; int algo; - if (hexgrip[0] == '0' && hexgrip[1] == 'x') - hexgrip += 2; + if (hexgrip[0] == '&') + hexgrip++; err = gpgsm_agent_readkey (ctrl, 0, hexgrip, &public); if (err) @@ -132,6 +132,7 @@ int selection; estream_t fp = NULL; int method; + char *keytype_buffer = NULL; const char *keytype; char *keygrip = NULL; unsigned int nbits; @@ -205,24 +206,70 @@ if (!*answer) goto again; else if (strlen (answer) != 40 && - !(answer[0] == '0' && answer[1] == 'x' - && strlen (answer+2) == 40)) + !(answer[0] == '&' && strlen (answer+1) == 40)) tty_printf (_("Not a valid keygrip (expecting 40 hex digits)\n")); else if (!(keytype = check_keygrip (ctrl, answer)) ) tty_printf (_("No key with this keygrip\n")); else break; /* Okay. */ } - nbits = 1024; /* A dummy value is sufficient. */ xfree (keygrip); keygrip = answer; answer = NULL; + nbits = 1024; /* A dummy value is sufficient. */ } else /* method == 3 */ { - tty_printf ("Not yet supported; " - "use the gpgsm-gencert.sh script instead\n"); - goto again; + char *serialno; + strlist_t keypairlist, sl; + int count; + + err = gpgsm_agent_scd_serialno (ctrl, &serialno); + if (err) + { + tty_printf (_("error reading the card: %s\n"), gpg_strerror (err)); + goto again; + } + tty_printf (_("Serial number of the card: %s\n"), serialno); + xfree (serialno); + + err = gpgsm_agent_scd_keypairinfo (ctrl, &keypairlist); + if (err) + { + tty_printf (_("error reading the card: %s\n"), gpg_strerror (err)); + goto again; + } + + do + { + tty_printf (_("Available keys:\n")); + for (count=1,sl=keypairlist; sl; sl = sl->next, count++) + tty_printf (" (%d) %s\n", count, sl->d); + xfree (answer); + answer = tty_get (_("Your selection? ")); + tty_kill_prompt (); + trim_spaces (answer); + selection = atoi (answer); + } + while (!(selection > 0 && selection < count)); + + for (count=1,sl=keypairlist; sl; sl = sl->next, count++) + if (count == selection) + break; + + s = sl->d; + while (*s && !spacep (s)) + s++; + while (spacep (s)) + s++; + + xfree (keygrip); + keygrip = NULL; + xfree (keytype_buffer); + keytype_buffer = xasprintf ("card:%s", s); + free_strlist (keypairlist); + keytype = keytype_buffer; + nbits = 1024; /* A dummy value is sufficient. */ } /* Ask for the key usage. */ @@ -358,6 +405,7 @@ es_fclose (fp); xfree (answer); xfree (subject_name); + xfree (keytype_buffer); xfree (keygrip); xfree (get_membuf (&mb_email, NULL)); xfree (get_membuf (&mb_dns, NULL)); Modified: trunk/sm/gpgsm.h =================================================================== --- trunk/sm/gpgsm.h 2009-07-01 18:30:33 UTC (rev 5061) +++ trunk/sm/gpgsm.h 2009-07-02 09:49:31 UTC (rev 5062) @@ -388,6 +388,8 @@ ksba_const_sexp_t keyparms, ksba_sexp_t *r_pubkey); int gpgsm_agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip, ksba_sexp_t *r_pubkey); +int gpgsm_agent_scd_serialno (ctrl_t ctrl, char **r_serialno); +int gpgsm_agent_scd_keypairinfo (ctrl_t ctrl, strlist_t *r_list); int gpgsm_agent_istrusted (ctrl_t ctrl, ksba_cert_t cert, const char *hexfpr, struct rootca_flags_s *rootca_flags); int gpgsm_agent_havekey (ctrl_t ctrl, const char *hexkeygrip); Modified: trunk/tools/gpgsm-gencert.sh =================================================================== --- trunk/tools/gpgsm-gencert.sh 2009-07-01 18:30:33 UTC (rev 5061) +++ trunk/tools/gpgsm-gencert.sh 2009-07-02 09:49:31 UTC (rev 5062) @@ -83,7 +83,9 @@ } - +echo "WARNING: This script is deprecated; please use" >&2 +echo " gpgsm --gen-key" >&2 +echo " instead." >&2 KEY_TYPE="" while [ -z "$KEY_TYPE" ]; do query_user_menu "Key type" "RSA" "Existing key" "Direct from card" From cvs at cvs.gnupg.org Thu Jul 2 12:43:33 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 02 Jul 2009 12:43:33 +0200 Subject: [svn] gcry - r1396 - trunk/doc Message-ID: Author: wk Date: 2009-07-02 12:43:32 +0200 (Thu, 02 Jul 2009) New Revision: 1396 Modified: trunk/doc/ChangeLog trunk/doc/gcrypt.texi Log: Fix bug#1079. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-05-26 09:41:53 UTC (rev 1395) +++ trunk/doc/ChangeLog 2009-07-02 10:43:32 UTC (rev 1396) @@ -1,3 +1,8 @@ +2009-07-02 Daiki Ueno + + * gcrypt.texi (Working with S-expressions): Describe format + character '%S'. Typo fixes. Fixes bug#1079. + 2009-05-10 Werner Koch * gcrypt.texi (Working with cipher handles): Clarified that Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2009-05-26 09:41:53 UTC (rev 1395) +++ trunk/doc/gcrypt.texi 2009-07-02 10:43:32 UTC (rev 1396) @@ -4038,8 +4038,13 @@ @item %b The next argument is expected to be of type @code{int} directly followed by an argument of type @code{char *}. This represents a -buffer of given length to be inserted into the resulting regular -expression. +buffer of given length to be inserted into the resulting S-expression. + at item %S +The next argument is expected to be of type @code{gcry_sexp_t} and a +copy of that S-expression is embedded in the resulting S-expression. +The argument needs to be a regular S-expression, starting with a +parenthesis. + @end table @noindent @@ -4111,8 +4116,7 @@ @noindent -There are a couple of functions to parse S-expressions and retrieve -elements: +There are functions to parse S-expressions and retrieve elements: @deftypefun gcry_sexp_t gcry_sexp_find_token (@w{const gcry_sexp_t @var{list}}, @w{const char *@var{token}}, @w{size_t @var{toklen}}) From cvs at cvs.gnupg.org Thu Jul 2 15:40:16 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 02 Jul 2009 15:40:16 +0200 Subject: [svn] gcry - r1397 - in trunk: . cipher src tests Message-ID: Author: wk Date: 2009-07-02 15:40:15 +0200 (Thu, 02 Jul 2009) New Revision: 1397 Modified: trunk/THANKS trunk/cipher/ChangeLog trunk/cipher/md.c trunk/src/ChangeLog trunk/src/dumpsexp.c trunk/src/sexp.c trunk/tests/ChangeLog trunk/tests/benchmark.c Log: Minor bug fixes. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2009-07-02 10:43:32 UTC (rev 1396) +++ trunk/cipher/ChangeLog 2009-07-02 13:40:15 UTC (rev 1397) @@ -1,3 +1,8 @@ +2009-07-02 Werner Koch + + * md.c (md_read): Fix incomplete check for NULL. + Reported by Fabian Kail. + 2009-03-31 Werner Koch * rsa.c (rsa_check_secret_key): Return GPG_ERR_BAD_SECKEY and not Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-07-02 10:43:32 UTC (rev 1396) +++ trunk/src/ChangeLog 2009-07-02 13:40:15 UTC (rev 1397) @@ -1,3 +1,13 @@ +2009-07-02 Werner Koch + + * dumpsexp.c (main): Fix handling multiple files. + (parse_and_print): Implement hex and octal escaping. + + * sexp.c (unquote_string): Remove superfluous clearing of ESC. + * dumpsexp.c (parse_and_print): Add missing break. + (main): Fix return value. + Reported by Fabian Keil. + 2009-02-16 Werner Koch * ath.h [HAVE_SYS_SELECT_H]: Include for fd_set. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-07-02 10:43:32 UTC (rev 1396) +++ trunk/tests/ChangeLog 2009-07-02 13:40:15 UTC (rev 1397) @@ -1,3 +1,7 @@ +2009-06-08 Werner Koch + + * benchmark.c (cipher_bench): Center labels. Suggested by Brad Hards. + 2009-02-16 Werner Koch * fipsdrv.c (print_buffer): Remove parens from initializer for Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2009-07-02 10:43:32 UTC (rev 1396) +++ trunk/THANKS 2009-07-02 13:40:15 UTC (rev 1397) @@ -21,6 +21,7 @@ Christian von Roques roques at pond.sub.org Christopher Oliver oliver at fritz.traverse.net Christian Recktenwald chris at citecs.de +Daiki Ueno ueno at unixuser org Dan Fandrich dan at coneharvesters com Daniel Eisenbud eisenbud at cs.swarthmore.edu Daniel Koening dan at mail.isis.de @@ -32,6 +33,7 @@ Elie De Brauwer elie at de-brauwer.be Enzo Michelangeli em at MailAndNews.com Ernst Molitor ernst.molitor at uni-bonn.de +Fabian Keil fk at fabiankeil de Fabio Coatti cova at felix.unife.it Felix von Leitner leitner at amdiv.de Frank Heckenbach heckenb at mi.uni-erlangen.de Modified: trunk/cipher/md.c =================================================================== --- trunk/cipher/md.c 2009-07-02 10:43:32 UTC (rev 1396) +++ trunk/cipher/md.c 2009-07-02 13:40:15 UTC (rev 1397) @@ -948,10 +948,13 @@ if (! algo) { - /* return the first algorithm */ - if (r && r->next) - log_debug ("more than one algorithm in md_read(0)\n"); - return r->digest->read( &r->context.c ); + /* Return the first algorithm */ + if (r) + { + if (r->next) + log_debug ("more than one algorithm in md_read(0)\n"); + return r->digest->read (&r->context.c); + } } else { Modified: trunk/src/dumpsexp.c =================================================================== --- trunk/src/dumpsexp.c 2009-07-02 10:43:32 UTC (rev 1396) +++ trunk/src/dumpsexp.c 2009-07-02 13:40:15 UTC (rev 1397) @@ -276,7 +276,7 @@ - +/* Returns 0 on success. */ static int parse_and_print (FILE *fp) { @@ -488,12 +488,37 @@ state = IN_STRING; break; } + break; case IN_OCT_ESC: - state = IN_STRING; + if (quote_idx < 3 && strchr ("01234567", c)) + { + quote_buf[quote_idx++] = c; + if (quote_idx == 3) + { + printchr ((unsigned int)quote_buf[0] * 8 * 8 + + (unsigned int)quote_buf[1] * 8 + + (unsigned int)quote_buf[2]); + state = IN_STRING; + } + } + else + state = IN_STRING; break; case IN_HEX_ESC: - state = IN_STRING; + if (quote_idx < 2 && strchr ("0123456789abcdefABCDEF", c)) + { + quote_buf[quote_idx++] = c; + if (quote_idx == 2) + { + printchr (xtoi_1 (quote_buf[0]) * 16 + + xtoi_1 (quote_buf[1])); + + state = IN_STRING; + } + } + else + state = IN_STRING; break; case CR_ESC: state = IN_STRING; @@ -590,7 +615,8 @@ } else { - for (; argc; argc--) + rc = 0; + for (; argc; argv++, argc--) { FILE *fp = fopen (*argv, "rb"); if (!fp) @@ -600,14 +626,13 @@ } else { - if ( parse_and_print (fp) ) + if (parse_and_print (fp)) rc = 1; fclose (fp); } } } - - return !rc; + return !!rc; } Modified: trunk/src/sexp.c =================================================================== --- trunk/src/sexp.c 2009-07-02 10:43:32 UTC (rev 1396) +++ trunk/src/sexp.c 2009-07-02 13:40:15 UTC (rev 1397) @@ -909,7 +909,6 @@ { s++; n--; } - esc = 0; break; case '\n': /* ignore LF[,CR] */ Modified: trunk/tests/benchmark.c =================================================================== --- trunk/tests/benchmark.c 2009-07-02 10:43:32 UTC (rev 1396) +++ trunk/tests/benchmark.c 2009-07-02 13:40:15 UTC (rev 1397) @@ -448,12 +448,12 @@ size_t allocated_buflen, buflen; int repetitions; static struct { int mode; const char *name; int blocked; } modes[] = { - { GCRY_CIPHER_MODE_ECB, "ECB", 1 }, - { GCRY_CIPHER_MODE_CBC, "CBC", 1 }, - { GCRY_CIPHER_MODE_CFB, "CFB", 0 }, - { GCRY_CIPHER_MODE_OFB, "OFB", 0 }, - { GCRY_CIPHER_MODE_CTR, "CTR", 0 }, - { GCRY_CIPHER_MODE_STREAM, "STREAM", 0 }, + { GCRY_CIPHER_MODE_ECB, " ECB", 1 }, + { GCRY_CIPHER_MODE_CBC, " CBC", 1 }, + { GCRY_CIPHER_MODE_CFB, " CFB", 0 }, + { GCRY_CIPHER_MODE_OFB, " OFB", 0 }, + { GCRY_CIPHER_MODE_CTR, " CTR", 0 }, + { GCRY_CIPHER_MODE_STREAM, " STREAM", 0 }, {0} }; int modeidx; From cvs at cvs.gnupg.org Thu Jul 2 15:56:40 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 02 Jul 2009 15:56:40 +0200 Subject: [svn] gcry - r1398 - in branches/LIBGCRYPT-1-4-BRANCH: random src Message-ID: Author: wk Date: 2009-07-02 15:56:40 +0200 (Thu, 02 Jul 2009) New Revision: 1398 Modified: branches/LIBGCRYPT-1-4-BRANCH/random/ChangeLog branches/LIBGCRYPT-1-4-BRANCH/random/rndhw.c branches/LIBGCRYPT-1-4-BRANCH/src/ChangeLog branches/LIBGCRYPT-1-4-BRANCH/src/fips.c Log: Small changes to reflect what fedora is doing. Modified: branches/LIBGCRYPT-1-4-BRANCH/random/ChangeLog =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/random/ChangeLog 2009-07-02 13:40:15 UTC (rev 1397) +++ branches/LIBGCRYPT-1-4-BRANCH/random/ChangeLog 2009-07-02 13:56:40 UTC (rev 1398) @@ -1,3 +1,7 @@ +2009-06-24 Werner Koch + + * rndhw.c (poll_padlock): Asm change from Fedora. + 2009-01-22 Werner Koch * random.c (_gcry_random_deinit_external_test): Do not return a Modified: branches/LIBGCRYPT-1-4-BRANCH/src/ChangeLog =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/src/ChangeLog 2009-07-02 13:40:15 UTC (rev 1397) +++ branches/LIBGCRYPT-1-4-BRANCH/src/ChangeLog 2009-07-02 13:56:40 UTC (rev 1398) @@ -1,3 +1,8 @@ +2009-06-24 Werner Koch + + * fips.c (_gcry_initialize_fips_mode): No FIPS mode if + /proc/version has insufficient permissions. + 2009-02-02 Werner Koch * ath.h: Include sys/time.h. Fixes bug#993. Modified: branches/LIBGCRYPT-1-4-BRANCH/random/rndhw.c =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/random/rndhw.c 2009-07-02 13:40:15 UTC (rev 1397) +++ branches/LIBGCRYPT-1-4-BRANCH/random/rndhw.c 2009-07-02 13:56:40 UTC (rev 1398) @@ -41,8 +41,8 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins), enum random_origins origin, int fast) { - char buffer[64+8] __attribute__ ((aligned (8))); - char *p; + volatile char buffer[64+8] __attribute__ ((aligned (8))); + volatile char *p; unsigned int nbytes, status; /* Peter Gutmann's cryptlib tests again whether the RNG is enabled @@ -59,8 +59,7 @@ ("movl %1, %%edi\n\t" /* Set buffer. */ "xorl %%edx, %%edx\n\t" /* Request up to 8 bytes. */ ".byte 0x0f, 0xa7, 0xc0\n\t" /* XSTORE RNG. */ - "movl %%eax, %0\n" /* Return the status. */ - : "=g" (status) + : "=a" (status) : "g" (p) : "%edx", "%edi", "cc" ); @@ -88,7 +87,7 @@ if (nbytes) { - (*add) (buffer, nbytes, origin); + (*add) ((void*)buffer, nbytes, origin); wipememory (buffer, nbytes); } return nbytes; Modified: branches/LIBGCRYPT-1-4-BRANCH/src/fips.c =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/src/fips.c 2009-07-02 13:40:15 UTC (rev 1397) +++ branches/LIBGCRYPT-1-4-BRANCH/src/fips.c 2009-07-02 13:56:40 UTC (rev 1398) @@ -155,6 +155,7 @@ fclose (fp); } else if ((saved_errno = errno) != ENOENT + && saved_errno != EACCES && !access ("/proc/version", F_OK) ) { /* Problem reading the fips file despite that we have the proc From cvs at cvs.gnupg.org Thu Jul 2 16:12:44 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 02 Jul 2009 16:12:44 +0200 Subject: [svn] gcry - r1399 - in trunk: random src Message-ID: Author: wk Date: 2009-07-02 16:12:44 +0200 (Thu, 02 Jul 2009) New Revision: 1399 Modified: trunk/random/ChangeLog trunk/random/rndhw.c trunk/src/ChangeLog trunk/src/fips.c Log: Get more in sync to the Fedora version. Modified: trunk/random/ChangeLog =================================================================== --- trunk/random/ChangeLog 2009-07-02 13:56:40 UTC (rev 1398) +++ trunk/random/ChangeLog 2009-07-02 14:12:44 UTC (rev 1399) @@ -1,3 +1,7 @@ +2009-07-02 Werner Koch + + * rndhw.c (poll_padlock): Asm change from Fedora. + 2009-01-22 Werner Koch * random.c (_gcry_random_deinit_external_test): Do not return a @@ -125,4 +129,4 @@ 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. - \ No newline at end of file + Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-07-02 13:56:40 UTC (rev 1398) +++ trunk/src/ChangeLog 2009-07-02 14:12:44 UTC (rev 1399) @@ -1,5 +1,8 @@ 2009-07-02 Werner Koch + * fips.c (_gcry_initialize_fips_mode): Do not use FIPS mode if + /proc/.../fips_enabled has insufficient permissions. + * dumpsexp.c (main): Fix handling multiple files. (parse_and_print): Implement hex and octal escaping. Modified: trunk/random/rndhw.c =================================================================== --- trunk/random/rndhw.c 2009-07-02 13:56:40 UTC (rev 1398) +++ trunk/random/rndhw.c 2009-07-02 14:12:44 UTC (rev 1399) @@ -41,8 +41,8 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins), enum random_origins origin, int fast) { - char buffer[64+8] __attribute__ ((aligned (8))); - char *p; + volatile char buffer[64+8] __attribute__ ((aligned (8))); + volatile char *p; unsigned int nbytes, status; /* Peter Gutmann's cryptlib tests again whether the RNG is enabled @@ -59,8 +59,7 @@ ("movl %1, %%edi\n\t" /* Set buffer. */ "xorl %%edx, %%edx\n\t" /* Request up to 8 bytes. */ ".byte 0x0f, 0xa7, 0xc0\n\t" /* XSTORE RNG. */ - "movl %%eax, %0\n" /* Return the status. */ - : "=g" (status) + : "=a" (status) : "g" (p) : "%edx", "%edi", "cc" ); @@ -88,7 +87,7 @@ if (nbytes) { - (*add) (buffer, nbytes, origin); + (*add) ((void*)buffer, nbytes, origin); wipememory (buffer, nbytes); } return nbytes; Modified: trunk/src/fips.c =================================================================== --- trunk/src/fips.c 2009-07-02 13:56:40 UTC (rev 1398) +++ trunk/src/fips.c 2009-07-02 14:12:44 UTC (rev 1399) @@ -155,6 +155,7 @@ fclose (fp); } else if ((saved_errno = errno) != ENOENT + && saved_errno != EACCES && !access ("/proc/version", F_OK) ) { /* Problem reading the fips file despite that we have the proc From cvs at cvs.gnupg.org Fri Jul 3 12:56:57 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 03 Jul 2009 12:56:57 +0200 Subject: [svn] ksba - r310 - trunk Message-ID: Author: wk Date: 2009-07-03 12:56:57 +0200 (Fri, 03 Jul 2009) New Revision: 310 Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac Log: Preparing a release Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-07-02 08:15:41 UTC (rev 309) +++ trunk/ChangeLog 2009-07-03 10:56:57 UTC (rev 310) @@ -1,3 +1,7 @@ +2009-07-03 Werner Koch + + Release 1.0.7. + 2009-06-05 Werner Koch Release 1.0.6. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-07-02 08:15:41 UTC (rev 309) +++ trunk/NEWS 2009-07-03 10:56:57 UTC (rev 310) @@ -1,4 +1,4 @@ -Noteworthy changes in version 1.0.7 +Noteworthy changes in version 1.0.7 (2009-07-03) ------------------------------------------------ * Detect overflow while parsing OIDs. Map BER encoded OIDs to well Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-07-02 08:15:41 UTC (rev 309) +++ trunk/configure.ac 2009-07-03 10:56:57 UTC (rev 310) @@ -25,7 +25,7 @@ # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. m4_define([my_version], [1.0.7]) -m4_define([my_issvn], [yes]) +m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) From cvs at cvs.gnupg.org Fri Jul 3 13:09:55 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 03 Jul 2009 13:09:55 +0200 Subject: [svn] ksba - r311 - tags Message-ID: Author: wk Date: 2009-07-03 13:09:55 +0200 (Fri, 03 Jul 2009) New Revision: 311 Added: tags/libksba-1.0.7/ Log: Release tag. From cvs at cvs.gnupg.org Fri Jul 3 13:41:12 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 03 Jul 2009 13:41:12 +0200 Subject: [svn] ksba - r312 - trunk Message-ID: Author: wk Date: 2009-07-03 13:41:12 +0200 (Fri, 03 Jul 2009) New Revision: 312 Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac Log: * configure.ac: Bump LT version to C17/A9/R7. Unfortunately only after the release so to anticipate fixes by distributions. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-07-03 11:09:55 UTC (rev 311) +++ trunk/ChangeLog 2009-07-03 11:41:12 UTC (rev 312) @@ -1,5 +1,10 @@ 2009-07-03 Werner Koch + * configure.ac: Bump LT version to C17/A9/R7. Unfortunately only + after the release so to anticipate fixes by distributions. + +2009-07-03 Werner Koch + Release 1.0.7. 2009-06-05 Werner Koch Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-07-03 11:09:55 UTC (rev 311) +++ trunk/NEWS 2009-07-03 11:41:12 UTC (rev 312) @@ -1,3 +1,7 @@ +Noteworthy changes in version 1.0.8 (unreleased) +------------------------------------------------ + + Noteworthy changes in version 1.0.7 (2009-07-03) ------------------------------------------------ Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-07-03 11:09:55 UTC (rev 311) +++ trunk/configure.ac 2009-07-03 11:41:12 UTC (rev 312) @@ -24,8 +24,8 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [1.0.7]) -m4_define([my_issvn], [no]) +m4_define([my_version], [1.0.8]) +m4_define([my_issvn], [yes]) m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) @@ -40,7 +40,7 @@ # Please remember to document interface changes in the NEWS file. LIBKSBA_LT_CURRENT=17 LIBKSBA_LT_AGE=9 -LIBKSBA_LT_REVISION=6 +LIBKSBA_LT_REVISION=7 #------------------- # If the API is changed in an incompatible way: increment the next counter. KSBA_CONFIG_API_VERSION=1 From cvs at cvs.gnupg.org Mon Jul 6 23:33:39 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 06 Jul 2009 23:33:39 +0200 Subject: [svn] GnuPG - r5063 - trunk/doc Message-ID: Author: wk Date: 2009-07-06 23:33:34 +0200 (Mon, 06 Jul 2009) New Revision: 5063 Modified: trunk/doc/ChangeLog trunk/doc/debugging.texi Log: * debugging.texi (Common Problems): Add a note about corrupted keys in --search-keys. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-07-02 09:49:31 UTC (rev 5062) +++ trunk/doc/ChangeLog 2009-07-06 21:33:34 UTC (rev 5063) @@ -1,3 +1,8 @@ +2009-07-06 Werner Koch + + * debugging.texi (Common Problems): Add a note about corrupted + keys in --search-keys. + 2009-06-02 Werner Koch * tools.texi (watchgnupg): Typo fix. Fixes bug#1065. Modified: trunk/doc/debugging.texi =================================================================== --- trunk/doc/debugging.texi 2009-07-02 09:49:31 UTC (rev 5062) +++ trunk/doc/debugging.texi 2009-07-06 21:33:34 UTC (rev 5063) @@ -228,6 +228,15 @@ implements those additional features. + at item Why does GPG's --search-key list weird keys? + +For performance reasons the keyservers do not check the keys the same +way @command{gpg} does. It may happen that the listing of keys +available on the keyservers shows keys with wrong user IDs or with user +Ids from other keys. If you try to import this key, the bad keys or bad +user ids won't get imported, though. This is a bit unfortunate but we +can't do anything about it without actually downloading the keys. + @end itemize From cvs at cvs.gnupg.org Tue Jul 7 12:02:43 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 07 Jul 2009 12:02:43 +0200 Subject: [svn] GnuPG - r5064 - in trunk: . agent common doc g10 sm tools Message-ID: Author: wk Date: 2009-07-07 12:02:41 +0200 (Tue, 07 Jul 2009) New Revision: 5064 Added: trunk/common/session-env.c trunk/common/session-env.h trunk/common/t-session-env.c Modified: trunk/NEWS trunk/agent/ChangeLog trunk/agent/agent.h trunk/agent/call-pinentry.c trunk/agent/command-ssh.c trunk/agent/command.c trunk/agent/gpg-agent.c trunk/agent/protect-tool.c trunk/common/ChangeLog trunk/common/Makefile.am trunk/common/asshelp.c trunk/common/asshelp.h trunk/common/get-passphrase.c trunk/common/get-passphrase.h trunk/common/t-exechelp.c trunk/doc/gpgsm.texi trunk/g10/ChangeLog trunk/g10/call-agent.c trunk/g10/gpg.c trunk/g10/options.h trunk/sm/ChangeLog trunk/sm/call-agent.c trunk/sm/gpgsm.c trunk/sm/gpgsm.h trunk/sm/misc.c trunk/sm/server.c trunk/tools/ChangeLog trunk/tools/gpg-connect-agent.c Log: Reworked passing of envars to Pinentry. [The diff below has been truncated] Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/agent/ChangeLog 2009-07-07 10:02:41 UTC (rev 5064) @@ -1,3 +1,21 @@ +2009-07-06 Werner Koch + + * agent.h: Include session-env.h. + (opt): Replace most of the startup_xxx fields by a session_env_t. + (struct server_control_s): Likewise. + * gpg-agent.c (main): Rewrite setting of the startup fields. + (handle_connections, main): Allocate SESSION_ENV. + (agent_init_default_ctrl, agent_deinit_default_ctrl): Change + accordingly. + * command.c (option_handler): Ditto. + (cmd_updatestartuptty): Change accordingly. Protect old values + from out of core failures. + * command-ssh.c (start_command_handler_ssh): Ditto. + (start_command_handler_ssh): Replace strdup by xtrystrdup. + * call-pinentry.c (atfork_cb): Pass new envrinmnet variables. + (start_pinentry): Use session_env stuff. + * protect-tool.c (main): Adjust call to gnupg_prepare_get_passphrase. + 2009-06-24 Werner Koch * genkey.c (agent_protect_and_store): Return RC and not 0. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/common/ChangeLog 2009-07-07 10:02:41 UTC (rev 5064) @@ -1,3 +1,20 @@ +2009-07-06 Werner Koch + + * get-passphrase.c (struct agentargs): Add SESSION_ENV and remove + obsolete args. + (gnupg_prepare_get_passphrase): Ditto. + + * session-env.c, session-env.h: New. + * t-session-env.c: New. + * Makefile.am (common_sources, module_tests): Add them. + * asshelp.h: Include "session-env.h" + * asshelp.c (send_one_option): Add arg PUTENV. + (send_pinentry_environment): Replace most args by SESSION_ENV and + rewrite fucntion. + (start_new_gpg_agent): Likewise. + + * t-exechelp.c (test_close_all_fds): Remove debug code. + 2009-07-01 Werner Koch * sexputil.c (get_pk_algo_from_canon_sexp): New. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/g10/ChangeLog 2009-07-07 10:02:41 UTC (rev 5064) @@ -1,6 +1,18 @@ +2009-07-07 Werner Koch + + * gpg.c (set_opt_session_env): New. + (main): Allocate opt.session_env. Use it for oDisplay, oTTYname, + oTTYtype and oXauthority. + + * options.h: Include session_env.h. + (opt): Add field SESSION_ENV, remove obsolete fields. + + * call-agent.c (start_agent): Adjust start_new_gpg_agent for + changed args. + 2009-06-24 Werner Koch - * keyedit.c (menu_select_key): Renmove dead assign to I. + * keyedit.c (menu_select_key): Remove dead assign to I. (menu_select_uid): Ditto. * keyring.c (keyring_search): Remove dead assign to NAME. * card-util.c (card_edit): Remove useless DID_CHECKPIN. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/sm/ChangeLog 2009-07-07 10:02:41 UTC (rev 5064) @@ -1,3 +1,15 @@ +2009-07-07 Werner Koch + + * gpgsm.h: Include session-env.h. + (opt): Add field SESSION_ENV. Remove obsolete fields. + * server.c (option_handler): Rewrite setting of option fields. + Replace strdup by xtrystrdup. + * gpgsm.c (set_opt_session_env): New. + (main): Use it for oDisplay, oTTYname, oTTYtype and oXauthority. + * call-agent.c (start_agent): Adjust start_new_gpg_agent for + changed args. + * misc.c (setup_pinentry_env): Use new session_env stuff. + 2009-07-02 Werner Koch * certreqgen-ui.c (gpgsm_gencertreq_tty): Allow using a key from a Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/tools/ChangeLog 2009-07-07 10:02:41 UTC (rev 5064) @@ -1,3 +1,8 @@ +2009-07-07 Werner Koch + + * gpg-connect-agent.c (start_agent): Adjust for changed args of + send_pinentry_environment. + 2009-06-30 Werner Koch * ccidmon.c (parse_line_sniffusb): Take also TAB as delimiter. @@ -1022,7 +1027,8 @@ * watchgnupg.c: New. - Copyright 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright 2003, 2004, 2005, 2006, 2007, 2008, + 2009 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 Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/NEWS 2009-07-07 10:02:41 UTC (rev 5064) @@ -1,15 +1,16 @@ Noteworthy changes in version 2.0.13 ------------------------------------------------- - This is a BETA version! + * The envvars XMODIFIERS, GTK_IM_MODULE and QT_IM_MODULE are now + passed to the Pinentry to make SCIM work. - * Minor bug fixes. - * gpgsm --gen-key implements a --batch mode. * gpgsm --gen-key implements all features of gpgsm-gencert.sh. + * Minor bug fixes. + Noteworthy changes in version 2.0.12 (2009-06-17) ------------------------------------------------- Modified: trunk/agent/agent.h =================================================================== --- trunk/agent/agent.h 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/agent/agent.h 2009-07-07 10:02:41 UTC (rev 5064) @@ -33,6 +33,7 @@ #include "../common/util.h" #include "../common/membuf.h" #include "../common/sysutils.h" /* (gnupg_fd_t) */ +#include "../common/session-env.h" /* To convey some special hash algorithms we use algorithm numbers reserved for application use. */ @@ -56,13 +57,9 @@ /* Environment setting gathered at program start or changed using the Assuan command UPDATESTARTUPTTY. */ - char *startup_display; - char *startup_ttyname; - char *startup_ttytype; + session_env_t startup_env; char *startup_lc_ctype; char *startup_lc_messages; - char *startup_xauthority; - char *startup_pinentry_user_data; const char *pinentry_program; /* Filename of the program to start as @@ -142,13 +139,10 @@ /* Private data of the SCdaemon (call-scd.c). */ struct scd_local_s *scd_local; - char *display; - char *ttyname; - char *ttytype; + session_env_t session_env; char *lc_ctype; char *lc_messages; - char *xauthority; - char *pinentry_user_data; + struct { int algo; unsigned char value[MAX_DIGEST_LEN]; Modified: trunk/agent/call-pinentry.c =================================================================== --- trunk/agent/call-pinentry.c 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/agent/call-pinentry.c 2009-07-07 10:02:41 UTC (rev 5064) @@ -172,14 +172,30 @@ if (!where) { + int iterator = 0; + const char *name, *assname, *value; + gcry_control (GCRYCTL_TERM_SECMEM); - if (ctrl->xauthority) - setenv ("XAUTHORITY", ctrl->xauthority, 1); - if (ctrl->pinentry_user_data) - setenv ("PINENTRY_USER_DATA", ctrl->pinentry_user_data, 1 ); + + while ((name = session_env_list_stdenvnames (&iterator, &assname))) + { + /* For all new envvars (!ASSNAME) and the two medium old + ones which do have an assuan name but are conveyed using + environment variables, update the environment of the + forked process. */ + if (!assname + || !strcmp (name, "XAUTHORITY") + || !strcmp (name, "PINENTRY_USER_DATA")) + { + value = session_env_getenv (ctrl->session_env, name); + if (value) + setenv (name, value, 1); + } + } } } + static int getinfo_pid_cb (void *opaque, const void *buffer, size_t length) { @@ -214,6 +230,7 @@ pth_event_t evt; const char *tmpstr; unsigned long pinentry_pid; + const char *value; evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0)); if (!pth_mutex_acquire (&entry_lock, 0, evt)) @@ -273,10 +290,11 @@ argv[0] = pgmname; #endif /*__APPLE__*/ - if (ctrl->display && !opt.keep_display) + if (!opt.keep_display + && (value = session_env_getenv (ctrl->session_env, "DISPLAY"))) { argv[1] = "--display"; - argv[2] = ctrl->display; + argv[2] = value; argv[3] = NULL; } else @@ -313,10 +331,12 @@ NULL, NULL, NULL, NULL, NULL, NULL); if (rc) return unlock_pinentry (rc); - if (ctrl->ttyname) + + value = session_env_getenv (ctrl->session_env, "GPG_TTY"); + if (value) { char *optstr; - if (asprintf (&optstr, "OPTION ttyname=%s", ctrl->ttyname) < 0 ) + if (asprintf (&optstr, "OPTION ttyname=%s", value) < 0 ) return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); @@ -324,10 +344,11 @@ if (rc) return unlock_pinentry (rc); } - if (ctrl->ttytype) + value = session_env_getenv (ctrl->session_env, "TERM"); + if (value) { char *optstr; - if (asprintf (&optstr, "OPTION ttytype=%s", ctrl->ttytype) < 0 ) + if (asprintf (&optstr, "OPTION ttytype=%s", value) < 0 ) return unlock_pinentry (out_of_core ()); rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, NULL); Modified: trunk/agent/command-ssh.c =================================================================== --- trunk/agent/command-ssh.c 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/agent/command-ssh.c 2009-07-07 10:02:41 UTC (rev 5064) @@ -2906,29 +2906,41 @@ void start_command_handler_ssh (ctrl_t ctrl, gnupg_fd_t sock_client) { - estream_t stream_sock; - gpg_error_t err; + estream_t stream_sock = NULL; + gpg_error_t err = 0; int ret; /* Because the ssh protocol does not send us information about the the current TTY setting, we resort here to use those from startup or those explictly set. */ - if (!ctrl->display && opt.startup_display) - ctrl->display = strdup (opt.startup_display); - if (!ctrl->ttyname && opt.startup_ttyname) - ctrl->ttyname = strdup (opt.startup_ttyname); - if (!ctrl->ttytype && opt.startup_ttytype) - ctrl->ttytype = strdup (opt.startup_ttytype); - if (!ctrl->lc_ctype && opt.startup_lc_ctype) - ctrl->lc_ctype = strdup (opt.startup_lc_ctype); - if (!ctrl->lc_messages && opt.startup_lc_messages) - ctrl->lc_messages = strdup (opt.startup_lc_messages); - if (!ctrl->xauthority && opt.startup_xauthority) - ctrl->xauthority = strdup (opt.startup_xauthority); - if (!ctrl->pinentry_user_data && opt.startup_pinentry_user_data) - ctrl->pinentry_user_data = strdup (opt.startup_pinentry_user_data); + { + static const char *names[] = + {"GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL}; + int idx; + const char *value; + for (idx=0; !err && names[idx]; idx++) + if (!session_env_getenv (ctrl->session_env, names[idx]) + && (value = session_env_getenv (opt.startup_env, names[idx]))) + err = session_env_setenv (ctrl->session_env, names[idx], value); + + if (!err && !ctrl->lc_ctype && opt.startup_lc_ctype) + if (!(ctrl->lc_ctype = xtrystrdup (opt.startup_lc_ctype))) + err = gpg_error_from_syserror (); + if (!err && !ctrl->lc_messages && opt.startup_lc_messages) + if (!(ctrl->lc_messages = xtrystrdup (opt.startup_lc_messages))) + err = gpg_error_from_syserror (); + + if (err) + { + log_error ("error setting default session environment: %s\n", + gpg_strerror (err)); + goto out; + } + } + + /* Create stream from socket. */ stream_sock = es_fdopen (FD2INT(sock_client), "r+"); if (!stream_sock) Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/agent/command.c 2009-07-07 10:02:41 UTC (rev 5064) @@ -1520,33 +1520,53 @@ static int cmd_updatestartuptty (assuan_context_t ctx, char *line) { + static const char *names[] = + { "GPG_TTY", "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL }; ctrl_t ctrl = assuan_get_pointer (ctx); - + gpg_error_t err = 0; + session_env_t se; + int idx; + char *lc_ctype = NULL; + char *lc_messages = NULL; + (void)line; - xfree (opt.startup_display); opt.startup_display = NULL; - xfree (opt.startup_ttyname); opt.startup_ttyname = NULL; - xfree (opt.startup_ttytype); opt.startup_ttytype = NULL; - xfree (opt.startup_lc_ctype); opt.startup_lc_ctype = NULL; - xfree (opt.startup_lc_messages); opt.startup_lc_messages = NULL; - xfree (opt.startup_xauthority); opt.startup_xauthority = NULL; + se = session_env_new (); + if (!se) + err = gpg_error_from_syserror (); - if (ctrl->display) - opt.startup_display = xtrystrdup (ctrl->display); - if (ctrl->ttyname) - opt.startup_ttyname = xtrystrdup (ctrl->ttyname); - if (ctrl->ttytype) - opt.startup_ttytype = xtrystrdup (ctrl->ttytype); - if (ctrl->lc_ctype) - opt.startup_lc_ctype = xtrystrdup (ctrl->lc_ctype); - if (ctrl->lc_messages) - opt.startup_lc_messages = xtrystrdup (ctrl->lc_messages); - if (ctrl->xauthority) - opt.startup_xauthority = xtrystrdup (ctrl->xauthority); - if (ctrl->pinentry_user_data) - opt.startup_pinentry_user_data = xtrystrdup (ctrl->pinentry_user_data); + for (idx=0; !err && names[idx]; idx++) + { + const char *value = session_env_getenv (ctrl->session_env, names[idx]); + if (value) + err = session_env_setenv (se, names[idx], value); + } - return 0; + if (!err && ctrl->lc_ctype) + if (!(lc_ctype = xtrystrdup (ctrl->lc_ctype))) + err = gpg_error_from_syserror (); + + if (!err && ctrl->lc_messages) + if (!(lc_messages = xtrystrdup (ctrl->lc_messages))) + err = gpg_error_from_syserror (); + + if (err) + { + session_env_release (se); + xfree (lc_ctype); + xfree (lc_messages); + } + else + { + session_env_release (opt.startup_env); + opt.startup_env = se; + xfree (opt.startup_lc_ctype); + opt.startup_lc_ctype = lc_ctype; + xfree (opt.startup_lc_messages); + opt.startup_lc_messages = lc_messages; + } + + return err; } @@ -1680,36 +1700,31 @@ option_handler (assuan_context_t ctx, const char *key, const char *value) { ctrl_t ctrl = assuan_get_pointer (ctx); + gpg_error_t err = 0; - if (!strcmp (key, "display")) + if (!strcmp (key, "putenv")) { - if (ctrl->display) - xfree (ctrl->display); - ctrl->display = xtrystrdup (value); - if (!ctrl->display) - return out_of_core (); + /* Change the session's environment to be used for the + Pinentry. Valid values are: + Delete envvar NAME + = Set envvar NAME to the empty string + = Set envvar NAME to VALUE + */ + err = session_env_putenv (ctrl->session_env, value); } + else if (!strcmp (key, "display")) + { + err = session_env_setenv (ctrl->session_env, "DISPLAY", value); + } else if (!strcmp (key, "ttyname")) { if (!opt.keep_tty) - { - if (ctrl->ttyname) - xfree (ctrl->ttyname); - ctrl->ttyname = xtrystrdup (value); - if (!ctrl->ttyname) - return out_of_core (); - } + err = session_env_setenv (ctrl->session_env, "GPG_TTY", value); } else if (!strcmp (key, "ttytype")) { if (!opt.keep_tty) - { - if (ctrl->ttytype) - xfree (ctrl->ttytype); - ctrl->ttytype = xtrystrdup (value); - if (!ctrl->ttytype) - return out_of_core (); - } + err = session_env_setenv (ctrl->session_env, "TERM", value); } else if (!strcmp (key, "lc-ctype")) { @@ -1729,28 +1744,20 @@ } else if (!strcmp (key, "xauthority")) { - if (ctrl->xauthority) - xfree (ctrl->xauthority); - ctrl->xauthority = xtrystrdup (value); - if (!ctrl->xauthority) - return out_of_core (); + err = session_env_setenv (ctrl->session_env, "XAUTHORITY", value); } else if (!strcmp (key, "pinentry-user-data")) { - if (ctrl->pinentry_user_data) - xfree (ctrl->pinentry_user_data); - ctrl->pinentry_user_data = xtrystrdup (value); - if (!ctrl->pinentry_user_data) - return out_of_core (); + err = session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", value); } else if (!strcmp (key, "use-cache-for-signing")) ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0; else if (!strcmp (key, "allow-pinentry-notify")) ctrl->server_local->allow_pinentry_notify = 1; else - return gpg_error (GPG_ERR_UNKNOWN_OPTION); + err = gpg_error (GPG_ERR_UNKNOWN_OPTION); - return 0; + return err; } Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/agent/gpg-agent.c 2009-07-07 10:02:41 UTC (rev 5064) @@ -609,29 +609,41 @@ opt.homedir = default_homedir (); /* Record some of the original environment strings. */ - opt.startup_display = getenv ("DISPLAY"); - if (opt.startup_display) - opt.startup_display = xstrdup (opt.startup_display); - opt.startup_ttyname = ttyname (0); - if (opt.startup_ttyname) - opt.startup_ttyname = xstrdup (opt.startup_ttyname); - opt.startup_ttytype = getenv ("TERM"); - if (opt.startup_ttytype) - opt.startup_ttytype = xstrdup (opt.startup_ttytype); - /* Fixme: Better use the locale function here. */ - opt.startup_lc_ctype = getenv ("LC_CTYPE"); - if (opt.startup_lc_ctype) - opt.startup_lc_ctype = xstrdup (opt.startup_lc_ctype); - opt.startup_lc_messages = getenv ("LC_MESSAGES"); - if (opt.startup_lc_messages) - opt.startup_lc_messages = xstrdup (opt.startup_lc_messages); - opt.startup_xauthority = getenv ("XAUTHORITY"); - if (opt.startup_xauthority) - opt.startup_xauthority = xstrdup (opt.startup_xauthority); - opt.startup_pinentry_user_data = getenv ("PINENTRY_USER_DATA"); - if (opt.startup_pinentry_user_data) - opt.startup_pinentry_user_data = xstrdup (opt.startup_pinentry_user_data); + { + const char *s; + int idx; + static const char *names[] = + { "DISPLAY", "TERM", "XAUTHORITY", "PINENTRY_USER_DATA", NULL }; + err = 0; + opt.startup_env = session_env_new (); + if (!opt.startup_env) + err = gpg_error_from_syserror (); + for (idx=0; !err && names[idx]; idx++) + { + s = getenv (names[idx]); + if (s) + err = session_env_setenv (opt.startup_env, names[idx], s); + } + if (!err) + { + s = ttyname (0); + if (s) + err = session_env_setenv (opt.startup_env, "GPG_TTY", s); + } + if (err) + log_fatal ("error recording startup environment: %s\n", + gpg_strerror (err)); + + /* Fixme: Better use the locale function here. */ + opt.startup_lc_ctype = getenv ("LC_CTYPE"); + if (opt.startup_lc_ctype) + opt.startup_lc_ctype = xstrdup (opt.startup_lc_ctype); + opt.startup_lc_messages = getenv ("LC_MESSAGES"); + if (opt.startup_lc_messages) + opt.startup_lc_messages = xstrdup (opt.startup_lc_messages); + } + /* Check whether we have a config file on the commandline */ orig_argc = argc; orig_argv = argv; @@ -924,6 +936,14 @@ strerror (errno) ); agent_exit (1); } + ctrl->session_env = session_env_new (); + if (!ctrl->session_env) + { + log_error ("error allocating session environment block: %s\n", + strerror (errno) ); + xfree (ctrl); + agent_exit (1); + } agent_init_default_ctrl (ctrl); start_command_handler (ctrl, GNUPG_INVALID_FD, GNUPG_INVALID_FD); agent_deinit_default_ctrl (ctrl); @@ -1218,63 +1238,43 @@ exit (rc); } + static void agent_init_default_ctrl (ctrl_t ctrl) { /* Note we ignore malloc errors because we can't do much about it and the request will fail anyway shortly after this initialization. */ - if (ctrl->display) - xfree (ctrl->display); - ctrl->display = default_display? xtrystrdup (default_display) : NULL; - - if (ctrl->ttyname) - xfree (ctrl->ttyname); - ctrl->ttyname = default_ttyname? xtrystrdup (default_ttyname) : NULL; - - if (ctrl->ttytype) - xfree (ctrl->ttytype); - ctrl->ttytype = default_ttytype? xtrystrdup (default_ttytype) : NULL; - + session_env_setenv (ctrl->session_env, "DISPLAY", default_display); + session_env_setenv (ctrl->session_env, "GPG_TTY", default_ttyname); + session_env_setenv (ctrl->session_env, "TERM", default_ttytype); + session_env_setenv (ctrl->session_env, "XAUTHORITY", default_xauthority); + session_env_setenv (ctrl->session_env, "PINENTRY_USER_DATA", NULL); + if (ctrl->lc_ctype) xfree (ctrl->lc_ctype); ctrl->lc_ctype = default_lc_ctype? xtrystrdup (default_lc_ctype) : NULL; - + if (ctrl->lc_messages) xfree (ctrl->lc_messages); ctrl->lc_messages = default_lc_messages? xtrystrdup (default_lc_messages) /**/ : NULL; - if (ctrl->xauthority) - xfree (ctrl->xauthority); - ctrl->xauthority = default_xauthority? xtrystrdup (default_xauthority) - /**/: NULL; - - if (ctrl->pinentry_user_data) - xfree (ctrl->pinentry_user_data); - ctrl->pinentry_user_data = NULL; } static void agent_deinit_default_ctrl (ctrl_t ctrl) { - if (ctrl->display) - xfree (ctrl->display); - if (ctrl->ttyname) - xfree (ctrl->ttyname); - if (ctrl->ttytype) - xfree (ctrl->ttytype); + session_env_release (ctrl->session_env); + if (ctrl->lc_ctype) xfree (ctrl->lc_ctype); if (ctrl->lc_messages) xfree (ctrl->lc_messages); - if (ctrl->xauthority) - xfree (ctrl->xauthority); - if (ctrl->pinentry_user_data) - xfree (ctrl->pinentry_user_data); } + /* Reread parts of the configuration. Note, that this function is obviously not thread-safe and should only be called from the PTH signal handler. @@ -1961,6 +1961,13 @@ strerror (errno) ); assuan_sock_close (fd); } + else if ( !(ctrl->session_env = session_env_new ()) ) + { + log_error ("error allocating session environment block: %s\n", + strerror (errno) ); + xfree (ctrl); + assuan_sock_close (fd); + } else { char threadname[50]; @@ -1999,6 +2006,13 @@ strerror (errno) ); assuan_sock_close (fd); } + else if ( !(ctrl->session_env = session_env_new ()) ) + { + log_error ("error allocating session environment block: %s\n", + strerror (errno) ); + xfree (ctrl); + assuan_sock_close (fd); + } else { char threadname[50]; Modified: trunk/agent/protect-tool.c =================================================================== --- trunk/agent/protect-tool.c 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/agent/protect-tool.c 2009-07-07 10:02:41 UTC (rev 5064) @@ -1086,7 +1086,7 @@ opt.verbose, opt_homedir, opt_agent_program, - NULL, NULL, NULL, NULL, NULL, NULL, NULL); + NULL, NULL, NULL); if (opt_prompt) opt_prompt = percent_plus_unescape (opt_prompt, 0); Modified: trunk/common/Makefile.am =================================================================== --- trunk/common/Makefile.am 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/common/Makefile.am 2009-07-07 10:02:41 UTC (rev 5064) @@ -69,6 +69,7 @@ pka.c pka.h \ http.c http.h \ localename.c \ + session-env.c session-env.h \ helpfile.c # Sources only useful without PTH. @@ -111,7 +112,8 @@ # # Module tests # -module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil t-exechelp +module_tests = t-convert t-percent t-gettime t-sysutils t-sexputil t-exechelp \ + t-session-env module_maint_tests = t-helpfile t-b64 t_common_ldadd = libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a \ @@ -125,6 +127,5 @@ t_sexputil_LDADD = $(t_common_ldadd) t_b64_LDADD = $(t_common_ldadd) t_exechelp_LDADD = $(t_common_ldadd) +t_session_env_LDADD = $(t_common_ldadd) - - Modified: trunk/common/asshelp.c =================================================================== --- trunk/common/asshelp.c 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/common/asshelp.c 2009-07-07 10:02:41 UTC (rev 5064) @@ -1,5 +1,5 @@ /* asshelp.c - Helper functions for Assuan - * Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc. + * Copyright (C) 2002, 2004, 2007, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -34,10 +34,9 @@ #include "status.h" #include "asshelp.h" - static gpg_error_t send_one_option (assuan_context_t ctx, gpg_err_source_t errsource, - const char *name, const char *value) + const char *name, const char *value, int use_putenv) { gpg_error_t err; char *optstr; @@ -46,7 +45,8 @@ if (!value || !*value) err = 0; /* Avoid sending empty strings. */ - else if (asprintf (&optstr, "OPTION %s=%s", name, value ) < 0) + else if (asprintf (&optstr, "OPTION %s%s=%s", + use_putenv? "putenv=":"", name, value) < 0) err = gpg_error_from_syserror (); else { @@ -64,58 +64,44 @@ gpg_error_t send_pinentry_environment (assuan_context_t ctx, gpg_err_source_t errsource, - const char *opt_display, - const char *opt_ttyname, - const char *opt_ttytype, const char *opt_lc_ctype, const char *opt_lc_messages, - const char *opt_xauthority, - const char *opt_pinentry_user_data) + session_env_t session_env) + { gpg_error_t err = 0; - char *dft_display = NULL; - char *dft_ttyname = NULL; - char *dft_ttytype = NULL; char *old_lc = NULL; char *dft_lc = NULL; - char *dft_xauthority = NULL; - char *dft_pinentry_user_data = NULL; + const char *dft_ttyname; + int iterator; + const char *name, *assname, *value; + int is_default; - /* Send the DISPLAY variable. */ - dft_display = getenv ("DISPLAY"); - if (opt_display || dft_display) + iterator = 0; + while ((name = session_env_list_stdenvnames (&iterator, &assname))) { - err = send_one_option (ctx, errsource, "display", - opt_display ? opt_display : dft_display); - if (err) - return err; - } + value = session_env_getenv_or_default (session_env, name, NULL); + if (!value) + continue; - /* Send the name of the TTY. */ - if (!opt_ttyname) - { - dft_ttyname = getenv ("GPG_TTY"); - if ((!dft_ttyname || !*dft_ttyname) && ttyname (0)) - dft_ttyname = ttyname (0); - } - if (opt_ttyname || dft_ttyname) - { - err = send_one_option (ctx, errsource, "ttyname", - opt_ttyname ? opt_ttyname : dft_ttyname); + if (assname) + err = send_one_option (ctx, errsource, assname, value, 0); + else + { + err = send_one_option (ctx, errsource, name, value, 1); + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION) + err = 0; /* Server too old; can't pass the new envvars. */ + } if (err) return err; } - /* Send the type of the TTY. */ - dft_ttytype = getenv ("TERM"); - if (opt_ttytype || (dft_ttyname && dft_ttytype)) - { - err = send_one_option (ctx, errsource, "ttytype", - opt_ttyname ? opt_ttytype : dft_ttytype); - if (err) - return err; - } + dft_ttyname = session_env_getenv_or_default (session_env, "GPG_TTY", + &is_default); + if (dft_ttyname && !is_default) + dft_ttyname = NULL; /* We need the default value. */ + /* Send the value for LC_CTYPE. */ #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) old_lc = setlocale (LC_CTYPE, NULL); @@ -130,7 +116,7 @@ if (opt_lc_ctype || (dft_ttyname && dft_lc)) { err = send_one_option (ctx, errsource, "lc-ctype", - opt_lc_ctype ? opt_lc_ctype : dft_lc); + opt_lc_ctype ? opt_lc_ctype : dft_lc, 0); } #if defined(HAVE_SETLOCALE) && defined(LC_CTYPE) if (old_lc) @@ -156,7 +142,7 @@ if (opt_lc_messages || (dft_ttyname && dft_lc)) { err = send_one_option (ctx, errsource, "lc-messages", - opt_lc_messages ? opt_lc_messages : dft_lc); + opt_lc_messages ? opt_lc_messages : dft_lc, 0); } #if defined(HAVE_SETLOCALE) && defined(LC_MESSAGES) if (old_lc) @@ -168,31 +154,6 @@ if (err) return err; - /* Send the XAUTHORITY variable. */ - dft_xauthority = getenv ("XAUTHORITY"); - if (opt_xauthority || dft_xauthority) - { - err = send_one_option (ctx, errsource, "xauthority", - opt_xauthority ? opt_xauthority : dft_xauthority); - if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION) - err = 0; - if (err) - return err; - } - - /* Send the PINENTRY_USER_DATA variable. */ - dft_pinentry_user_data = getenv ("PINENTRY_USER_DATA"); - if (opt_pinentry_user_data || dft_pinentry_user_data) - { - err = send_one_option (ctx, errsource, "pinentry-user-data", - opt_pinentry_user_data ? - opt_pinentry_user_data : dft_pinentry_user_data); - if (gpg_err_code (err) == GPG_ERR_UNKNOWN_OPTION) - err = 0; - if (err) - return err; - } - return 0; } @@ -205,13 +166,9 @@ gpg_err_source_t errsource, const char *homedir, const char *agent_program, - const char *opt_display, - const char *opt_ttyname, - const char *opt_ttytype, const char *opt_lc_ctype, const char *opt_lc_messages, - const char *opt_xauthority, - const char *opt_pinentry_user_data, + session_env_t session_env, int verbose, int debug, gpg_error_t (*status_cb)(ctrl_t, int, ...), ctrl_t status_cb_arg) @@ -365,10 +322,8 @@ NULL, NULL, NULL, NULL, NULL, NULL); if (!rc) rc = send_pinentry_environment (ctx, errsource, - opt_display, opt_ttyname, opt_ttytype, opt_lc_ctype, opt_lc_messages, - opt_xauthority, - opt_pinentry_user_data); + session_env); if (rc) { assuan_disconnect (ctx); Modified: trunk/common/asshelp.h =================================================================== --- trunk/common/asshelp.h 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/common/asshelp.h 2009-07-07 10:02:41 UTC (rev 5064) @@ -23,31 +23,25 @@ #include #include +#include "session-env.h" + gpg_error_t send_pinentry_environment (assuan_context_t ctx, gpg_err_source_t errsource, - const char *opt_display, - const char *opt_ttyname, - const char *opt_ttytype, const char *opt_lc_ctype, const char *opt_lc_messages, - const char *opt_xauthority, - const char *opt_pinentry_user_data); + session_env_t session_env); /* This fucntion is used by the call-agent.c modules to fire up a new - agent. What a parameter list ;-). */ + agent. */ gpg_error_t start_new_gpg_agent (assuan_context_t *r_ctx, gpg_err_source_t errsource, const char *homedir, const char *agent_program, - const char *opt_display, - const char *opt_ttyname, - const char *opt_ttytype, const char *opt_lc_ctype, const char *opt_lc_messages, - const char *opt_xauthority, - const char *opt_pinentry_user_data, + session_env_t session_env, int verbose, int debug, gpg_error_t (*status_cb)(ctrl_t, int, ...), ctrl_t status_cb_arg); Modified: trunk/common/get-passphrase.c =================================================================== --- trunk/common/get-passphrase.c 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/common/get-passphrase.c 2009-07-07 10:02:41 UTC (rev 5064) @@ -39,12 +39,9 @@ int verbosity; const char *homedir; const char *agent_program; - const char *display; - const char *ttyname; - const char *ttytype; const char *lc_ctype; const char *lc_messages; - const char *xauthority; + session_env_t session_env; const char *pinentry_user_data; } agentargs; @@ -57,25 +54,17 @@ int verbosity, const char *homedir, const char *agent_program, - const char *opt_display, - const char *opt_ttyname, - const char *opt_ttytype, const char *opt_lc_ctype, const char *opt_lc_messages, - const char *opt_xauthority, - const char *opt_pinentry_user_data) + session_env_t session_env) { agentargs.errsource = errsource; agentargs.verbosity = verbosity; agentargs.homedir = homedir; agentargs.agent_program = agent_program; - agentargs.display = opt_display; - agentargs.ttyname = opt_ttyname; - agentargs.ttytype = opt_ttytype; agentargs.lc_ctype = opt_lc_ctype; agentargs.lc_messages = opt_lc_messages; - agentargs.xauthority = opt_xauthority; - agentargs.pinentry_user_data = opt_pinentry_user_data; + agentargs.session_env = session_env; } @@ -96,13 +85,9 @@ agentargs.errsource, agentargs.homedir, agentargs.agent_program, - agentargs.display, - agentargs.ttyname, - agentargs.ttytype, agentargs.lc_ctype, agentargs.lc_messages, - agentargs.xauthority, - agentargs.pinentry_user_data, + agentargs.session_env, agentargs.verbosity, 0, NULL, NULL); if (!err) { Modified: trunk/common/get-passphrase.h =================================================================== --- trunk/common/get-passphrase.h 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/common/get-passphrase.h 2009-07-07 10:02:41 UTC (rev 5064) @@ -20,17 +20,15 @@ #ifndef GNUPG_COMMON_GET_PASSPHRASE_H #define GNUPG_COMMON_GET_PASSPHRASE_H +#include "session-env.h" + void gnupg_prepare_get_passphrase (gpg_err_source_t errsource, int verbosity, const char *homedir, const char *agent_program, - const char *opt_display, - const char *opt_ttyname, - const char *opt_ttytype, const char *opt_lc_ctype, const char *opt_lc_messages, - const char *opt_xauthority, - const char *opt_pinentry_user_data); + session_env_t session_env); gpg_error_t gnupg_get_passphrase (const char *cache_id, const char *err_msg, Added: trunk/common/session-env.c =================================================================== --- trunk/common/session-env.c (rev 0) +++ trunk/common/session-env.c 2009-07-07 10:02:41 UTC (rev 5064) @@ -0,0 +1,384 @@ +/* se4ssiobn-env.c - session environment helper functions. + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "session-env.h" + + +struct variable_s +{ + char *value; /* Pointer into NAME to the Nul terminated value. */ + int is_default; /* The value is a default one. */ + char name[1]; /* Nul terminated Name and space for the value. */ +}; + + + +/* The session environment object. */ +struct session_environment_s +{ + size_t arraysize; /* Allocated size or ARRAY. */ + size_t arrayused; /* Used size of ARRAY. */ + struct variable_s **array; /* Array of variables. NULL slots are unused. */ +}; + + +/* A list of environment vribales we pass from the acual user + (e.g. gpgme) down to the pinentry. We do not handle the locale + settings because they do not only depend on envvars. */ +static struct +{ + const char *name; + const char *assname; /* Name used by Assuan or NULL. */ +} stdenvnames[] = { + { "GPG_TTY", "ttyname" }, /* GnuPG specific envvar. */ + { "TERM", "ttytype" }, /* Used to set ttytype. */ + { "DISPLAY", "display" }, /* The X-Display. */ + { "XAUTHORITY","xauthority"}, /* Xlib Authentication. */ + { "XMODIFIERS" }, /* Used by Xlib to select X input + modules (eg "@im=SCIM"). */ + { "GTK_IM_MODULE" }, /* Used by gtk to select gtk input + modules (eg "scim-bridge"). */ + { "QT_IM_MODULE" }, /* Used by Qt to select qt input + modules (eg "xim"). */ + { "PINENTRY_USER_DATA", "pinentry-user-data"} + /* Used for communication with + non-standard Pinentries. */ +}; + + +/* Track last allocated arraysize of all objects ever created. If + nothing has ever been allocated we use INITIAL_ARRAYSIZE and we + will never use more than MAXDEFAULT_ARRAYSIZE for initial + allocation. Note that this is not reentrant if used with a + preemptive thread model. */ +static size_t lastallocatedarraysize; +#define INITIAL_ARRAYSIZE 8 /* Let's use the number of stdenvnames. */ +#define CHUNK_ARRAYSIZE 10 +#define MAXDEFAULT_ARRAYSIZE (INITIAL_ARRAYSIZE + CHUNK_ARRAYSIZE * 5) + + +/* Return the names of standard environment variables one after the + other. The caller needs to set the value at the address of + ITERATOR initally to 0 and then call this function until it returns + NULL. */ +const char * +session_env_list_stdenvnames (int *iterator, const char **r_assname) +{ + int idx = *iterator; + + if (idx < 0 || idx >= DIM (stdenvnames)) + return NULL; + *iterator = idx + 1; + if (r_assname) + *r_assname = stdenvnames[idx].assname; + return stdenvnames[idx].name; +} + + +/* Create a new session environment object. Return NULL and sets + ERRNO on failure. */ +session_env_t +session_env_new (void) +{ + session_env_t se; + + se = xtrycalloc (1, sizeof *se); + if (se) + { + se->arraysize = (lastallocatedarraysize? + lastallocatedarraysize : INITIAL_ARRAYSIZE); + se->array = xtrycalloc (se->arraysize, sizeof *se->array); + if (!se->array) + { + xfree (se); + se = NULL; + } + } + + return se; +} + + +/* Release a session environment object. */ +void +session_env_release (session_env_t se) +{ + int idx; + + if (!se) + return; + + if (se->arraysize > INITIAL_ARRAYSIZE + && se->arraysize <= MAXDEFAULT_ARRAYSIZE + && se->arraysize > lastallocatedarraysize) + lastallocatedarraysize = se->arraysize; + + for (idx=0; idx < se->arrayused; idx++) + if (se->array[idx]) + xfree (se->array[idx]); + xfree (se->array); + xfree (se); +} + + +static gpg_error_t +delete_var (session_env_t se, const char *name) +{ + int idx; + + for (idx=0; idx < se->arrayused; idx++) + if (se->array[idx] && !strcmp (se->array[idx]->name, name)) + { + xfree (se->array[idx]); + se->array[idx] = NULL; + } + return 0; +} + + +static gpg_error_t +update_var (session_env_t se, const char *string, size_t namelen, + const char *explicit_value, int set_default) +{ + int idx; + int freeidx = -1; + const char *value; + size_t valuelen; + struct variable_s *var; + + if (explicit_value) + value = explicit_value; + else + value = string + namelen + 1; + valuelen = strlen (value); + + for (idx=0; idx < se->arrayused; idx++) + { + if (!se->array[idx]) + freeidx = idx; + else if (!strncmp (se->array[idx]->name, string, namelen) + && strlen (se->array[idx]->name) == namelen) + { + /* Check if the value is the same; no need to update it, + except for updating the default flag. */ + if (strlen (se->array[idx]->value) == valuelen) + { + se->array[idx]->is_default = !!set_default; + return 0; + } + /* Prepare for update. */ + freeidx = idx; + } + } + + if (freeidx == -1) + { + if (se->arrayused == se->arraysize) + { + /* Reallocate the array. */ + size_t newsize; + struct variable_s **newarray; + + newsize = se->arraysize + CHUNK_ARRAYSIZE; + newarray = xtrycalloc (newsize, sizeof *newarray); + if (!newarray) + return gpg_error_from_syserror (); + for (idx=0; idx < se->arrayused; idx++) + newarray[idx] = se->array[idx]; + se->arraysize = newsize; + xfree (se->array); + se->array = newarray; + } + freeidx = se->arrayused++; + } + + /* Allocate new memory and return an error if that didn't worked. + Allocating it first allows us to keep the old value; it doesn't + matter that arrayused has already been incremented in case of a + new entry - it will then pint to a NULL slot. */ + var = xtrymalloc (sizeof *var + namelen + 1 + valuelen); + if (!var) + return gpg_error_from_syserror (); + var->is_default = !!set_default; + memcpy (var->name, string, namelen); + var->name[namelen] = '\0'; + var->value = var->name + namelen + 1; + strcpy (var->value, value); + + xfree (se->array[freeidx]); + se->array[freeidx] = var; + return 0; +} + + +/* Set or update an environment variable of the session environment. + String is similar to the putval(3) function but it is reentrant and + takes a copy. In particular it exhibits this behaviour: + + Delete envvar NAME + = Set envvar NAME to the empty string + = Set envvar NAME to VALUE + + On success 0 is returned; on error an gpg-error code. */ +gpg_error_t +session_env_putenv (session_env_t se, const char *string) +{ + const char *s; + + if (!string || !*string) + return gpg_error (GPG_ERR_INV_VALUE); + s = strchr (string, '='); + if (s == string) + return gpg_error (GPG_ERR_INV_VALUE); + if (!s) + return delete_var (se, string); + else + return update_var (se, string, s - string, NULL, 0); +} + + +/* Same as session_env_putenv but with name and value given as distict + values. */ +gpg_error_t +session_env_setenv (session_env_t se, const char *name, const char *value) +{ + if (!name || !*name) + return gpg_error (GPG_ERR_INV_VALUE); + if (!value) + return delete_var (se, name); + else + return update_var (se, name, strlen (name), value, 0); +} + + + + +/* Return the value of the environment variable NAME from the SE + object. If the variable does not exist, NULL is returned. The + returned value is valid as long as SE is valid and as long it has + not been removed or updated by a call to session_env_putenv. The + caller MUST not change the returned value. */ +char * +session_env_getenv (session_env_t se, const char *name) +{ + int idx; + + if (!se || !name || !*name) + return NULL; + + for (idx=0; idx < se->arrayused; idx++) + if (se->array[idx] && !strcmp (se->array[idx]->name, name)) + return se->array[idx]->is_default? NULL : se->array[idx]->value; + return NULL; +} + + +/* Return the value of the environment variable NAME from the SE + object. The returned value is valid as long as SE is valid and as + long it has not been removed or updated by a call to + session_env_putenv. If the variable does not exist, the fucntion + tries to return the value trough a call to getenv; if that returns + a value, this value is recorded and and used. If no value could be + found, returns NULL. The caller must not change the returned + value. */ +char * +session_env_getenv_or_default (session_env_t se, const char *name, + int *r_default) +{ + int idx; + char *defvalue; + + if (r_default) + *r_default = 0; + if (!se || !name || !*name) + return NULL; + + for (idx=0; idx < se->arrayused; idx++) + if (se->array[idx] && !strcmp (se->array[idx]->name, name)) + { + if (r_default && se->array[idx]->is_default) + *r_default = 1; + return se->array[idx]->value; + } + + /* Get the default value with and additional fallback for GPG_TTY. */ + defvalue = getenv (name); + if ((!defvalue || !*defvalue) && !strcmp (name, "GPG_TTY") && ttyname (0)) + defvalue = ttyname (0); + if (defvalue) + { + /* Record the default value for later use so that we are safe + from later modifications of the environment. We need to take + a copy to better cope with the rules of putenv(3). We ignore + the error of the update function because we can't return an + explicit error anyway and the following scan would then fail + anyway. */ + update_var (se, name, strlen (name), defvalue, 1); + + for (idx=0; idx < se->arrayused; idx++) + if (se->array[idx] && !strcmp (se->array[idx]->name, name)) + { + if (r_default && se->array[idx]->is_default) + *r_default = 1; + return se->array[idx]->value; + } + } + + return NULL; +} + + +/* List the entire environment stored in SE. The caller initially + needs to set the value of ITERATOR to 0 and then call this function + until it returns NULL. The value is retruned at R_VALUE. If + R_DEFAULT is not NULL, the default flag is stored on return. The + default flag indicates that the value has been taken from the + process' environment. The caller must not change the returned + name or value. */ +char * +session_env_listenv (session_env_t se, int *iterator, + const char **r_value, int *r_default) +{ + int idx = *iterator; + + if (!se || idx < 0) + return NULL; + + for (; idx < se->arrayused; idx++) + if (se->array[idx]) + { + *iterator = idx+1; + if (r_default) + *r_default = se->array[idx]->is_default; + if (r_value) + *r_value = se->array[idx]->value; + return se->array[idx]->name; + } + return NULL; +} + + Added: trunk/common/session-env.h =================================================================== --- trunk/common/session-env.h (rev 0) +++ trunk/common/session-env.h 2009-07-07 10:02:41 UTC (rev 5064) @@ -0,0 +1,43 @@ +/* session-env.h - Definitions for session environment functions + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef GNUPG_COMMON_SESSION_ENV_H +#define GNUPG_COMMON_SESSION_ENV_H + +struct session_environment_s; +typedef struct session_environment_s *session_env_t; + +const char *session_env_list_stdenvnames (int *iterator, + const char **r_assname); + +session_env_t session_env_new (void); +void session_env_release (session_env_t se); + +gpg_error_t session_env_putenv (session_env_t se, const char *string); +gpg_error_t session_env_setenv (session_env_t se, + const char *name, const char *value); + +char *session_env_getenv (session_env_t se, const char *name); +char *session_env_getenv_or_default (session_env_t se, const char *name, + int *r_default); +char *session_env_listenv (session_env_t se, int *iterator, + const char **r_value, int *r_default); + + +#endif /*GNUPG_COMMON_SESSION_ENV_H*/ Modified: trunk/common/t-exechelp.c =================================================================== --- trunk/common/t-exechelp.c 2009-07-06 21:33:34 UTC (rev 5063) +++ trunk/common/t-exechelp.c 2009-07-07 10:02:41 UTC (rev 5064) @@ -69,7 +69,7 @@ /* That is a very crude test. To do a proper test we would need to fork a test process and best return information by some other means - that file descriptors. */ + than file descriptors. */ static void test_close_all_fds (void) { @@ -77,7 +77,7 @@ int *array; int fd; int initial_count, count, n; -#if 1 +#if 0 char buffer[100]; snprintf (buffer, sizeof buffer, "/bin/ls -l /proc/%d/fd", (int)getpid ()); Added: trunk/common/t-session-env.c =================================================================== --- trunk/common/t-session-env.c (rev 0) +++ trunk/common/t-session-env.c 2009-07-07 10:02:41 UTC (rev 5064) @@ -0,0 +1,294 @@ +/* t-session-env.c - Module test for session-env.c + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include + +#include "util.h" +#include "session-env.h" + +#define pass() do { ; } while(0) +#define fail(e) do { fprintf (stderr, "%s:%d: function failed: %s\n", \ + __FILE__,__LINE__, gpg_strerror (e)); \ + exit (1); \ + } while(0) + +static int verbose; + +static void +listall (session_env_t se) +{ + int iterator = 0; + const char *name, *value; + int def; + + if (verbose) + printf ("environment of %p\n", se); + while ( (name = session_env_listenv (se, &iterator, &value, &def)) ) + if (verbose) + printf (" %s%s=%s\n", def? "[def] ":" ", name, value); + +} + + +static void +show_stdnames (void) +{ + const char *name, *assname; + int iterator = 0; + + printf ("Known envvars:"); + while ((name = session_env_list_stdenvnames (&iterator, &assname))) + { + printf ( " %s", name); + if (assname) + printf ( "(%s)", assname); + } + putchar('\n'); +} + + +static void +test_all (void) +{ + gpg_error_t err; + session_env_t se_0, se; + const char *s, *s2; + int idx; + + se_0 = session_env_new (); + if (!se_0) + fail (gpg_error_from_syserror ()); + se = session_env_new (); + if (!se) + fail (gpg_error_from_syserror ()); + + err = session_env_putenv (se, NULL); + if (gpg_err_code (err) != GPG_ERR_INV_VALUE) + fail (err); + err = session_env_putenv (se, ""); From cvs at cvs.gnupg.org Tue Jul 7 12:29:52 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 07 Jul 2009 12:29:52 +0200 Subject: [svn] GnuPG - r5065 - trunk/tools Message-ID: Author: wk Date: 2009-07-07 12:29:52 +0200 (Tue, 07 Jul 2009) New Revision: 5065 Modified: trunk/tools/gpg-connect-agent.c Log: Release session_env. Modified: trunk/tools/gpg-connect-agent.c =================================================================== --- trunk/tools/gpg-connect-agent.c 2009-07-07 10:02:41 UTC (rev 5064) +++ trunk/tools/gpg-connect-agent.c 2009-07-07 10:29:52 UTC (rev 5065) @@ -2081,11 +2081,6 @@ assuan_context_t ctx; session_env_t session_env; - session_env = session_env_new (); - if (!session_env) - log_fatal ("error allocating session environment block: %s\n", - strerror (errno)); - infostr = getenv ("GPG_AGENT_INFO"); if (!infostr || !*infostr) { @@ -2174,8 +2169,14 @@ exit (1); } + session_env = session_env_new (); + if (!session_env) + log_fatal ("error allocating session environment block: %s\n", + strerror (errno)); + rc = send_pinentry_environment (ctx, GPG_ERR_SOURCE_DEFAULT, NULL, NULL, session_env); + session_env_release (session_env); if (rc) { log_error (_("error sending standard options: %s\n"), gpg_strerror (rc)); From cvs at cvs.gnupg.org Tue Jul 7 14:38:18 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 07 Jul 2009 14:38:18 +0200 Subject: [svn] gpgme - r1389 - trunk/src Message-ID: Author: wk Date: 2009-07-07 14:38:18 +0200 (Tue, 07 Jul 2009) New Revision: 1389 Modified: trunk/src/ChangeLog trunk/src/engine-gpgsm.c Log: * engine-gpgsm.c (gpgsm_import): Return an error for unknown data encodings. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-06-22 14:50:17 UTC (rev 1388) +++ trunk/src/ChangeLog 2009-07-07 12:38:18 UTC (rev 1389) @@ -1,3 +1,8 @@ +2009-07-07 Werner Koch + + * engine-gpgsm.c (gpgsm_import): Return an error for unknown data + encodings. + 2009-06-22 Marcus Brinkmann * debug.h: Everywhere, use %p instead of 0x%x to print pointer. Modified: trunk/src/engine-gpgsm.c =================================================================== --- trunk/src/engine-gpgsm.c 2009-06-22 14:50:17 UTC (rev 1388) +++ trunk/src/engine-gpgsm.c 2009-07-07 12:38:18 UTC (rev 1389) @@ -1544,6 +1544,7 @@ { engine_gpgsm_t gpgsm = engine; gpgme_error_t err; + gpgme_data_encoding_t dataenc; if (!gpgsm) return gpg_error (GPG_ERR_INV_VALUE); @@ -1551,10 +1552,18 @@ if (keydata && keyarray) gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */ + dataenc = gpgme_data_get_encoding (keydata); + if (keyarray) { return gpg_error (GPG_ERR_NOT_IMPLEMENTED); } + else if (dataenc == GPGME_DATA_ENCODING_URL + || dataenc == GPGME_DATA_ENCODING_URL0 + || dataenc == GPGME_DATA_ENCODING_URLESC) + { + return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + } else { gpgsm->input_cb.data = keydata; From cvs at cvs.gnupg.org Tue Jul 7 14:39:39 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 07 Jul 2009 14:39:39 +0200 Subject: [svn] gpgme - r1390 - trunk/src Message-ID: Author: wk Date: 2009-07-07 14:39:39 +0200 (Tue, 07 Jul 2009) New Revision: 1390 Modified: trunk/src/engine-gpg.c Log: Typo fix. Modified: trunk/src/engine-gpg.c =================================================================== --- trunk/src/engine-gpg.c 2009-07-07 12:38:18 UTC (rev 1389) +++ trunk/src/engine-gpg.c 2009-07-07 12:39:39 UTC (rev 1390) @@ -2140,8 +2140,8 @@ gpg >= 2.0.10. FIXME: We should check that we have such a version to that we can return a proper error code. The problem is that we don't know the context - here and thus can't accesses the cached version - number for the engine info structure. */ + here and thus can't access the cached version number + for the engine info structure. */ err = add_arg (gpg, "--locate-keys"); if ((mode & GPGME_KEYLIST_MODE_SIGS)) err = add_arg (gpg, "--with-sig-check"); From cvs at cvs.gnupg.org Tue Jul 7 16:17:39 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 07 Jul 2009 16:17:39 +0200 Subject: [svn] gpgme - r1391 - in trunk/tests: . gpg Message-ID: Author: wk Date: 2009-07-07 16:17:39 +0200 (Tue, 07 Jul 2009) New Revision: 1391 Added: trunk/tests/run-export.c trunk/tests/run-import.c trunk/tests/run-keylist.c Removed: trunk/tests/gpg/pgp-export.c trunk/tests/gpg/pgp-import.c trunk/tests/gpg/pgp-keylist.c Modified: trunk/tests/ChangeLog trunk/tests/Makefile.am trunk/tests/gpg/Makefile.am Log: Move gpg test programs to the top test directory. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-07-07 12:39:39 UTC (rev 1390) +++ trunk/tests/ChangeLog 2009-07-07 14:17:39 UTC (rev 1391) @@ -1,3 +1,16 @@ +2009-07-07 Werner Koch + + * gpg/pgp-keylist.c: Rename to ... + * run-keylist.c: ... this. + * gpg/pgp-import.c: Rename to ... + * run-import.c: ... this. + * gpg/pgp-export.c: Rename to ... + * run-export.c: ... this. + * run-support.h: New. Copied from gpg/t-support.h. + * gpg/Makefile.am (noinst_PROGRAMS): Remove them. + * Makefile.am (noinst_PROGRAMS): Add them. + (noinst_HEADERS): New. + 2009-06-22 Marcus Brinkmann * gpg/t-support.h (passphrase_cb): Implement write() according to Modified: trunk/tests/Makefile.am =================================================================== --- trunk/tests/Makefile.am 2009-07-07 12:39:39 UTC (rev 1390) +++ trunk/tests/Makefile.am 2009-07-07 14:17:39 UTC (rev 1391) @@ -30,8 +30,11 @@ AM_CPPFLAGS = @GPG_ERROR_CFLAGS@ LDADD = ../src/libgpgme.la @GPG_ERROR_LIBS@ -noinst_PROGRAMS = $(TESTS) +noinst_HEADERS = run-support.h +noinst_PROGRAMS = $(TESTS) run-keylist run-export run-import + + if RUN_GPG_TESTS gpgtests = gpg else Modified: trunk/tests/gpg/Makefile.am =================================================================== --- trunk/tests/gpg/Makefile.am 2009-07-07 12:39:39 UTC (rev 1390) +++ trunk/tests/gpg/Makefile.am 2009-07-07 14:17:39 UTC (rev 1391) @@ -50,8 +50,7 @@ t_thread1_LDADD = ../../src/libgpgme-pthread.la # We don't run t-genkey in the test suite, because it takes too long -# The other programs are used for debugging. -noinst_PROGRAMS = $(TESTS) t-genkey pgp-keylist pgp-export pgp-import +noinst_PROGRAMS = $(TESTS) t-genkey mkdemodirs: mkdemodirs.in Makefile sed -e 's,[@]GPG[@],$(GPG),g' < $(srcdir)/mkdemodirs.in > mkdemodirs Deleted: trunk/tests/gpg/pgp-export.c Deleted: trunk/tests/gpg/pgp-import.c Deleted: trunk/tests/gpg/pgp-keylist.c Copied: trunk/tests/run-export.c (from rev 1389, trunk/tests/gpg/pgp-export.c) =================================================================== --- trunk/tests/run-export.c (rev 0) +++ trunk/tests/run-export.c 2009-07-07 14:17:39 UTC (rev 1391) @@ -0,0 +1,161 @@ +/* pgp-export.c - Helper to run an export command + Copyright (C) 2008, 2009 g10 Code GmbH + + This file is part of GPGME. + + GPGME 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. + + GPGME 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, see . +*/ + +/* We need to include config.h so that we know whether we are building + with large file system (LFS) support. */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#define PGM "run-export" + +#include "run-support.h" + + +static int verbose; + + +static int +show_usage (int ex) +{ + fputs ("usage: " PGM " [options] USERIDS\n\n" + "Options:\n" + " --verbose run in verbose mode\n" + " --extern send keys to the keyserver (TAKE CARE!)\n" + , stderr); + exit (ex); +} + +int +main (int argc, char **argv) +{ + int last_argc = -1; + gpgme_error_t err; + gpgme_ctx_t ctx; + gpgme_key_t key; + gpgme_keylist_result_t result; + gpgme_key_t keyarray[100]; + int keyidx = 0; + gpgme_data_t out; + gpgme_export_mode_t mode = 0; + + if (argc) + { argc--; argv++; } + + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + show_usage (0); + else if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--extern")) + { + mode |= GPGME_KEYLIST_MODE_EXTERN; + argc--; argv++; + } + else if (!strncmp (*argv, "--", 2)) + show_usage (1); + + } + + if (!argc) + show_usage (1); + + init_gpgme (GPGME_PROTOCOL_OpenPGP); + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP); + + /* Lookup the keys. */ + err = gpgme_op_keylist_ext_start (ctx, (const char**)argv, 0, 0); + fail_if_err (err); + + while (!(err = gpgme_op_keylist_next (ctx, &key))) + { + printf ("keyid: %s (fpr: %s)\n", + key->subkeys?nonnull (key->subkeys->keyid):"?", + key->subkeys?nonnull (key->subkeys->fpr):"?"); + + if (keyidx < DIM (keyarray)-1) + keyarray[keyidx++] = key; + else + { + fprintf (stderr, PGM": too many keys" + "- skipping this key\n"); + gpgme_key_unref (key); + } + } + if (gpg_err_code (err) != GPG_ERR_EOF) + fail_if_err (err); + err = gpgme_op_keylist_end (ctx); + fail_if_err (err); + keyarray[keyidx] = NULL; + + result = gpgme_op_keylist_result (ctx); + if (result->truncated) + { + fprintf (stderr, PGM ": key listing unexpectedly truncated\n"); + exit (1); + } + + /* Now for the actual export. */ + if ((mode & GPGME_KEYLIST_MODE_EXTERN)) + printf ("sending keys to keyserver\n"); + + err = gpgme_data_new (&out); + fail_if_err (err); + + gpgme_set_armor (ctx, 1); + err = gpgme_op_export_keys (ctx, keyarray, mode, + (mode & GPGME_KEYLIST_MODE_EXTERN)? NULL:out); + fail_if_err (err); + + fflush (NULL); + if (!(mode & GPGME_KEYLIST_MODE_EXTERN)) + { + fputs ("Begin Result:\n", stdout); + print_data (out); + fputs ("End Result.\n", stdout); + } + + /* Cleanup. */ + gpgme_data_release (out); + + for (keyidx=0; keyarray[keyidx]; keyidx++) + gpgme_key_unref (keyarray[keyidx]); + + gpgme_release (ctx); + return 0; +} Property changes on: trunk/tests/run-export.c ___________________________________________________________________ Name: svn:mergeinfo + Copied: trunk/tests/run-import.c (from rev 1389, trunk/tests/gpg/pgp-import.c) =================================================================== --- trunk/tests/run-import.c (rev 0) +++ trunk/tests/run-import.c 2009-07-07 14:17:39 UTC (rev 1391) @@ -0,0 +1,129 @@ +/* pgp-import.c - Helper to run an import command + Copyright (C) 2008, 2009 g10 Code GmbH + + This file is part of GPGME. + + GPGME 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. + + GPGME 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, see . +*/ + +/* We need to include config.h so that we know whether we are building + with large file system (LFS) support. */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#define PGM "run-import" + +#include "run-support.h" + + +static int verbose; + + +static int +show_usage (int ex) +{ + fputs ("usage: " PGM " [options] FILENAMEs\n\n" + "Options:\n" + " --verbose run in verbose mode\n" + " --url import from given URLs\n" + " -0 URLs are delimited by a nul\n" + , stderr); + exit (ex); +} + +int +main (int argc, char **argv) +{ + int last_argc = -1; + gpgme_error_t err; + gpgme_ctx_t ctx; + int url_mode = 0; + int nul_mode = 0; + gpgme_import_result_t impres; + gpgme_data_t data; + + if (argc) + { argc--; argv++; } + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + show_usage (0); + else if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--url")) + { + url_mode = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "-0")) + { + nul_mode = 1; + argc--; argv++; + } + else if (!strncmp (*argv, "--", 2)) + show_usage (1); + + } + + if (!argc) + show_usage (1); + + init_gpgme (GPGME_PROTOCOL_OpenPGP); + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP); + + for (; argc; argc--, argv++) + { + printf ("reading file `%s'\n", *argv); + err = gpgme_data_new_from_file (&data, *argv, 1); + fail_if_err (err); + + if (url_mode) + gpgme_data_set_encoding (data, (nul_mode? GPGME_DATA_ENCODING_URL0 + : GPGME_DATA_ENCODING_URL)); + + err = gpgme_op_import (ctx, data); + fail_if_err (err); + impres = gpgme_op_import_result (ctx); + if (!impres) + { + fprintf (stderr, PGM ": no import result returned\n"); + exit (1); + } + print_import_result (impres); + + gpgme_data_release (data); + } + + gpgme_release (ctx); + return 0; +} Property changes on: trunk/tests/run-import.c ___________________________________________________________________ Name: svn:mergeinfo + Copied: trunk/tests/run-keylist.c (from rev 1389, trunk/tests/gpg/pgp-keylist.c) =================================================================== --- trunk/tests/run-keylist.c (rev 0) +++ trunk/tests/run-keylist.c 2009-07-07 14:17:39 UTC (rev 1391) @@ -0,0 +1,223 @@ +/* run-keylist.c - Helper to show a key listing. + Copyright (C) 2008, 2009 g10 Code GmbH + + This file is part of GPGME. + + GPGME 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. + + GPGME 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, see . +*/ + +/* We need to include config.h so that we know whether we are building + with large file system (LFS) support. */ +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include + +#include + +#define PGM "run-keylist" + +#include "run-support.h" + + +static int verbose; + + +static int +show_usage (int ex) +{ + fputs ("usage: " PGM " [options] [USERID]\n\n" + "Options:\n" + " --verbose run in verbose mode\n" + " --local use GPGME_KEYLIST_MODE_LOCAL\n" + " --extern use GPGME_KEYLIST_MODE_EXTERN\n" + " --sigs use GPGME_KEYLIST_MODE_SIGS\n" + " --sig-notations use GPGME_KEYLIST_MODE_SIG_NOTATIONS\n" + " --ephemeral use GPGME_KEYLIST_MODE_EPHEMERAL\n" + " --validate use GPGME_KEYLIST_MODE_VALIDATE\n" + " --import import all keys\n" + , stderr); + exit (ex); +} + +int +main (int argc, char **argv) +{ + int last_argc = -1; + gpgme_error_t err; + gpgme_ctx_t ctx; + gpgme_keylist_mode_t mode = 0; + gpgme_key_t key; + gpgme_keylist_result_t result; + int import = 0; + gpgme_key_t keyarray[100]; + int keyidx = 0; + + if (argc) + { argc--; argv++; } + + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + show_usage (0); + else if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--local")) + { + mode |= GPGME_KEYLIST_MODE_LOCAL; + argc--; argv++; + } + else if (!strcmp (*argv, "--extern")) + { + mode |= GPGME_KEYLIST_MODE_EXTERN; + argc--; argv++; + } + else if (!strcmp (*argv, "--sigs")) + { + mode |= GPGME_KEYLIST_MODE_SIGS; + argc--; argv++; + } + else if (!strcmp (*argv, "--sig-notations")) + { + mode |= GPGME_KEYLIST_MODE_SIG_NOTATIONS; + argc--; argv++; + } + else if (!strcmp (*argv, "--ephemeral")) + { + mode |= GPGME_KEYLIST_MODE_EPHEMERAL; + argc--; argv++; + } + else if (!strcmp (*argv, "--validate")) + { + mode |= GPGME_KEYLIST_MODE_VALIDATE; + argc--; argv++; + } + else if (!strcmp (*argv, "--import")) + { + import = 1; + argc--; argv++; + } + else if (!strncmp (*argv, "--", 2)) + show_usage (1); + + } + + if (argc > 1) + show_usage (1); + + init_gpgme (GPGME_PROTOCOL_OpenPGP); + + err = gpgme_new (&ctx); + fail_if_err (err); + gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP); + + gpgme_set_keylist_mode (ctx, mode); + + err = gpgme_op_keylist_start (ctx, argc? argv[0]:NULL, 0); + fail_if_err (err); + + while (!(err = gpgme_op_keylist_next (ctx, &key))) + { + gpgme_user_id_t uid; + int nuids; + + + printf ("keyid : %s\n", key->subkeys?nonnull (key->subkeys->keyid):"?"); + printf ("fpr : %s\n", key->subkeys?nonnull (key->subkeys->fpr):"?"); + printf ("caps : %s%s%s%s\n", + key->can_encrypt? "e":"", + key->can_sign? "s":"", + key->can_certify? "c":"", + key->can_authenticate? "a":""); + printf ("flags :%s%s%s%s%s%s\n", + key->secret? " secret":"", + key->revoked? " revoked":"", + key->expired? " expired":"", + key->disabled? " disabled":"", + key->invalid? " invalid":"", + key->is_qualified? " qualifid":""); + for (nuids=0, uid=key->uids; uid; uid = uid->next, nuids++) + { + printf ("userid %d: %s\n", nuids, nonnull(uid->uid)); + printf ("valid %d: %s\n", nuids, + uid->validity == GPGME_VALIDITY_UNKNOWN? "unknown": + uid->validity == GPGME_VALIDITY_UNDEFINED? "undefined": + uid->validity == GPGME_VALIDITY_NEVER? "never": + uid->validity == GPGME_VALIDITY_MARGINAL? "marginal": + uid->validity == GPGME_VALIDITY_FULL? "full": + uid->validity == GPGME_VALIDITY_ULTIMATE? "ultimate": "[?]"); + } + + putchar ('\n'); + + if (import) + { + if (keyidx < DIM (keyarray)-1) + keyarray[keyidx++] = key; + else + { + fprintf (stderr, PGM": too many keys in import mode" + "- skipping this key\n"); + gpgme_key_unref (key); + } + } + else + gpgme_key_unref (key); + } + if (gpg_err_code (err) != GPG_ERR_EOF) + fail_if_err (err); + err = gpgme_op_keylist_end (ctx); + fail_if_err (err); + keyarray[keyidx] = NULL; + + result = gpgme_op_keylist_result (ctx); + if (result->truncated) + { + fprintf (stderr, PGM ": key listing unexpectedly truncated\n"); + exit (1); + } + + if (import) + { + gpgme_import_result_t impres; + + err = gpgme_op_import_keys (ctx, keyarray); + fail_if_err (err); + impres = gpgme_op_import_result (ctx); + if (!impres) + { + fprintf (stderr, PGM ": no import result returned\n"); + exit (1); + } + print_import_result (impres); + } + + for (keyidx=0; keyarray[keyidx]; keyidx++) + gpgme_key_unref (keyarray[keyidx]); + + gpgme_release (ctx); + return 0; +} Property changes on: trunk/tests/run-keylist.c ___________________________________________________________________ Name: svn:mergeinfo + From cvs at cvs.gnupg.org Tue Jul 7 16:33:11 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 07 Jul 2009 16:33:11 +0200 Subject: [svn] gpgme - r1392 - in trunk: src tests Message-ID: Author: wk Date: 2009-07-07 16:33:10 +0200 (Tue, 07 Jul 2009) New Revision: 1392 Modified: trunk/src/ChangeLog trunk/src/engine-gpg.c trunk/src/engine-gpgsm.c trunk/tests/ChangeLog trunk/tests/run-keylist.c Log: Inmplement import from keys for GPGSM. Add option --cms to run-keylist test program. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-07-07 14:17:39 UTC (rev 1391) +++ trunk/src/ChangeLog 2009-07-07 14:33:10 UTC (rev 1392) @@ -1,5 +1,12 @@ 2009-07-07 Werner Koch + * engine-gpgsm.c (struct engine_gpgsm): Add fields + input_helper_data and input_helper_memory. + (close_notify_handler): Release these new fields. + (gpgsm_import): Implement the keyarray feature. + + * engine-gpg.c (gpg_import): Actually return GPG_ERR_INV_VALUE. + * engine-gpgsm.c (gpgsm_import): Return an error for unknown data encodings. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-07-07 14:17:39 UTC (rev 1391) +++ trunk/tests/ChangeLog 2009-07-07 14:33:10 UTC (rev 1392) @@ -1,5 +1,7 @@ 2009-07-07 Werner Koch + * run-keylist.c (main): Add options --cms and --openpgp. + * gpg/pgp-keylist.c: Rename to ... * run-keylist.c: ... this. * gpg/pgp-import.c: Rename to ... Modified: trunk/src/engine-gpg.c =================================================================== --- trunk/src/engine-gpg.c 2009-07-07 14:17:39 UTC (rev 1391) +++ trunk/src/engine-gpg.c 2009-07-07 14:33:10 UTC (rev 1392) @@ -1914,7 +1914,7 @@ gpgme_data_encoding_t dataenc; if (keydata && keyarray) - gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */ + return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */ dataenc = gpgme_data_get_encoding (keydata); Modified: trunk/src/engine-gpgsm.c =================================================================== --- trunk/src/engine-gpgsm.c 2009-07-07 14:17:39 UTC (rev 1391) +++ trunk/src/engine-gpgsm.c 2009-07-07 14:33:10 UTC (rev 1392) @@ -70,6 +70,8 @@ /* Input, output etc are from the servers perspective. */ iocb_data_t input_cb; + gpgme_data_t input_helper_data; /* Input helper data object. */ + void *input_helper_memory; /* Input helper memory block. */ iocb_data_t output_cb; @@ -141,6 +143,16 @@ (*gpgsm->io_cbs.remove) (gpgsm->input_cb.tag); gpgsm->input_cb.fd = -1; gpgsm->input_cb.tag = NULL; + if (gpgsm->input_helper_data) + { + gpgme_data_release (gpgsm->input_helper_data); + gpgsm->input_helper_data = NULL; + } + if (gpgsm->input_helper_memory) + { + free (gpgsm->input_helper_memory); + gpgsm->input_helper_memory = NULL; + } } else if (gpgsm->output_cb.fd == fd) { @@ -1545,18 +1557,79 @@ engine_gpgsm_t gpgsm = engine; gpgme_error_t err; gpgme_data_encoding_t dataenc; + int idx; if (!gpgsm) return gpg_error (GPG_ERR_INV_VALUE); if (keydata && keyarray) - gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */ + return gpg_error (GPG_ERR_INV_VALUE); /* Only one is allowed. */ dataenc = gpgme_data_get_encoding (keydata); if (keyarray) { - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + size_t buflen; + char *buffer, *p; + + /* Fist check whether the engine already features the + --re-import option. */ + err = gpgsm_assuan_simple_command + (gpgsm->assuan_ctx, + "GETINFO cmd_has_option IMPORT re-import", NULL, NULL); + if (err) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + /* Create an internal data object with a list of all + fingerprints. The data object and its memory (to avoid an + extra copy by gpgme_data_new_from_mem) are stored in two + variables which are released by the close_notify_handler. */ + for (idx=0, buflen=0; keyarray[idx]; idx++) + { + if (keyarray[idx]->protocol == GPGME_PROTOCOL_CMS + && keyarray[idx]->subkeys + && keyarray[idx]->subkeys->fpr + && *keyarray[idx]->subkeys->fpr) + buflen += strlen (keyarray[idx]->subkeys->fpr) + 1; + } + /* Allocate a bufer with extra space for the trailing Nul + introduced by the use of stpcpy. */ + buffer = malloc (buflen+1); + if (!buffer) + return gpg_error_from_syserror (); + for (idx=0, p = buffer; keyarray[idx]; idx++) + { + if (keyarray[idx]->protocol == GPGME_PROTOCOL_CMS + && keyarray[idx]->subkeys + && keyarray[idx]->subkeys->fpr + && *keyarray[idx]->subkeys->fpr) + p = stpcpy (stpcpy (p, keyarray[idx]->subkeys->fpr), "\n"); + } + + err = gpgme_data_new_from_mem (&gpgsm->input_helper_data, + buffer, buflen, 0); + if (err) + { + free (buffer); + return err; + } + gpgsm->input_helper_memory = buffer; + + gpgsm->input_cb.data = gpgsm->input_helper_data; + err = gpgsm_set_fd (gpgsm, INPUT_FD, map_data_enc (gpgsm->input_cb.data)); + if (err) + { + gpgme_data_release (gpgsm->input_helper_data); + gpgsm->input_helper_data = NULL; + free (gpgsm->input_helper_memory); + gpgsm->input_helper_memory = NULL; + return err; + } + gpgsm_clear_fd (gpgsm, OUTPUT_FD); + gpgsm_clear_fd (gpgsm, MESSAGE_FD); + gpgsm->inline_data = NULL; + + return start (gpgsm, "IMPORT --re-import"); } else if (dataenc == GPGME_DATA_ENCODING_URL || dataenc == GPGME_DATA_ENCODING_URL0 @@ -1573,10 +1646,9 @@ gpgsm_clear_fd (gpgsm, OUTPUT_FD); gpgsm_clear_fd (gpgsm, MESSAGE_FD); gpgsm->inline_data = NULL; + + return start (gpgsm, "IMPORT"); } - - err = start (gpgsm, "IMPORT"); - return err; } Modified: trunk/tests/run-keylist.c =================================================================== --- trunk/tests/run-keylist.c 2009-07-07 14:17:39 UTC (rev 1391) +++ trunk/tests/run-keylist.c 2009-07-07 14:33:10 UTC (rev 1392) @@ -43,6 +43,8 @@ fputs ("usage: " PGM " [options] [USERID]\n\n" "Options:\n" " --verbose run in verbose mode\n" + " --openpgp use the OpenPGP protocol (default)\n" + " --cms use the CMS protocol\n" " --local use GPGME_KEYLIST_MODE_LOCAL\n" " --extern use GPGME_KEYLIST_MODE_EXTERN\n" " --sigs use GPGME_KEYLIST_MODE_SIGS\n" @@ -54,6 +56,7 @@ exit (ex); } + int main (int argc, char **argv) { @@ -66,6 +69,7 @@ int import = 0; gpgme_key_t keyarray[100]; int keyidx = 0; + gpgme_protocol_t protocol = GPGME_PROTOCOL_OpenPGP; if (argc) { argc--; argv++; } @@ -85,6 +89,16 @@ verbose = 1; argc--; argv++; } + else if (!strcmp (*argv, "--openpgp")) + { + protocol = GPGME_PROTOCOL_OpenPGP; + argc--; argv++; + } + else if (!strcmp (*argv, "--cms")) + { + protocol = GPGME_PROTOCOL_CMS; + argc--; argv++; + } else if (!strcmp (*argv, "--local")) { mode |= GPGME_KEYLIST_MODE_LOCAL; @@ -128,11 +142,11 @@ if (argc > 1) show_usage (1); - init_gpgme (GPGME_PROTOCOL_OpenPGP); + init_gpgme (protocol); err = gpgme_new (&ctx); fail_if_err (err); - gpgme_set_protocol (ctx, GPGME_PROTOCOL_OpenPGP); + gpgme_set_protocol (ctx, protocol); gpgme_set_keylist_mode (ctx, mode); From cvs at cvs.gnupg.org Tue Jul 7 18:51:34 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 07 Jul 2009 18:51:34 +0200 Subject: [svn] GnuPG - r5066 - trunk/jnlib Message-ID: Author: wk Date: 2009-07-07 18:51:33 +0200 (Tue, 07 Jul 2009) New Revision: 5066 Modified: trunk/jnlib/ChangeLog trunk/jnlib/dotlock.c trunk/jnlib/logging.c trunk/jnlib/stringhelp.c trunk/jnlib/strlist.c trunk/jnlib/utf8conv.c Log: Minor bug fixes. Enhanced function docs. Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2009-07-07 10:29:52 UTC (rev 5065) +++ trunk/jnlib/ChangeLog 2009-07-07 16:51:33 UTC (rev 5066) @@ -1,3 +1,9 @@ +2009-07-07 Werner Koch + + * stringhelp.c (make_filename_try): Use jnlib_malloc. + + * dotlock.c (read_lockfile): Replace jnlib_xmalloc by jnlib_malloc. + 2009-06-04 Werner Koch * mischelp.h: Include SUN_LEN etc also for W32. Modified: trunk/jnlib/dotlock.c =================================================================== --- trunk/jnlib/dotlock.c 2009-07-07 10:29:52 UTC (rev 5065) +++ trunk/jnlib/dotlock.c 2009-07-07 16:51:33 UTC (rev 5066) @@ -598,7 +598,11 @@ *same_node = 0; expected_len = 10 + 1 + h->nodename_len + 1; if ( expected_len >= sizeof buffer_space) - buffer = jnlib_xmalloc (expected_len); + { + buffer = jnlib_malloc (expected_len); + if (!buffer) + return -1; + } else buffer = buffer_space; Modified: trunk/jnlib/logging.c =================================================================== --- trunk/jnlib/logging.c 2009-07-07 10:29:52 UTC (rev 5065) +++ trunk/jnlib/logging.c 2009-07-07 16:51:33 UTC (rev 5066) @@ -267,6 +267,9 @@ /* Setup a new stream. */ #ifdef USE_FUNWRITER + /* The xmalloc below is justified because we can expect that this + function is called only during initialization and there is no + easy way out of this error condition. */ cookie = jnlib_xmalloc (sizeof *cookie + (name? strlen (name):0)); strcpy (cookie->name, name? name:""); cookie->quiet = 0; Modified: trunk/jnlib/stringhelp.c =================================================================== --- trunk/jnlib/stringhelp.c 2009-07-07 10:29:52 UTC (rev 5065) +++ trunk/jnlib/stringhelp.c 2009-07-07 16:51:33 UTC (rev 5066) @@ -252,9 +252,9 @@ -/*************** - * Extract from a given path the filename component. - * +/* + * Extract from a given path the filename component. This function + * terminates the process on memory shortage. */ char * make_basename(const char *filepath, const char *inputpath) @@ -281,11 +281,10 @@ -/*************** - * Extract from a given filename the path prepended to it. - * If their isn't a path prepended to the filename, a dot - * is returned ('.'). - * +/* + * Extract from a given filename the path prepended to it. If there + * isn't a path prepended to the filename, a dot is returned ('.'). + * This function terminates the process on memory shortage. */ char * make_dirname(const char *filepath) @@ -346,7 +345,8 @@ /* Construct a filename from the NULL terminated list of parts. Tilde - expansion is done here. This function will never fail. */ + expansion is done here. This function terminates the process on + memory shortage. */ char * make_filename (const char *first_part, ... ) { @@ -361,7 +361,7 @@ make_filename_try (const char *first_part, ... ) { MAKE_FILENAME_PART1 - name = jnlib_xmalloc (n); + name = jnlib_malloc (n); if (!name) return NULL; MAKE_FILENAME_PART2 @@ -550,8 +550,9 @@ delim) : 0; } -/* Create a string from the buffer P_ARG of length N which is suitable for - printing. Caller must release the created string using xfree. */ +/* Create a string from the buffer P_ARG of length N which is suitable + for printing. Caller must release the created string using xfree. + This function terminates the process on memory shortage. */ char * sanitize_buffer (const void *p_arg, size_t n, int delim) { @@ -940,7 +941,8 @@ } /* Percent-escape the string STR by replacing colons with '%3a'. If - EXTRA is not NULL all characters in EXTRA are also escaped. */ + EXTRA is not NULL all characters in EXTRA are also escaped. This + function terminates the process on memory shortage. */ char * percent_escape (const char *str, const char *extra) { Modified: trunk/jnlib/strlist.c =================================================================== --- trunk/jnlib/strlist.c 2009-07-07 10:29:52 UTC (rev 5065) +++ trunk/jnlib/strlist.c 2009-07-07 16:51:33 UTC (rev 5066) @@ -41,6 +41,8 @@ } +/* Add STRING to the LIST at the front. This function terminates the + process on memory shortage. */ strlist_t add_to_strlist( strlist_t *list, const char *string ) { @@ -55,8 +57,9 @@ } -/* Same as add_to_strlist() but if is_utf8 is *not* set, a conversion - to UTF-8 is done. */ +/* Same as add_to_strlist() but if IS_UTF8 is *not* set, a conversion + to UTF-8 is done. This function terminates the process on memory + shortage. */ #ifdef JNLIB_NEED_UTF8CONV strlist_t add_to_strlist2( strlist_t *list, const char *string, int is_utf8 ) @@ -75,6 +78,9 @@ } #endif /* JNLIB_NEED_UTF8CONV*/ + +/* Add STRING to the LIST at the end. This function terminates the + process on memory shortage. */ strlist_t append_to_strlist( strlist_t *list, const char *string ) { @@ -114,7 +120,8 @@ #endif /* JNLIB_NEED_UTF8CONV */ -/* Return a copy of LIST. */ +/* Return a copy of LIST. This function terminates the process on + memory shortage.*/ strlist_t strlist_copy (strlist_t list) { @@ -155,6 +162,9 @@ } +/* Remove the first item from LIST and return its content in an + allocated buffer. This function terminates the process on memory + shortage. */ char * strlist_pop (strlist_t *list) { Modified: trunk/jnlib/utf8conv.c =================================================================== --- trunk/jnlib/utf8conv.c 2009-07-07 10:29:52 UTC (rev 5065) +++ trunk/jnlib/utf8conv.c 2009-07-07 16:51:33 UTC (rev 5066) @@ -314,7 +314,8 @@ /* Convert string, which is in native encoding to UTF8 and return a - new allocated UTF-8 string. */ + new allocated UTF-8 string. This function terminates the process + on memory shortage. */ char * native_to_utf8 (const char *orig_string) { @@ -682,7 +683,8 @@ illegal encodings by some "\xnn" and quote all control characters. A character with value DELIM will always be quoted, it must be a vanilla ASCII character. A DELIM value of -1 is special: - it disables all quoting of control characters. */ + it disables all quoting of control characters. This function + terminates the process on memory shortage. */ char * utf8_to_native (const char *string, size_t length, int delim) { From cvs at cvs.gnupg.org Tue Jul 7 18:52:13 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 07 Jul 2009 18:52:13 +0200 Subject: [svn] GnuPG - r5067 - in trunk: . agent doc sm Message-ID: Author: wk Date: 2009-07-07 18:52:12 +0200 (Tue, 07 Jul 2009) New Revision: 5067 Modified: trunk/NEWS trunk/TODO trunk/agent/command.c trunk/doc/gpgsm.texi trunk/sm/ChangeLog trunk/sm/gpgsm.h trunk/sm/import.c trunk/sm/server.c Log: Impleemned gpgsm's IMPORT --re-import feature. Typo fix. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-07-07 16:51:33 UTC (rev 5066) +++ trunk/sm/ChangeLog 2009-07-07 16:52:12 UTC (rev 5067) @@ -1,5 +1,11 @@ 2009-07-07 Werner Koch + * server.c (command_has_option): New. + (cmd_getinfo): Add subcommand "cmd_has_option". + (cmd_import): Implement option --re-import. + * import.c (gpgsm_import): Add arg reimport_mode. + (reimport_one): New. + * gpgsm.h: Include session-env.h. (opt): Add field SESSION_ENV. Remove obsolete fields. * server.c (option_handler): Rewrite setting of option fields. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-07-07 16:51:33 UTC (rev 5066) +++ trunk/NEWS 2009-07-07 16:52:12 UTC (rev 5067) @@ -8,6 +8,8 @@ * gpgsm --gen-key implements all features of gpgsm-gencert.sh. + * New option --re-import for gpgsm's IMPORT server command. + * Minor bug fixes. Modified: trunk/TODO =================================================================== --- trunk/TODO 2009-07-07 16:51:33 UTC (rev 5066) +++ trunk/TODO 2009-07-07 16:52:12 UTC (rev 5067) @@ -82,9 +82,6 @@ ** check that we issue NO_SECKEY xxx if a -u key was not found We don't. The messages returned are also wrong (recipient vs. signer). -* jnlib/ -** Try to remove all jnlib_xmalloc. - * g10/ ** issue a NO_SECKEY xxxx if a -u key was not found. Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2009-07-07 16:51:33 UTC (rev 5066) +++ trunk/agent/command.c 2009-07-07 16:52:12 UTC (rev 5067) @@ -1802,7 +1802,7 @@ } -/* Return true if the commznd CMD implements the option OPT. */ +/* Return true if the command CMD implements the option OPT. */ static int command_has_option (const char *cmd, const char *cmdopt) { Modified: trunk/doc/gpgsm.texi =================================================================== --- trunk/doc/gpgsm.texi 2009-07-07 16:51:33 UTC (rev 5066) +++ trunk/doc/gpgsm.texi 2009-07-07 16:52:12 UTC (rev 5067) @@ -1219,15 +1219,20 @@ To import certificates into the internal key database, the command @example - IMPORT + IMPORT [--re-import] @end example is used. The data is expected on the file descriptor set with the @code{INPUT} command. Certain checks are performend on the -certificate. Note that the code will also handle PKCS\#12 files and +certificate. Note that the code will also handle PKCS#12 files and import private keys; a helper program is used for that. +With the option @option{--re-import} the input data is expected to a be +a linefeed separated list of fingerprints. The command will re-import +the corresponding certificates; that is they are made permanent by +removing their ephemeral flag. + @node GPGSM DELETE @subsection Delete certificates @@ -1259,6 +1264,11 @@ Return the version of the program. @item pid Return the process id of the process. + at item agent-check +Return success if the agent is running. + at item cmd_has_option @var{cmd} @var{opt} +Return success if the command @var{cmd} implements the option @var{opt}. +The leading two dashes usually used with @var{opt} shall not be given. @end table @mansect see also Modified: trunk/sm/gpgsm.h =================================================================== --- trunk/sm/gpgsm.h 2009-07-07 16:51:33 UTC (rev 5066) +++ trunk/sm/gpgsm.h 2009-07-07 16:52:12 UTC (rev 5067) @@ -333,7 +333,7 @@ estream_t fp, unsigned int mode); /*-- import.c --*/ -int gpgsm_import (ctrl_t ctrl, int in_fd); +int gpgsm_import (ctrl_t ctrl, int in_fd, int reimport_mode); int gpgsm_import_files (ctrl_t ctrl, int nfiles, char **files, int (*of)(const char *fname)); Modified: trunk/sm/import.c =================================================================== --- trunk/sm/import.c 2009-07-07 16:51:33 UTC (rev 5066) +++ trunk/sm/import.c 2009-07-07 16:52:12 UTC (rev 5067) @@ -1,5 +1,5 @@ /* import.c - Import certificates - * Copyright (C) 2001, 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2004, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -34,7 +34,9 @@ #include "exechelp.h" #include "i18n.h" #include "sysutils.h" +#include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */ + struct stats_s { unsigned long count; unsigned long imported; @@ -405,14 +407,136 @@ } + +/* Re-import certifciates. IN_FD is a list of linefeed delimited + fingerprints t re-import. The actual re-import is done by clearing + the ephemeral flag. */ +static int +reimport_one (ctrl_t ctrl, struct stats_s *stats, int in_fd) +{ + gpg_error_t err = 0; + estream_t fp = NULL; + char line[100]; /* Sufficient for a fingerprint. */ + KEYDB_HANDLE kh; + KEYDB_SEARCH_DESC desc; + ksba_cert_t cert = NULL; + unsigned int flags; + + kh = keydb_new (0); + if (!kh) + { + err = gpg_error (GPG_ERR_ENOMEM);; + log_error (_("failed to allocate keyDB handle\n")); + goto leave; + } + keydb_set_ephemeral (kh, 1); + + fp = es_fdopen_nc (in_fd, "r"); + if (!fp) + { + err = gpg_error_from_syserror (); + log_error ("es_fdopen(%d) failed: %s\n", in_fd, gpg_strerror (err)); + goto leave; + } + + while (es_fgets (line, DIM(line)-1, fp) ) + { + if (*line && line[strlen(line)-1] != '\n') + { + err = gpg_error (GPG_ERR_LINE_TOO_LONG); + goto leave; + } + trim_spaces (line); + if (!*line) + continue; + + stats->count++; + + err = keydb_classify_name (line, &desc); + if (err) + { + print_import_problem (ctrl, NULL, 0); + stats->not_imported++; + continue; + } + + keydb_search_reset (kh); + err = keydb_search (kh, &desc, 1); + if (err) + { + print_import_problem (ctrl, NULL, 0); + stats->not_imported++; + continue; + } + + ksba_cert_release (cert); + cert = NULL; + err = keydb_get_cert (kh, &cert); + if (err) + { + log_error ("keydb_get_cert() failed: %s\n", gpg_strerror (err)); + print_import_problem (ctrl, NULL, 1); + stats->not_imported++; + continue; + } + + err = keydb_get_flags (kh, KEYBOX_FLAG_BLOB, 0, &flags); + if (err) + { + log_error (_("error getting stored flags: %s\n"), gpg_strerror (err)); + print_imported_status (ctrl, cert, 0); + stats->not_imported++; + continue; + } + if ( !(flags & KEYBOX_FLAG_BLOB_EPHEMERAL) ) + { + print_imported_status (ctrl, cert, 0); + stats->unchanged++; + continue; + } + + err = keydb_set_cert_flags (cert, 1, KEYBOX_FLAG_BLOB, 0, + KEYBOX_FLAG_BLOB_EPHEMERAL, 0); + if (err) + { + log_error ("clearing ephemeral flag failed: %s\n", + gpg_strerror (err)); + print_import_problem (ctrl, cert, 0); + stats->not_imported++; + continue; + } + + print_imported_status (ctrl, cert, 1); + stats->imported++; + } + err = 0; + if (es_ferror (fp)) + { + err = gpg_error_from_syserror (); + log_error ("error reading fd %d: %s\n", in_fd, gpg_strerror (err)); + goto leave; + } + + leave: + ksba_cert_release (cert); + keydb_release (kh); + es_fclose (fp); + return err; +} + + + int -gpgsm_import (ctrl_t ctrl, int in_fd) +gpgsm_import (ctrl_t ctrl, int in_fd, int reimport_mode) { int rc; struct stats_s stats; memset (&stats, 0, sizeof stats); - rc = import_one (ctrl, &stats, in_fd); + if (reimport_mode) + rc = reimport_one (ctrl, &stats, in_fd); + else + rc = import_one (ctrl, &stats, in_fd); print_imported_summary (ctrl, &stats); /* If we never printed an error message do it now so that a command line invocation will return with an error (log_error keeps a Modified: trunk/sm/server.c =================================================================== --- trunk/sm/server.c 2009-07-07 16:51:33 UTC (rev 5066) +++ trunk/sm/server.c 2009-07-07 16:52:12 UTC (rev 5067) @@ -1,6 +1,6 @@ /* server.c - Server mode and main entry point * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, - * 2007, 2008 Free Software Foundation, Inc. + * 2007, 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -68,7 +68,11 @@ }; + +static int command_has_option (const char *cmd, const char *cmdopt); + + /* Note that it is sufficient to allocate the target string D as long as the source string S, i.e.: strlen(s)+1; */ @@ -638,25 +642,31 @@ } -/* IMPORT +/* IMPORT [--re-import] - Import the certificates read form the input-fd, return status - message for each imported one. The import checks the validity of - the certificate but not of the entire chain. It is possible to - import expired certificates. */ + Import the certificates read form the input-fd, return status + message for each imported one. The import checks the validity of + the certificate but not of the entire chain. It is possible to + import expired certificates. + + With the option --re-import the input data is expected to a be a LF + separated list of fingerprints. The command will re-import these + certificates, meaning that they are made permanent by removing + their ephemeral flag. */ static int cmd_import (assuan_context_t ctx, char *line) { ctrl_t ctrl = assuan_get_pointer (ctx); int rc; int fd = translate_sys2libc_fd (assuan_get_input_fd (ctx), 0); + int reimport = has_option (line, "--re-import"); (void)line; if (fd == -1) return set_error (GPG_ERR_ASS_NO_INPUT, NULL); - rc = gpgsm_import (assuan_get_pointer (ctx), fd); + rc = gpgsm_import (assuan_get_pointer (ctx), fd, reimport); /* close and reset the fd */ close_message_fd (ctrl); @@ -1029,12 +1039,14 @@ version - Return the version of the program. pid - Return the process id of the server. agent-check - Return success if the agent is running. + cmd_has_option CMD OPT + - Returns OK if the command CMD implements the option OPT. */ static int cmd_getinfo (assuan_context_t ctx, char *line) { - int rc; + int rc = 0; if (!strcmp (line, "version")) { @@ -1053,13 +1065,60 @@ ctrl_t ctrl = assuan_get_pointer (ctx); rc = gpgsm_agent_send_nop (ctrl); } + else if (!strncmp (line, "cmd_has_option", 14) + && (line[14] == ' ' || line[14] == '\t' || !line[14])) + { + char *cmd, *cmdopt; + line += 14; + while (*line == ' ' || *line == '\t') + line++; + if (!*line) + rc = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + cmd = line; + while (*line && (*line != ' ' && *line != '\t')) + line++; + if (!*line) + rc = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + *line++ = 0; + while (*line == ' ' || *line == '\t') + line++; + if (!*line) + rc = gpg_error (GPG_ERR_MISSING_VALUE); + else + { + cmdopt = line; + if (!command_has_option (cmd, cmdopt)) + rc = gpg_error (GPG_ERR_GENERAL); + } + } + } + } else rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); + return rc; } +/* Return true if the command CMD implements the option OPT. */ +static int +command_has_option (const char *cmd, const char *cmdopt) +{ + if (!strcmp (cmd, "IMPORT")) + { + if (!strcmp (cmdopt, "re-import")) + return 1; + } + + return 0; +} + + /* Tell the assuan library about our commands */ static int register_commands (assuan_context_t ctx) From cvs at cvs.gnupg.org Wed Jul 8 05:50:27 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Wed, 08 Jul 2009 05:50:27 +0200 Subject: [svn] GnuPG - r5068 - branches/STABLE-BRANCH-1-4/keyserver Message-ID: Author: dshaw Date: 2009-07-08 05:50:26 +0200 (Wed, 08 Jul 2009) New Revision: 5068 Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c Log: * gpgkeys_hkp.c (main, srv_replace): Minor tweaks to use the DNS-SD names ("pgpkey-http" and "pgpkey-https") in SRV lookups instead of "hkp" and "hkps". Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-07-07 16:52:12 UTC (rev 5067) +++ branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-07-08 03:50:26 UTC (rev 5068) @@ -1,3 +1,9 @@ +2009-07-06 David Shaw + + * gpgkeys_hkp.c (main, srv_replace): Minor tweaks to use the + DNS-SD names ("pgpkey-http" and "pgpkey-https") in SRV lookups + instead of "hkp" and "hkps". + 2009-06-24 Werner Koch * gpgkeys_ldap.c (send_key): Do not loop over a NULL modlist in Modified: branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-07-07 16:52:12 UTC (rev 5067) +++ branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-07-08 03:50:26 UTC (rev 5068) @@ -494,18 +494,21 @@ /* If there is a SRV record, take the highest ranked possibility. This is a hack, as we don't proceed downwards. */ static void -srv_replace(void) +srv_replace(const char *srvtag) { #ifdef USE_DNS_SRV struct srventry *srvlist=NULL; int srvcount; - if(1+strlen(opt->scheme)+6+strlen(opt->host)+1<=MAXDNAME) + if(!srvtag) + return; + + if(1+strlen(srvtag)+6+strlen(opt->host)+1<=MAXDNAME) { char srvname[MAXDNAME]; strcpy(srvname,"_"); - strcat(srvname,opt->scheme); + strcat(srvname,srvtag); strcat(srvname,"._tcp."); strcat(srvname,opt->host); srvcount=getsrv(srvname,&srvlist); @@ -720,17 +723,26 @@ port=opt->port; else if(try_srv) { + char *srvtag; + + if(ascii_strcasecmp(opt->scheme,"hkp")==0) + srvtag="pgpkey-http"; + else if(ascii_strcasecmp(opt->scheme,"hkps")==0) + srvtag="pgpkey-https"; + else + srvtag=NULL; + #ifdef HAVE_LIBCURL /* We're using libcurl, so fake SRV support via our wrapper. This isn't as good as true SRV support, as we do not try all possible targets at one particular level and work our way down the list, but it's better than nothing. */ - srv_replace(); + srv_replace(srvtag); #else /* We're using our internal curl shim, so we can use its (true) SRV support. Obviously, CURLOPT_SRVTAG_GPG_HACK isn't a real libcurl option. It's specific to our shim. */ - curl_easy_setopt(curl,CURLOPT_SRVTAG_GPG_HACK,opt->scheme); + curl_easy_setopt(curl,CURLOPT_SRVTAG_GPG_HACK,srvtag); #endif } From cvs at cvs.gnupg.org Wed Jul 8 06:01:13 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Wed, 08 Jul 2009 06:01:13 +0200 Subject: [svn] GnuPG - r5069 - trunk/keyserver Message-ID: Author: dshaw Date: 2009-07-08 06:01:13 +0200 (Wed, 08 Jul 2009) New Revision: 5069 Modified: trunk/keyserver/ChangeLog trunk/keyserver/gpgkeys_hkp.c Log: * gpgkeys_hkp.c (main, srv_replace): Minor tweaks to use the DNS-SD names ("pgpkey-http" and "pgpkey-https") in SRV lookups instead of "hkp" and "hkps". Modified: trunk/keyserver/ChangeLog =================================================================== --- trunk/keyserver/ChangeLog 2009-07-08 03:50:26 UTC (rev 5068) +++ trunk/keyserver/ChangeLog 2009-07-08 04:01:13 UTC (rev 5069) @@ -1,3 +1,9 @@ +2009-07-06 David Shaw + + * gpgkeys_hkp.c (main, srv_replace): Minor tweaks to use the + DNS-SD names ("pgpkey-http" and "pgpkey-https") in SRV lookups + instead of "hkp" and "hkps". + 2009-06-24 Werner Koch * gpgkeys_ldap.c (send_key): Do not deep free a NULL modlist. Modified: trunk/keyserver/gpgkeys_hkp.c =================================================================== --- trunk/keyserver/gpgkeys_hkp.c 2009-07-08 03:50:26 UTC (rev 5068) +++ trunk/keyserver/gpgkeys_hkp.c 2009-07-08 04:01:13 UTC (rev 5069) @@ -489,18 +489,21 @@ /* If there is a SRV record, take the highest ranked possibility. This is a hack, as we don't proceed downwards. */ static void -srv_replace(void) +srv_replace(const char *srvtag) { #ifdef USE_DNS_SRV struct srventry *srvlist=NULL; int srvcount; - if(1+strlen(opt->scheme)+6+strlen(opt->host)+1<=MAXDNAME) + if(!srvtag) + return; + + if(1+strlen(srvtag)+6+strlen(opt->host)+1<=MAXDNAME) { char srvname[MAXDNAME]; strcpy(srvname,"_"); - strcat(srvname,opt->scheme); + strcat(srvname,srvtag); strcat(srvname,"._tcp."); strcat(srvname,opt->host); srvcount=getsrv(srvname,&srvlist); @@ -714,17 +717,26 @@ port=opt->port; else if(try_srv) { + char *srvtag; + + if(ks_strcasecmp(opt->scheme,"hkp")==0) + srvtag="pgpkey-http"; + else if(ks_strcasecmp(opt->scheme,"hkps")==0) + srvtag="pgpkey-https"; + else + srvtag=NULL; + #ifdef HAVE_LIBCURL /* We're using libcurl, so fake SRV support via our wrapper. This isn't as good as true SRV support, as we do not try all possible targets at one particular level and work our way down the list, but it's better than nothing. */ - srv_replace(); + srv_replace(srvtag); #else /* We're using our internal curl shim, so we can use its (true) SRV support. Obviously, CURLOPT_SRVTAG_GPG_HACK isn't a real libcurl option. It's specific to our shim. */ - curl_easy_setopt(curl,CURLOPT_SRVTAG_GPG_HACK,opt->scheme); + curl_easy_setopt(curl,CURLOPT_SRVTAG_GPG_HACK,srvtag); #endif } From cvs at cvs.gnupg.org Wed Jul 8 13:49:18 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 08 Jul 2009 13:49:18 +0200 Subject: [svn] gpgme - r1393 - trunk/tests Message-ID: Author: wk Date: 2009-07-08 13:49:18 +0200 (Wed, 08 Jul 2009) New Revision: 1393 Added: trunk/tests/run-support.h Log: Add issing file. From cvs at cvs.gnupg.org Thu Jul 9 10:52:32 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 09 Jul 2009 10:52:32 +0200 Subject: [svn] GnuPG - r5070 - in trunk: . g10 Message-ID: Author: wk Date: 2009-07-09 10:52:31 +0200 (Thu, 09 Jul 2009) New Revision: 5070 Modified: trunk/NEWS trunk/g10/ChangeLog trunk/g10/gpg.c trunk/g10/keygen.c Log: Changed default hash algorithm preferences Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-07-08 04:01:13 UTC (rev 5069) +++ trunk/g10/ChangeLog 2009-07-09 08:52:31 UTC (rev 5070) @@ -1,3 +1,14 @@ +2009-07-09 Werner Koch + + * gpg.c (main): Remove the SHA-1 default from the personal digest + list. This was used in the past as a hack to avoid preferring + RMD-160. + + * keygen.c (keygen_set_std_prefs): Remove RMD-160 from the list. + Change order to SHA-256, SHA-1, SHA-384, SHA-512, SHA-224. + (gen_dsa): Use a 256 bit Q for 2048 bit P. Runt to FIPS allowed + values in non-expert mode. + 2009-07-07 Werner Koch * gpg.c (set_opt_session_env): New. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-07-08 04:01:13 UTC (rev 5069) +++ trunk/NEWS 2009-07-09 08:52:31 UTC (rev 5070) @@ -1,15 +1,18 @@ Noteworthy changes in version 2.0.13 ------------------------------------------------- + * GPG now generates 2048 bit RSA keys by default. The default hash + algorithm preferences has changed to prefer SHA-256 over SHA-1. + 2048 bit DSA keys are now generated to use a 256 bit hash algorithm + * The envvars XMODIFIERS, GTK_IM_MODULE and QT_IM_MODULE are now passed to the Pinentry to make SCIM work. - * gpgsm --gen-key implements a --batch mode. + * The GPGSM command --gen-key features a --batch mode and implements + all features of gpgsm-gencert.sh in standard mode. - * gpgsm --gen-key implements all features of gpgsm-gencert.sh. + * New option --re-import for GPGSM's IMPORT server command. - * New option --re-import for gpgsm's IMPORT server command. - * Minor bug fixes. Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2009-07-08 04:01:13 UTC (rev 5069) +++ trunk/g10/gpg.c 2009-07-09 08:52:31 UTC (rev 5070) @@ -3195,11 +3195,6 @@ keygen_set_std_prefs(opt.def_preference_list,0)) log_error(_("invalid default preferences\n")); - /* We provide defaults for the personal digest list. This is - SHA-1. */ - if(!pers_digest_list) - pers_digest_list="h2"; - if(pers_cipher_list && keygen_set_std_prefs(pers_cipher_list,PREFTYPE_SYM)) log_error(_("invalid personal cipher preferences\n")); Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2009-07-08 04:01:13 UTC (rev 5069) +++ trunk/g10/keygen.c 2009-07-09 08:52:31 UTC (rev 5070) @@ -1,6 +1,6 @@ /* keygen.c - generate a key pair * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2006, 2007 Free Software Foundation, Inc. + * 2006, 2007, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -301,7 +301,7 @@ byte sym[MAX_PREFS], hash[MAX_PREFS], zip[MAX_PREFS]; int nsym=0, nhash=0, nzip=0, val, rc=0; int mdc=1, modify=0; /* mdc defaults on, modify defaults off. */ - char dummy_string[45+1]; /* Enough for 15 items. */ + char dummy_string[20*4+1]; /* Enough for 20 items. */ if (!string || !ascii_strcasecmp (string, "default")) { @@ -345,16 +345,30 @@ if ( !openpgp_cipher_test_algo (CIPHER_ALGO_IDEA) ) strcat(dummy_string,"S1 "); - /* SHA-1 */ - strcat(dummy_string,"H2 "); - if (!openpgp_md_test_algo(DIGEST_ALGO_SHA256)) - strcat(dummy_string,"H8 "); + /* The default hash algo order is: + SHA-256, SHA-1, SHA-384, SHA-512, SHA-224. + Ordering SHA-1 before SHA-384 might be viewed as a bit + strange; it is done because we expect that soon enough + SHA-3 will be available and at that point there should + be no more need for SHA-384 etc. Anyway this order is + just a default and can easily be changed by a config + option. */ + if (!openpgp_md_test_algo (DIGEST_ALGO_SHA256)) + strcat (dummy_string, "H8 "); - /* RIPEMD160 */ - if (!openpgp_md_test_algo(DIGEST_ALGO_RMD160)) - strcat(dummy_string,"H3 "); + strcat (dummy_string, "H2 "); /* SHA-1 */ + if (!openpgp_md_test_algo (DIGEST_ALGO_SHA384)) + strcat (dummy_string, "H9 "); + + if (!openpgp_md_test_algo (DIGEST_ALGO_SHA512)) + strcat (dummy_string, "H10 "); + + if (!openpgp_md_test_algo (DIGEST_ALGO_SHA224)) + strcat (dummy_string, "H11 "); + + /* ZLIB */ strcat(dummy_string,"Z2 "); @@ -507,7 +521,8 @@ /* Return a fake user ID containing the preferences. Caller must free. */ -PKT_user_id *keygen_get_std_prefs(void) +PKT_user_id * +keygen_get_std_prefs(void) { int i,j=0; PKT_user_id *uid=xmalloc_clear(sizeof(PKT_user_id)); @@ -1280,6 +1295,14 @@ log_info(_("keysize rounded up to %u bits\n"), nbits ); } + /* To comply with FIPS rules we round up to the next value unless in + expert mode. */ + if (!opt.expert && nbits > 1024 && (nbits % 1024)) + { + nbits = ((nbits + 1023) / 1024) * 1024; + log_info(_("keysize rounded up to %u bits\n"), nbits ); + } + /* Figure out a q size based on the key size. FIPS 180-3 says: @@ -1291,11 +1314,11 @@ 2048/256 is an odd pair since there is also a 2048/224 and 3072/256. Matching sizes is not a very exact science. - We'll do 256 qbits for nbits over 2048, 224 for nbits over 1024 + We'll do 256 qbits for nbits over 2047, 224 for nbits over 1024 but less than 2048, and 160 for 1024 (DSA1). */ - if (nbits > 2048) + if (nbits > 2047) qbits = 256; else if ( nbits > 1024) qbits = 224; From cvs at cvs.gnupg.org Thu Jul 9 11:12:01 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 09 Jul 2009 11:12:01 +0200 Subject: [svn] GnuPG - r5071 - trunk/po Message-ID: Author: wk Date: 2009-07-09 11:12:01 +0200 (Thu, 09 Jul 2009) New Revision: 5071 Modified: trunk/po/ChangeLog trunk/po/zh_CN.po Log: Marked an entry fuzzy. Modified: trunk/po/ChangeLog =================================================================== --- trunk/po/ChangeLog 2009-07-09 08:52:31 UTC (rev 5070) +++ trunk/po/ChangeLog 2009-07-09 09:12:01 UTC (rev 5071) @@ -1,3 +1,7 @@ +2009-07-09 Werner Koch + + * zh_CN.po : Marked fuzzy. See bug#1078. + 2009-06-30 Werner Koch * es.po: Mark a bad translation fuzzy. Modified: trunk/po/zh_CN.po [not shown] From cvs at cvs.gnupg.org Thu Jul 9 13:57:28 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 09 Jul 2009 13:57:28 +0200 Subject: [svn] gcry - r1400 - in trunk: random tests Message-ID: Author: wk Date: 2009-07-09 13:57:28 +0200 (Thu, 09 Jul 2009) New Revision: 1400 Modified: trunk/random/ChangeLog trunk/random/rndlinux.c trunk/random/rndunix.c trunk/tests/ChangeLog trunk/tests/benchmark.c Log: [random/ChangeLog] * rndlinux.c (_gcry_rndlinux_gather_random): Print real values for the progess function and call it before blocking. Suggested by Christian Grothoff. * rndunix.c (slow_poll): Add similar, but not yet functional, code. SCALAR(0x81980e8) Copyright 2008, 2009 Free Software Foundation, Inc. [tests/ChangeLog] * benchmark.c (progress_cb): New. (main): Add option --progress. Modified: trunk/random/ChangeLog =================================================================== --- trunk/random/ChangeLog 2009-07-02 14:12:44 UTC (rev 1399) +++ trunk/random/ChangeLog 2009-07-09 11:57:28 UTC (rev 1400) @@ -1,3 +1,10 @@ +2009-07-09 Werner Koch + + * rndlinux.c (_gcry_rndlinux_gather_random): Print real values for + the progess function and call it before blocking. Suggested by + Christian Grothoff. + * rndunix.c (slow_poll): Add similar, but not yet functional, code. + 2009-07-02 Werner Koch * rndhw.c (poll_padlock): Asm change from Fedora. @@ -120,7 +127,7 @@ here. * Makefile.am: New. - Copyright 2008 Free Software Foundation, Inc. + Copyright 2008, 2009 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 Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-07-02 14:12:44 UTC (rev 1399) +++ trunk/tests/ChangeLog 2009-07-09 11:57:28 UTC (rev 1400) @@ -1,3 +1,8 @@ +2009-07-09 Werner Koch + + * benchmark.c (progress_cb): New. + (main): Add option --progress. + 2009-06-08 Werner Koch * benchmark.c (cipher_bench): Center labels. Suggested by Brad Hards. Modified: trunk/random/rndlinux.c =================================================================== --- trunk/random/rndlinux.c 2009-07-02 14:12:44 UTC (rev 1399) +++ trunk/random/rndlinux.c 2009-07-09 11:57:28 UTC (rev 1400) @@ -1,5 +1,6 @@ /* rndlinux.c - raw random number for OSes with /dev/random - * Copyright (C) 1998, 2001, 2002, 2003, 2007 Free Software Foundation, Inc. + * Copyright (C) 1998, 2001, 2002, 2003, 2007, + * 2009 Free Software Foundation, Inc. * * This file is part of Libgcrypt. * @@ -93,9 +94,12 @@ static int fd_random = -1; int fd; int n; - int warn=0; byte buffer[768]; size_t n_hw; + size_t want = length; + size_t last_so_far = 0; + int any_need_entropy = 0; + int delay; /* First read from a hardware source. However let it account only for up to 50% of the requested bytes. */ @@ -119,7 +123,11 @@ fd = fd_urandom; } - /* And enter the read loop. */ + /* Enter the read loop. */ + delay = 0; /* Start with 0 seconds so that we do no block on the + first iteration and in turn call the progess function + before blocking. To give the OS a better chance to + return with something we will actually use 100ms. */ while (length) { fd_set rfds; @@ -128,40 +136,49 @@ FD_ZERO(&rfds); FD_SET(fd, &rfds); - tv.tv_sec = 3; - tv.tv_usec = 0; - if( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) + tv.tv_sec = delay; + tv.tv_usec = delay? 0 : 100000; + if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) { - if( !warn ) + if (!any_need_entropy || last_so_far != (want - length) ) { - _gcry_random_progress ("need_entropy", 'X', 0, (int)length); - warn = 1; + last_so_far = want - length; + _gcry_random_progress ("need_entropy", 'X', + (int)last_so_far, (int)want); + any_need_entropy = 1; } + delay = 3; /* Use 3 seconds henceforth. */ continue; } - else if( rc == -1 ) - { - log_error ("select() error: %s\n", strerror(errno)); - continue; - } + else if( rc == -1 ) + { + log_error ("select() error: %s\n", strerror(errno)); + if (!delay) + delay = 1; /* Use 1 second if we encounter an error before + we have ever blocked. */ + continue; + } - do - { - int nbytes = length < sizeof(buffer)? length : sizeof(buffer); - n = read(fd, buffer, nbytes ); - if( n >= 0 && n > nbytes ) - { - log_error("bogus read from random device (n=%d)\n", n ); - n = nbytes; - } - } - while( n == -1 && errno == EINTR ); - if( n == -1 ) - log_fatal("read error on random device: %s\n", strerror(errno)); - (*add)( buffer, n, origin ); - length -= n; + do + { + int nbytes = length < sizeof(buffer)? length : sizeof(buffer); + n = read(fd, buffer, nbytes ); + if( n >= 0 && n > nbytes ) + { + log_error("bogus read from random device (n=%d)\n", n ); + n = nbytes; + } + } + while( n == -1 && errno == EINTR ); + if ( n == -1 ) + log_fatal("read error on random device: %s\n", strerror(errno)); + (*add)( buffer, n, origin ); + length -= n; } memset(buffer, 0, sizeof(buffer) ); - + + if (any_need_entropy) + _gcry_random_progress ("need_entropy", 'X', (int)want, (int)want); + return 0; /* success */ } Modified: trunk/random/rndunix.c =================================================================== --- trunk/random/rndunix.c 2009-07-02 14:12:44 UTC (rev 1399) +++ trunk/random/rndunix.c 2009-07-09 11:57:28 UTC (rev 1400) @@ -521,8 +521,11 @@ int maxFD = 0; #endif /* OS-specific brokenness */ int bufPos, i, usefulness = 0; + int last_so_far = 0; + int any_need_entropy = 0; + int delay; + int rc; - /* Fire up each randomness source */ FD_ZERO(&fds); for (i = 0; dataSources[i].path != NULL; i++) { @@ -566,22 +569,41 @@ /* Suck all the data we can get from each of the sources */ bufPos = 0; moreSources = 1; + delay = 0; /* Return immediately (well, after 100ms) the first time. */ while (moreSources && bufPos <= gather_buffer_size) { /* Wait for data to become available from any of the sources, with a * timeout of 10 seconds. This adds even more randomness since data * becomes available in a nondeterministic fashion. Kudos to HP's QA * department for managing to ship a select() which breaks its own * prototype */ - tv.tv_sec = 10; - tv.tv_usec = 0; + tv.tv_sec = delay; + tv.tv_usec = delay? 0 : 100000; #if defined( __hpux ) && ( OS_VERSION == 9 ) - if (select(maxFD + 1, (int *)&fds, NULL, NULL, &tv) == -1) + rc = select(maxFD + 1, (int *)&fds, NULL, NULL, &tv); #else /* */ - if (select(maxFD + 1, &fds, NULL, NULL, &tv) == -1) + rc = select(maxFD + 1, &fds, NULL, NULL, &tv); #endif /* __hpux */ - break; + if (rc == -1) + break; /* Ooops; select failed. */ + if (!rc) + { + /* FIXME: Because we run several tools at once it is + unlikely that we will see a block in select at all. */ + if (!any_need_entropy + || last_so_far != (gather_buffer_size - bufPos) ) + { + last_so_far = gather_buffer_size - bufPos; + _gcry_random_progress ("need_entropy", 'X', + last_so_far, + gather_buffer_size); + any_need_entropy = 1; + } + delay = 10; /* Use 10 seconds henceforth. */ + /* Note that the fd_set is setup again at the end of this loop. */ + } + /* One of the sources has data available, read it into the buffer */ for (i = 0; dataSources[i].path != NULL; i++) { if( dataSources[i].pipe && FD_ISSET(dataSources[i].pipeFD, &fds)) { @@ -661,6 +683,11 @@ } } + if (any_need_entropy) + _gcry_random_progress ("need_entropy", 'X', + gather_buffer_size, + gather_buffer_size); + if( dbgfp ) { fprintf(dbgfp, "Got %d bytes, usefulness = %d\n", bufPos, usefulness); fflush(dbgfp); Modified: trunk/tests/benchmark.c =================================================================== --- trunk/tests/benchmark.c 2009-07-02 14:12:44 UTC (rev 1399) +++ trunk/tests/benchmark.c 2009-07-09 11:57:28 UTC (rev 1400) @@ -340,6 +340,18 @@ static void +progress_cb (void *cb_data, const char *what, int printchar, + int current, int total) +{ + (void)cb_data; + + fprintf (stderr, PGM ": progress (%s %c %d %d)\n", + what, printchar, current, total); + fflush (stderr); +} + + +static void random_bench (int very_strong) { char buf[128]; @@ -1002,6 +1014,7 @@ int last_argc = -1; int no_blinding = 0; int use_random_daemon = 0; + int with_progress = 0; if (argc) { argc--; argv++; } @@ -1056,6 +1069,11 @@ /* This command needs to be called before gcry_check_version. */ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); } + else if (!strcmp (*argv, "--progress")) + { + argc--; argv++; + with_progress = 1; + } } gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); @@ -1074,9 +1092,12 @@ if (use_random_daemon) gcry_control (GCRYCTL_USE_RANDOM_DAEMON, 1); + gcry_set_progress_handler (progress_cb, NULL); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (cipher_repetitions < 1) cipher_repetitions = 1; From cvs at cvs.gnupg.org Thu Jul 9 14:26:27 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 09 Jul 2009 14:26:27 +0200 Subject: [svn] gcry - r1401 - trunk/doc Message-ID: Author: wk Date: 2009-07-09 14:26:26 +0200 (Thu, 09 Jul 2009) New Revision: 1401 Modified: trunk/doc/gcrypt.texi Log: Explicitly mention zeroisation. Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2009-07-09 11:57:28 UTC (rev 1400) +++ trunk/doc/gcrypt.texi 2009-07-09 12:26:26 UTC (rev 1401) @@ -1695,6 +1695,8 @@ @deftypefun void gcry_cipher_close (gcry_cipher_hd_t @var{h}) This function releases the context created by @code{gcry_cipher_open}. +It also zeroises all sensitive information associated with this cipher +handle. @end deftypefun In order to use a handle for performing cryptographic operations, a @@ -3652,8 +3654,10 @@ Release all resources of hash context @var{h}. @var{h} should not be used after a call to this function. A @code{NULL} passed as @var{h} is -ignored. +ignored. The function also zeroises all sensitive information +associated with this handle. + @end deftypefun Often you have to do several hash operations using the same algorithm. @@ -4055,7 +4059,10 @@ @deftypefun void gcry_sexp_release (@w{gcry_sexp_t @var{sexp}}) -Release the S-expression object @var{sexp}. +Release the S-expression object @var{sexp}. If the S-expression is +stored in secure memory it explicitly zeroises that memory; note that +this is done in addition to the zeroisation always done when freeing +secure memory. @end deftypefun @@ -5135,8 +5142,6 @@ used with the test context the DT value is taken from the context and incremented on each use. - - @c @node Helper Subsystems Architecture @c @section Helper Subsystems Architecture @c From cvs at cvs.gnupg.org Thu Jul 9 14:34:46 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 09 Jul 2009 14:34:46 +0200 Subject: [svn] gcry - r1402 - branches/LIBGCRYPT-1-4-BRANCH/doc Message-ID: Author: wk Date: 2009-07-09 14:34:46 +0200 (Thu, 09 Jul 2009) New Revision: 1402 Modified: branches/LIBGCRYPT-1-4-BRANCH/doc/ChangeLog branches/LIBGCRYPT-1-4-BRANCH/doc/gcrypt.texi Log: Doc updates. Modified: branches/LIBGCRYPT-1-4-BRANCH/doc/ChangeLog =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/doc/ChangeLog 2009-07-09 12:26:26 UTC (rev 1401) +++ branches/LIBGCRYPT-1-4-BRANCH/doc/ChangeLog 2009-07-09 12:34:46 UTC (rev 1402) @@ -1,3 +1,10 @@ +2009-07-09 Werner Koch + + * gcrypt.texi (Working with S-expressions): Describe format + character '%S'. Typo fixes. + (gcry_cipher_close, gcry_md_close) + (gcry_sexp_release): Explicitly mention zeroisation. + 2009-04-02 Werner Koch * gcrypt.texi (Self-Tests): Fix name of register functions. Modified: branches/LIBGCRYPT-1-4-BRANCH/doc/gcrypt.texi =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/doc/gcrypt.texi 2009-07-09 12:26:26 UTC (rev 1401) +++ branches/LIBGCRYPT-1-4-BRANCH/doc/gcrypt.texi 2009-07-09 12:34:46 UTC (rev 1402) @@ -12,7 +12,7 @@ (version @value{VERSION}, @value{UPDATED}), which is GNU's library of cryptographic building blocks. -Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008 Free Software Foundation, Inc. +Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -1695,6 +1695,8 @@ @deftypefun void gcry_cipher_close (gcry_cipher_hd_t @var{h}) This function releases the context created by @code{gcry_cipher_open}. +It also zeroises all sensitive information associated with this cipher +handle. @end deftypefun In order to use a handle for performing cryptographic operations, a @@ -1703,11 +1705,11 @@ @deftypefun gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t @var{h}, const void *@var{k}, size_t @var{l}) Set the key @var{k} used for encryption or decryption in the context -denoted by the handle @var{h}. The length @var{l} of the key @var{k} -must match the required length of the algorithm set for this context or -be in the allowed range for algorithms with variable key size. The -function checks this and returns an error if there is a problem. A -caller should always check for an error. +denoted by the handle @var{h}. The length @var{l} (in bytes) of the +key @var{k} must match the required length of the algorithm set for +this context or be in the allowed range for algorithms with variable +key size. The function checks this and returns an error if there is a +problem. A caller should always check for an error. @end deftypefun @@ -1719,18 +1721,18 @@ @deftypefun gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t @var{h}, const void *@var{k}, size_t @var{l}) Set the initialization vector used for encryption or decryption. The -vector is passed as the buffer @var{K} of length @var{l} and copied to -internal data structures. The function checks that the IV matches the -requirement of the selected algorithm and mode. +vector is passed as the buffer @var{K} of length @var{l} bytes and +copied to internal data structures. The function checks that the IV +matches the requirement of the selected algorithm and mode. @end deftypefun @deftypefun gcry_error_t gcry_cipher_setctr (gcry_cipher_hd_t @var{h}, const void *@var{c}, size_t @var{l}) Set the counter vector used for encryption or decryption. The counter -is passed as the buffer @var{c} of length @var{l} and copied to +is passed as the buffer @var{c} of length @var{l} bytes and copied to internal data structures. The function checks that the counter matches the requirement of the selected algorithm (i.e., it must be -the same size as the block size). +the same size as the block size). @end deftypefun @deftypefun gcry_error_t gcry_cipher_reset (gcry_cipher_hd_t @var{h}) @@ -2431,9 +2433,9 @@ PKCS#1 block type 1 style padding. @var{hash-algo} is a string with the hash algorithm to be encoded into the signature, this may be any hash algorithm name as supported by Libgcrypt. Most likely, this will be -"sha1", "rmd160" or "md5". It is obvious that the length of @var{block} -must match the size of that message digests; the function checks that -this and other constraints are valid. +"sha256" or "sha1". It is obvious that the length of @var{block} must +match the size of that message digests; the function checks that this +and other constraints are valid. @noindent If PKCS#1 padding is not required (because the caller does already @@ -3410,26 +3412,36 @@ @item GCRY_MD_SHA1 This is the SHA-1 algorithm which yields a message digest of 20 bytes. +Note that SHA-1 begins to show some weaknesses and it is suggested to +fade out its use if strong cryptographic properties are required. @item GCRY_MD_RMD160 This is the 160 bit version of the RIPE message digest (RIPE-MD-160). -Like SHA-1 it also yields a digest of 20 bytes. +Like SHA-1 it also yields a digest of 20 bytes. This algorithm share a +lot of design properties with SHA-1 and thus it is advisable not to use +it for new protocols. @item GCRY_MD_MD5 This is the well known MD5 algorithm, which yields a message digest of -16 bytes. +16 bytes. Note that the MD5 algorithm has severe weaknesses, for +example it is easy to compute two messages yielding the same hash +(collision attack). The use of this algorithm is only justified for +non-cryptographic application. + @item GCRY_MD_MD4 This is the MD4 algorithm, which yields a message digest of 16 bytes. +This algorithms ha severe weaknesses and should not be used. @item GCRY_MD_MD2 This is an reserved identifier for MD-2; there is no implementation yet. +This algorithm has severe weaknesses and should not be used. @item GCRY_MD_TIGER This is the TIGER/192 algorithm which yields a message digest of 24 bytes. @item GCRY_MD_HAVAL -This is an reserved for the HAVAL algorithm with 5 passes and 160 +This is an reserved value for the HAVAL algorithm with 5 passes and 160 bit. It yields a message digest of 20 bytes. Note that there is no implementation yet available. @@ -3450,16 +3462,19 @@ See FIPS 180-2 for the specification. @item GCRY_MD_CRC32 -This is the ISO 3309 and ITU-T V.42 cyclic redundancy check. It -yields an output of 4 bytes. +This is the ISO 3309 and ITU-T V.42 cyclic redundancy check. It yields +an output of 4 bytes. Note that this is not a hash algorithm in the +cryptographic sense. @item GCRY_MD_CRC32_RFC1510 This is the above cyclic redundancy check function, as modified by RFC -1510. It yields an output of 4 bytes. +1510. It yields an output of 4 bytes. Note that this is not a hash +algorithm in the cryptographic sense. @item GCRY_MD_CRC24_RFC2440 This is the OpenPGP cyclic redundancy check function. It yields an -output of 3 bytes. +output of 3 bytes. Note that this is not a hash algorithm in the +cryptographic sense. @item GCRY_MD_WHIRLPOOL This is the Whirlpool algorithm which yields a message digest of 64 @@ -3626,8 +3641,9 @@ @deftypefun gcry_error_t gcry_md_setkey (gcry_md_hd_t @var{h}, const void *@var{key}, size_t @var{keylen}) -For use with the HMAC feature, set the MAC key to the value of @var{key} -of length @var{keylen}. There is no restriction on the length of the key. +For use with the HMAC feature, set the MAC key to the value of + at var{key} of length @var{keylen} bytes. There is no restriction on +the length of the key. @end deftypefun @@ -3638,8 +3654,10 @@ Release all resources of hash context @var{h}. @var{h} should not be used after a call to this function. A @code{NULL} passed as @var{h} is -ignored. +ignored. The function also zeroises all sensitive information +associated with this handle. + @end deftypefun Often you have to do several hash operations using the same algorithm. @@ -4024,8 +4042,13 @@ @item %b The next argument is expected to be of type @code{int} directly followed by an argument of type @code{char *}. This represents a -buffer of given length to be inserted into the resulting regular -expression. +buffer of given length to be inserted into the resulting S-expression. + at item %S +The next argument is expected to be of type @code{gcry_sexp_t} and a +copy of that S-expression is embedded in the resulting S-expression. +The argument needs to be a regular S-expression, starting with a +parenthesis. + @end table @noindent @@ -4036,7 +4059,10 @@ @deftypefun void gcry_sexp_release (@w{gcry_sexp_t @var{sexp}}) -Release the S-expression object @var{sexp}. +Release the S-expression object @var{sexp}. If the S-expression is +stored in secure memory it explicitly zeroises that memory; note that +this is done in addition to the zeroisation always done when freeing +secure memory. @end deftypefun @@ -4097,8 +4123,7 @@ @noindent -There are a couple of functions to parse S-expressions and retrieve -elements: +There are functions to parse S-expressions and retrieve elements: @deftypefun gcry_sexp_t gcry_sexp_find_token (@w{const gcry_sexp_t @var{list}}, @w{const char *@var{token}}, @w{size_t @var{toklen}}) @@ -4630,15 +4655,15 @@ Like @code{gcry_malloc}, but uses secure memory. @end deftypefun - at deftypefun {void *} gcry_calloc (size_t @var{n}) + at deftypefun {void *} gcry_calloc (size_t @var{n}, size_t @var{m}) -This function tries to allocate @var{n} bytes of cleared memory -(i.e. memory that is initialized with zero bytes). On success it -returns a pointer to the memory area, in an out-of-core condition, it -returns NULL. +This function allocates a cleared block of memory (i.e. initialized with +zero bytes) long enough to contain a vector of @var{n} elements, each of +size @var{m} bytes. On success it returns a pointer to the memory +block; in an out-of-core condition, it returns NULL. @end deftypefun - at deftypefun {void *} gcry_calloc_secure (size_t @var{n}) + at deftypefun {void *} gcry_calloc_secure (size_t @var{n}, size_t @var{m}) Like @code{gcry_calloc}, but uses secure memory. @end deftypefun @@ -5117,8 +5142,6 @@ used with the test context the DT value is taken from the context and incremented on each use. - - @c @node Helper Subsystems Architecture @c @section Helper Subsystems Architecture @c From cvs at cvs.gnupg.org Thu Jul 9 16:54:19 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 09 Jul 2009 16:54:19 +0200 Subject: [svn] GnuPG - r5072 - in trunk: . doc g10 scd Message-ID: Author: wk Date: 2009-07-09 16:54:18 +0200 (Thu, 09 Jul 2009) New Revision: 5072 Modified: trunk/NEWS trunk/doc/DETAILS trunk/g10/ChangeLog trunk/g10/card-util.c trunk/scd/ChangeLog trunk/scd/app-openpgp.c Log: Support writing of existing keys with non-matching key sizes. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-07-09 09:12:01 UTC (rev 5071) +++ trunk/g10/ChangeLog 2009-07-09 14:54:18 UTC (rev 5072) @@ -1,5 +1,8 @@ 2009-07-09 Werner Koch + * card-util.c (card_store_subkey): Do not restrict to 1024 bit keys. + Print an error message on write errors. + * gpg.c (main): Remove the SHA-1 default from the personal digest list. This was used in the past as a hack to avoid preferring RMD-160. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-07-09 09:12:01 UTC (rev 5071) +++ trunk/scd/ChangeLog 2009-07-09 14:54:18 UTC (rev 5072) @@ -1,3 +1,11 @@ +2009-07-09 Werner Koch + + * app-openpgp.c (change_keyattr): New. + (do_writekey): Call it. + + * app-openpgp.c (does_key_exist): Add arg GENERATING. Change + callers. + 2009-06-30 Werner Koch * ccid-driver.c (ccid_transceive): Set RESYNCING flag. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-07-09 09:12:01 UTC (rev 5071) +++ trunk/NEWS 2009-07-09 14:54:18 UTC (rev 5072) @@ -13,6 +13,11 @@ * New option --re-import for GPGSM's IMPORT server command. + * Enhanced writing of existing keys to OpenPGP v2 cards. + + * Add hack to the internal CCID driver to allow the use of some + Omnikey based card readers with 2048 bit keys. + * Minor bug fixes. Modified: trunk/doc/DETAILS =================================================================== --- trunk/doc/DETAILS 2009-07-09 09:12:01 UTC (rev 5071) +++ trunk/doc/DETAILS 2009-07-09 14:54:18 UTC (rev 5072) @@ -503,8 +503,9 @@ "char" is the character displayed with no --status-fd enabled, with the linefeed replaced by an 'X'. "cur" is the current amount done and "total" is amount to be done; a "total" of 0 indicates that - the total amount is not known. 100/100 may be used to detect the - end of operation. + the total amount is not known. The condition + TOATL && CUR == TOTAL + may be used to detect the end of an operation. Well known values for WHAT: "pk_dsa" - DSA key generation "pk_elg" - Elgamal key generation Modified: trunk/g10/card-util.c =================================================================== --- trunk/g10/card-util.c 2009-07-09 09:12:01 UTC (rev 5071) +++ trunk/g10/card-util.c 2009-07-09 14:54:18 UTC (rev 5072) @@ -1,5 +1,5 @@ /* card-util.c - Utility functions for the OpenPGP card. - * Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. + * Copyright (C) 2003, 2004, 2005, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1393,7 +1393,8 @@ show_card_key_info (&info); - if (!is_RSA (sk->pubkey_algo) || nbits_from_sk (sk) != 1024 ) + if (!is_RSA (sk->pubkey_algo) + || (!info.is_v2 && nbits_from_sk (sk) != 1024) ) { tty_printf ("You may only store a 1024 bit RSA key on the card\n"); tty_printf ("\n"); @@ -1461,7 +1462,10 @@ rc = save_unprotected_key_to_card (sk, keyno); if (rc) - goto leave; + { + log_error (_("error writing key to card: %s\n"), gpg_strerror (rc)); + goto leave; + } /* Get back to the maybe protected original secret key. */ if (copied_sk) Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2009-07-09 09:12:01 UTC (rev 5071) +++ trunk/scd/app-openpgp.c 2009-07-09 14:54:18 UTC (rev 5072) @@ -213,6 +213,7 @@ void *pincb_arg, const void *indata, size_t indatalen, unsigned char **outdata, size_t *outdatalen); +static void parse_algorithm_attribute (app_t app, int keyno); @@ -2144,9 +2145,10 @@ /* Check whether a key already exists. KEYIDX is the index of the key (0..2). If FORCE is TRUE a diagnositic will be printed but no - error returned if the key already exists. */ + error returned if the key already exists. The flag GENERATING is + only used to print correct messages. */ static gpg_error_t -does_key_exist (app_t app, int keyidx, int force) +does_key_exist (app_t app, int keyidx, int generating, int force) { const unsigned char *fpr; unsigned char *buffer; @@ -2178,8 +2180,10 @@ } else if (i!=20) log_info (_("existing key will be replaced\n")); + else if (generating) + log_info (_("generating new key\n")); else - log_info (_("generating new key\n")); + log_info (_("writing new key\n")); return 0; } @@ -2340,7 +2344,64 @@ } +/* Helper for do_writekley to change the size of a key. Not ethat + this deletes the entire key without asking. */ +static gpg_error_t +change_keyattr (app_t app, int keyno, unsigned int nbits, + gpg_error_t (*pincb)(void*, const char *, char **), + void *pincb_arg) +{ + gpg_error_t err; + unsigned char *buffer; + size_t buflen; + void *relptr; + assert (keyno >=0 && keyno <= 2); + + if (nbits > 3072) + return gpg_error (GPG_ERR_TOO_LARGE); + + /* Read the current attributes into a buffer. */ + relptr = get_one_do (app, 0xC1+keyno, &buffer, &buflen, NULL); + if (!relptr) + return gpg_error (GPG_ERR_CARD); + if (buflen < 6 || buffer[0] != 1) + { + /* Attriutes too short or not an RSA key. */ + xfree (relptr); + return gpg_error (GPG_ERR_CARD); + } + + /* We only change n_bits and don't touch anything else. Before we + do so, we round up NBITS to a sensible way in the same way as + gpg's key generation does it. This may help to sort out problems + with a few bits too short keys. */ + nbits = ((nbits + 31) / 32) * 32; + buffer[1] = (nbits >> 8); + buffer[2] = nbits; + + /* Prepare for storing the key. */ + err = verify_chv3 (app, pincb, pincb_arg); + if (err) + { + xfree (relptr); + return err; + } + + /* Change the attribute. */ + err = iso7816_put_data (app->slot, 0, 0xC1+keyno, buffer, buflen); + xfree (relptr); + if (err) + log_error ("error changing size of key %d to %u bits\n", keyno+1, nbits); + else + log_info ("size of key %d changed to %u bits\n", keyno+1, nbits); + flush_cache (app); + parse_algorithm_attribute (app, keyno); + return err; +} + + + /* Handle the WRITEKEY command for OpenPGP. This function expects a canonical encoded S-expression with the secret key in KEYDATA and its length (for assertions) in KEYDATALEN. KEYID needs to be the @@ -2385,7 +2446,7 @@ else return gpg_error (GPG_ERR_INV_ID); - err = does_key_exist (app, keyno, force); + err = does_key_exist (app, keyno, 0, force); if (err) return err; @@ -2515,6 +2576,14 @@ if (opt.verbose) log_info ("RSA modulus size is %u bits (%u bytes)\n", nbits, (unsigned int)rsa_n_len); + if (nbits && nbits != maxbits + && app->app_local->extcap.algo_attr_change) + { + /* Try to switch the key to a new length. */ + err = change_keyattr (app, keyno, nbits, pincb, pincb_arg); + if (!err) + maxbits = app->app_local->keyattr[keyno].n_bits; + } if (nbits != maxbits) { log_error (_("RSA modulus missing or not of size %d bits\n"), @@ -2696,7 +2765,7 @@ app->app_local->pk[keyno].read_done = 0; /* Check whether a key already exists. */ - rc = does_key_exist (app, keyno, force); + rc = does_key_exist (app, keyno, 1, force); if (rc) return rc; From cvs at cvs.gnupg.org Fri Jul 10 12:15:33 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 10 Jul 2009 12:15:33 +0200 Subject: [svn] GnuPG - r5073 - trunk/scd Message-ID: Author: wk Date: 2009-07-10 12:15:33 +0200 (Fri, 10 Jul 2009) New Revision: 5073 Modified: trunk/scd/ChangeLog trunk/scd/app-dinsig.c trunk/scd/app-nks.c trunk/scd/app-openpgp.c trunk/scd/app-p15.c trunk/scd/iso7816.c trunk/scd/iso7816.h Log: Fix for card keys > 2048 bit. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-07-09 14:54:18 UTC (rev 5072) +++ trunk/scd/ChangeLog 2009-07-10 10:15:33 UTC (rev 5073) @@ -1,3 +1,12 @@ +2009-07-10 Werner Koch + + * iso7816.c (iso7816_compute_ds): Add args EXTENDED_MODE and LE. + Change all callers to use 0. + (iso7816_internal_authenticate): Add args EXTENDED_MODE and LE. + * app-openpgp.c (do_sign): Take exmode and Le from card + capabilities and pass them to iso7816_compute_ds. + (do_auth): Ditto for iso7816_internal_authenticate. + 2009-07-09 Werner Koch * app-openpgp.c (change_keyattr): New. Modified: trunk/scd/app-dinsig.c =================================================================== --- trunk/scd/app-dinsig.c 2009-07-09 14:54:18 UTC (rev 5072) +++ trunk/scd/app-dinsig.c 2009-07-10 10:15:33 UTC (rev 5073) @@ -483,7 +483,8 @@ rc = verify_pin (app, pincb, pincb_arg); if (!rc) - rc = iso7816_compute_ds (app->slot, data, datalen, outdata, outdatalen); + rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0, + outdata, outdatalen); return rc; } Modified: trunk/scd/app-nks.c =================================================================== --- trunk/scd/app-nks.c 2009-07-09 14:54:18 UTC (rev 5072) +++ trunk/scd/app-nks.c 2009-07-10 10:15:33 UTC (rev 5073) @@ -969,7 +969,8 @@ rc = verify_pin (app, 0, NULL, pincb, pincb_arg); /* Compute the signature. */ if (!rc) - rc = iso7816_compute_ds (app->slot, data, datalen, outdata, outdatalen); + rc = iso7816_compute_ds (app->slot, 0, data, datalen, 0, + outdata, outdatalen); return rc; } Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2009-07-09 14:54:18 UTC (rev 5072) +++ trunk/scd/app-openpgp.c 2009-07-10 10:15:33 UTC (rev 5073) @@ -3008,6 +3008,7 @@ const char *fpr = NULL; unsigned long sigcount; int use_auth = 0; + int exmode, le_value; if (!keyidstr || !*keyidstr) return gpg_error (GPG_ERR_INV_VALUE); @@ -3148,7 +3149,19 @@ xfree (pinvalue); } - rc = iso7816_compute_ds (app->slot, data, datalen, outdata, outdatalen); + + if (app->app_local->cardcap.ext_lc_le) + { + exmode = 1; /* Use extended length. */ + le_value = app->app_local->extcap.max_rsp_data; + } + else + { + exmode = 0; + le_value = 0; + } + rc = iso7816_compute_ds (app->slot, exmode, data, datalen, le_value, + outdata, outdatalen); return rc; } @@ -3219,8 +3232,23 @@ rc = verify_chv2 (app, pincb, pincb_arg); if (!rc) - rc = iso7816_internal_authenticate (app->slot, indata, indatalen, - outdata, outdatalen); + { + int exmode, le_value; + + if (app->app_local->cardcap.ext_lc_le) + { + exmode = 1; /* Use extended length. */ + le_value = app->app_local->extcap.max_rsp_data; + } + else + { + exmode = 0; + le_value = 0; + } + rc = iso7816_internal_authenticate (app->slot, exmode, + indata, indatalen, le_value, + outdata, outdatalen); + } return rc; } Modified: trunk/scd/app-p15.c =================================================================== --- trunk/scd/app-p15.c 2009-07-09 14:54:18 UTC (rev 5072) +++ trunk/scd/app-p15.c 2009-07-10 10:15:33 UTC (rev 5073) @@ -3180,11 +3180,11 @@ } if (hashalgo == MD_USER_TLS_MD5SHA1) - err = iso7816_compute_ds (app->slot, data, 36, outdata, outdatalen); + err = iso7816_compute_ds (app->slot, 0, data, 36, 0, outdata, outdatalen); else if (no_data_padding) - err = iso7816_compute_ds (app->slot, data+15, 20, outdata, outdatalen); + err = iso7816_compute_ds (app->slot, 0, data+15, 20, 0,outdata,outdatalen); else - err = iso7816_compute_ds (app->slot, data, 35, outdata, outdatalen); + err = iso7816_compute_ds (app->slot, 0, data, 35, 0, outdata, outdatalen); return err; } Modified: trunk/scd/iso7816.c =================================================================== --- trunk/scd/iso7816.c 2009-07-09 14:54:18 UTC (rev 5072) +++ trunk/scd/iso7816.c 2009-07-10 10:15:33 UTC (rev 5073) @@ -505,9 +505,10 @@ /* Perform the security operation COMPUTE DIGITAL SIGANTURE. On success 0 is returned and the data is availavle in a newly allocated buffer stored at RESULT with its length stored at - RESULTLEN. */ + RESULTLEN. For LE see do_generate_keypair. */ gpg_error_t -iso7816_compute_ds (int slot, const unsigned char *data, size_t datalen, +iso7816_compute_ds (int slot, int extended_mode, + const unsigned char *data, size_t datalen, int le, unsigned char **result, size_t *resultlen) { int sw; @@ -517,9 +518,16 @@ *result = NULL; *resultlen = 0; - sw = apdu_send (slot, 0, - 0x00, CMD_PSO, 0x9E, 0x9A, datalen, (const char*)data, - result, resultlen); + if (!extended_mode) + le = 256; /* Ignore provided Le and use what apdu_send uses. */ + else if (le >= 0 && le < 256) + le = 256; + + sw = apdu_send_le (slot, extended_mode, + 0x00, CMD_PSO, 0x9E, 0x9A, + datalen, (const char*)data, + le, + result, resultlen); if (sw != SW_SUCCESS) { /* Make sure that pending buffers are released. */ @@ -586,9 +594,11 @@ } +/* For LE see do_generate_keypair. */ gpg_error_t -iso7816_internal_authenticate (int slot, +iso7816_internal_authenticate (int slot, int extended_mode, const unsigned char *data, size_t datalen, + int le, unsigned char **result, size_t *resultlen) { int sw; @@ -598,8 +608,16 @@ *result = NULL; *resultlen = 0; - sw = apdu_send (slot, 0, 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0, - datalen, (const char*)data, result, resultlen); + if (!extended_mode) + le = 256; /* Ignore provided Le and use what apdu_send uses. */ + else if (le >= 0 && le < 256) + le = 256; + + sw = apdu_send_le (slot, extended_mode, + 0x00, CMD_INTERNAL_AUTHENTICATE, 0, 0, + datalen, (const char*)data, + le, + result, resultlen); if (sw != SW_SUCCESS) { /* Make sure that pending buffers are released. */ Modified: trunk/scd/iso7816.h =================================================================== --- trunk/scd/iso7816.h 2009-07-09 14:54:18 UTC (rev 5072) +++ trunk/scd/iso7816.h 2009-07-10 10:15:33 UTC (rev 5073) @@ -93,15 +93,17 @@ gpg_error_t iso7816_manage_security_env (int slot, int p1, int p2, const unsigned char *data, size_t datalen); -gpg_error_t iso7816_compute_ds (int slot, +gpg_error_t iso7816_compute_ds (int slot, int extended_mode, const unsigned char *data, size_t datalen, + int le, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_decipher (int slot, int extended_mode, const unsigned char *data, size_t datalen, int padind, unsigned char **result, size_t *resultlen); -gpg_error_t iso7816_internal_authenticate (int slot, +gpg_error_t iso7816_internal_authenticate (int slot, int extended_mode, const unsigned char *data, size_t datalen, + int le, unsigned char **result, size_t *resultlen); gpg_error_t iso7816_generate_keypair (int slot, int extended_mode, const unsigned char *data, size_t datalen, From cvs at cvs.gnupg.org Fri Jul 10 12:47:30 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 10 Jul 2009 12:47:30 +0200 Subject: [svn] GnuPG - r5074 - trunk/scd Message-ID: Author: wk Date: 2009-07-10 12:47:30 +0200 (Fri, 10 Jul 2009) New Revision: 5074 Modified: trunk/scd/ChangeLog trunk/scd/app-openpgp.c Log: Better reset the PIN verification stati after changing the key attributes. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-07-10 10:15:33 UTC (rev 5073) +++ trunk/scd/ChangeLog 2009-07-10 10:47:30 UTC (rev 5074) @@ -6,6 +6,7 @@ * app-openpgp.c (do_sign): Take exmode and Le from card capabilities and pass them to iso7816_compute_ds. (do_auth): Ditto for iso7816_internal_authenticate. + (change_keyattr): Reset CHV verification status. 2009-07-09 Werner Koch Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2009-07-10 10:15:33 UTC (rev 5073) +++ trunk/scd/app-openpgp.c 2009-07-10 10:47:30 UTC (rev 5074) @@ -2397,6 +2397,9 @@ log_info ("size of key %d changed to %u bits\n", keyno+1, nbits); flush_cache (app); parse_algorithm_attribute (app, keyno); + app->did_chv1 = 0; + app->did_chv2 = 0; + app->did_chv3 = 0; return err; } From cvs at cvs.gnupg.org Mon Jul 13 11:59:23 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 13 Jul 2009 11:59:23 +0200 Subject: [svn] GnuPG - r5075 - trunk/scd Message-ID: Author: wk Date: 2009-07-13 11:59:22 +0200 (Mon, 13 Jul 2009) New Revision: 5075 Modified: trunk/scd/ChangeLog trunk/scd/apdu.c trunk/scd/app.c trunk/scd/ccid-driver.c Log: * ccid-driver.c (struct ccid_driver_s): Add fields last_progress, progress_cb and progress_cb_arg. (ccid_set_progress_cb): New. (print_progress): New. (ccid_transceive): Call print_progress for wait time extensions. * apdu.c (struct reader_table_s): Add field set_progress_cb. (new_reader_slot): Clear that field. (open_ccid_reader): Set it to .. (set_progress_cb_ccid_reader): ... new fucntion. * app.c (print_progress_line): New. (lock_reader): Add arg CTRL to set a progress callback and change all callers to provide it. (unlock_reader): Remove the progress callback. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-07-10 10:47:30 UTC (rev 5074) +++ trunk/scd/ChangeLog 2009-07-13 09:59:22 UTC (rev 5075) @@ -1,3 +1,19 @@ +2009-07-13 Werner Koch + + * ccid-driver.c (struct ccid_driver_s): Add fields last_progress, + progress_cb and progress_cb_arg. + (ccid_set_progress_cb): New. + (print_progress): New. + (ccid_transceive): Call print_progress for wait time extensions. + * apdu.c (struct reader_table_s): Add field set_progress_cb. + (new_reader_slot): Clear that field. + (open_ccid_reader): Set it to .. + (set_progress_cb_ccid_reader): ... new fucntion. + * app.c (print_progress_line): New. + (lock_reader): Add arg CTRL to set a progress callback and + change all callers to provide it. + (unlock_reader): Remove the progress callback. + 2009-07-10 Werner Koch * iso7816.c (iso7816_compute_ds): Add args EXTENDED_MODE and LE. Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2009-07-10 10:47:30 UTC (rev 5074) +++ trunk/scd/apdu.c 2009-07-13 09:59:22 UTC (rev 5075) @@ -109,6 +109,7 @@ unsigned char *, size_t *, struct pininfo_s *); int (*check_keypad)(int, int, int, int, int, int); void (*dump_status_reader)(int); + int (*set_progress_cb)(int, gcry_handler_progress_t, void*); struct { ccid_driver_t handle; @@ -339,6 +340,7 @@ reader_table[reader].send_apdu_reader = NULL; reader_table[reader].check_keypad = NULL; reader_table[reader].dump_status_reader = NULL; + reader_table[reader].set_progress_cb = NULL; reader_table[reader].used = 1; reader_table[reader].any_status = 0; @@ -1835,6 +1837,15 @@ static int +set_progress_cb_ccid_reader (int slot, gcry_handler_progress_t cb, void *cb_arg) +{ + reader_table_t slotp = reader_table + slot; + + return ccid_set_progress_cb (slotp->ccid.handle, cb, cb_arg); +} + + +static int get_status_ccid (int slot, unsigned int *status) { int rc; @@ -1955,6 +1966,7 @@ reader_table[slot].send_apdu_reader = send_apdu_ccid; reader_table[slot].check_keypad = check_ccid_keypad; reader_table[slot].dump_status_reader = dump_ccid_reader_status; + reader_table[slot].set_progress_cb = set_progress_cb_ccid_reader; /* Our CCID reader code does not support T=0 at all, thus reset the flag. */ reader_table[slot].is_t0 = 0; @@ -2601,7 +2613,31 @@ } +/* Set the progress callback of SLOT to CB and its args to CB_ARG. If + CB is NULL the progress callback is removed. */ +int +apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg) +{ + int sw; + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) + return SW_HOST_NO_DRIVER; + + if (reader_table[slot].set_progress_cb) + { + sw = lock_slot (slot); + if (!sw) + { + sw = reader_table[slot].set_progress_cb (slot, cb, cb_arg); + unlock_slot (slot); + } + } + else + sw = 0; + return sw; +} + + /* Do a reset for the card in reader at SLOT. */ int apdu_reset (int slot) @@ -2681,7 +2717,6 @@ } - unsigned char * apdu_get_atr (int slot, size_t *atrlen) { Modified: trunk/scd/app.c =================================================================== --- trunk/scd/app.c 2009-07-10 10:47:30 UTC (rev 5074) +++ trunk/scd/app.c 2009-07-13 09:59:22 UTC (rev 5075) @@ -48,6 +48,20 @@ +static void +print_progress_line (void *opaque, const char *what, int pc, int cur, int tot) +{ + ctrl_t ctrl = opaque; + char line[100]; + + if (ctrl) + { + snprintf (line, sizeof line, "%s %c %d %d", what, pc, cur, tot); + send_status_direct (ctrl, "PROGRESS", line); + } +} + + /* Lock the reader SLOT. This function shall be used right before calling any of the actual application functions to serialize access to the reader. We do this always even if the reader is not @@ -56,7 +70,7 @@ success; only then the unlock_reader function must be called after returning from the handler. */ static gpg_error_t -lock_reader (int slot) +lock_reader (int slot, ctrl_t ctrl) { gpg_error_t err; @@ -84,6 +98,8 @@ return err; } + apdu_set_progress_cb (slot, print_progress_line, ctrl); + return 0; } @@ -95,10 +111,11 @@ || !lock_table[slot].initialized) log_bug ("unlock_reader called for invalid slot %d\n", slot); + apdu_set_progress_cb (slot, NULL, NULL); + if (!pth_mutex_release (&lock_table[slot].lock)) log_error ("failed to release APP lock for slot %d: %s\n", slot, strerror (errno)); - } @@ -171,7 +188,7 @@ return; /* FIXME: We are ignoring any error value here. */ - lock_reader (slot); + lock_reader (slot, NULL); /* Mark application as non-reusable. */ if (lock_table[slot].app) @@ -229,7 +246,7 @@ *r_app = NULL; - err = lock_reader (slot); + err = lock_reader (slot, ctrl); if (err) return err; @@ -461,7 +478,7 @@ /* Move the reference to the application in the lock table. */ slot = app->slot; /* FIXME: We are ignoring any error value. */ - lock_reader (slot); + lock_reader (slot, NULL); if (lock_table[slot].app != app) { unlock_reader (slot); @@ -579,7 +596,7 @@ if (app->apptype && !(flags & 1)) send_status_info (ctrl, "APPTYPE", app->apptype, strlen (app->apptype), NULL, 0); - err = lock_reader (app->slot); + err = lock_reader (app->slot, ctrl); if (err) return err; err = app->fnc.learn_status (app, ctrl, flags); @@ -604,7 +621,7 @@ return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.readcert) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, NULL/* FIXME*/); if (err) return err; err = app->fnc.readcert (app, certid, cert, certlen); @@ -636,7 +653,7 @@ return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.readkey) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, NULL /*FIXME*/); if (err) return err; err= app->fnc.readkey (app, keyid, pk, pklen); @@ -678,7 +695,7 @@ if (!app->fnc.getattr) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, ctrl); if (err) return err; err = app->fnc.getattr (app, ctrl, name); @@ -701,7 +718,7 @@ return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.setattr) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, NULL /*FIXME*/); if (err) return err; err = app->fnc.setattr (app, name, pincb, pincb_arg, value, valuelen); @@ -727,7 +744,7 @@ return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.sign) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, NULL /*FIXME*/); if (err) return err; err = app->fnc.sign (app, keyidstr, hashalgo, @@ -759,7 +776,7 @@ return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.auth) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, NULL /*FIXME*/); if (err) return err; err = app->fnc.auth (app, keyidstr, @@ -791,7 +808,7 @@ return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.decipher) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, NULL /*FIXME*/); if (err) return err; err = app->fnc.decipher (app, keyidstr, @@ -821,7 +838,7 @@ return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.writecert) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, ctrl); if (err) return err; err = app->fnc.writecert (app, ctrl, certidstr, @@ -849,7 +866,7 @@ return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.writekey) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, ctrl); if (err) return err; err = app->fnc.writekey (app, ctrl, keyidstr, flags, @@ -876,7 +893,7 @@ return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.genkey) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, ctrl); if (err) return err; err = app->fnc.genkey (app, ctrl, keynostr, flags, @@ -900,7 +917,7 @@ return gpg_error (GPG_ERR_INV_VALUE); if (!app->ref_count) return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); - err = lock_reader (app->slot); + err = lock_reader (app->slot, NULL /*FIXME*/); if (err) return err; err = iso7816_get_challenge (app->slot, nbytes, buffer); @@ -924,7 +941,7 @@ return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.change_pin) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, ctrl); if (err) return err; err = app->fnc.change_pin (app, ctrl, chvnostr, reset_mode, @@ -952,7 +969,7 @@ return gpg_error (GPG_ERR_CARD_NOT_INITIALIZED); if (!app->fnc.check_pin) return gpg_error (GPG_ERR_UNSUPPORTED_OPERATION); - err = lock_reader (app->slot); + err = lock_reader (app->slot, NULL /*FIXME*/); if (err) return err; err = app->fnc.check_pin (app, keyidstr, pincb, pincb_arg); Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2009-07-10 10:47:30 UTC (rev 5074) +++ trunk/scd/ccid-driver.c 2009-07-13 09:59:22 UTC (rev 5075) @@ -254,6 +254,12 @@ int apdu_level; /* Reader supports short APDU level exchange. With a value of 2 short and extended level is supported.*/ + time_t last_progress; /* Last time we sent progress line. */ + + /* The progress callback and its first arg as supplied to + ccid_set_progress_cb. */ + void (*progress_cb)(void *, const char *, int, int, int); + void *progress_cb_arg; }; @@ -302,6 +308,23 @@ } +static void +print_progress (ccid_driver_t handle) +{ + time_t ct = time (NULL); + + /* We don't want to print progress lines too often. */ + if (ct == handle->last_progress) + return; + + if (handle->progress_cb) + handle->progress_cb (handle->progress_cb_arg, "card_busy", 'w', 0, 0); + + handle->last_progress = ct; +} + + + /* Pint an error message for a failed CCID command including a textual error code. MSG shall be the CCID message at a minimum of 10 bytes. */ static void @@ -1670,6 +1693,20 @@ } +int +ccid_set_progress_cb (ccid_driver_t handle, + void (*cb)(void *, const char *, int, int, int), + void *cb_arg) +{ + if (!handle || !handle->rid) + return CCID_DRIVER_ERR_INV_VALUE; + + handle->progress_cb = cb; + handle->progress_cb_arg = cb_arg; + return 0; +} + + /* Close the reader HANDLE. */ int ccid_close_reader (ccid_driver_t handle) @@ -2894,6 +2931,7 @@ tpdu[tpdulen++] = (edc >> 8); tpdu[tpdulen++] = edc; DEBUGOUT_1 ("T=1: waittime extension of bwi=%d\n", bwi); + print_progress (handle); } else if ( (tpdu[1] & 0x20) && (tpdu[1] & 0x1f) == 0 && !tpdu[2]) { From cvs at cvs.gnupg.org Mon Jul 13 11:59:50 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 13 Jul 2009 11:59:50 +0200 Subject: [svn] GnuPG - r5076 - trunk/scd Message-ID: Author: wk Date: 2009-07-13 11:59:50 +0200 (Mon, 13 Jul 2009) New Revision: 5076 Modified: trunk/scd/apdu.h trunk/scd/ccid-driver.h Log: Add new prototypes Modified: trunk/scd/apdu.h =================================================================== --- trunk/scd/apdu.h 2009-07-13 09:59:22 UTC (rev 5075) +++ trunk/scd/apdu.h 2009-07-13 09:59:50 UTC (rev 5076) @@ -105,6 +105,8 @@ int apdu_connect (int slot); int apdu_disconnect (int slot); +int apdu_set_progress_cb (int slot, gcry_handler_progress_t cb, void *cb_arg); + int apdu_activate (int slot); int apdu_reset (int slot); int apdu_get_status (int slot, int hang, Modified: trunk/scd/ccid-driver.h =================================================================== --- trunk/scd/ccid-driver.h 2009-07-13 09:59:22 UTC (rev 5075) +++ trunk/scd/ccid-driver.h 2009-07-13 09:59:50 UTC (rev 5076) @@ -80,6 +80,9 @@ int ccid_set_debug_level (int level); char *ccid_get_reader_list (void); int ccid_open_reader (ccid_driver_t *handle, const char *readerid); +int ccid_set_progress_cb (ccid_driver_t handle, + void (*cb)(void *, const char *, int, int, int), + void *cb_arg); int ccid_shutdown_reader (ccid_driver_t handle); int ccid_close_reader (ccid_driver_t handle); int ccid_get_atr (ccid_driver_t handle, From cvs at cvs.gnupg.org Mon Jul 13 12:29:41 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 13 Jul 2009 12:29:41 +0200 Subject: [svn] GnuPG - r5077 - branches/STABLE-BRANCH-1-4/po Message-ID: Author: wk Date: 2009-07-13 12:29:40 +0200 (Mon, 13 Jul 2009) New Revision: 5077 Modified: branches/STABLE-BRANCH-1-4/po/ChangeLog branches/STABLE-BRANCH-1-4/po/nl.po Log: fix bug#1085. Modified: branches/STABLE-BRANCH-1-4/po/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/po/ChangeLog 2009-07-13 09:59:50 UTC (rev 5076) +++ branches/STABLE-BRANCH-1-4/po/ChangeLog 2009-07-13 10:29:40 UTC (rev 5077) @@ -1,3 +1,7 @@ +2009-07-13 Werner Koch + + * nl.po: Applied a small fix by Jeroen Leeuwestein. Fixes bug#1085. + 2009-06-17 Ga?l Qu?ri (up) * fr.po: Updated. Modified: branches/STABLE-BRANCH-1-4/po/nl.po [not shown] From cvs at cvs.gnupg.org Mon Jul 13 16:43:48 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 13 Jul 2009 16:43:48 +0200 Subject: [svn] pinentry - r210 - in trunk: . qt4 Message-ID: Author: marcus Date: 2009-07-13 16:43:48 +0200 (Mon, 13 Jul 2009) New Revision: 210 Modified: trunk/ChangeLog trunk/qt4/pinentrydialog.cpp Log: 2009-07-10 Till Adam * qt4/pinentrydialog.cpp (PinEntryDialog): Redesign the dialog to be prettier. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-06-19 07:39:10 UTC (rev 209) +++ trunk/ChangeLog 2009-07-13 14:43:48 UTC (rev 210) @@ -1,3 +1,8 @@ +2009-07-10 Till Adam + + * qt4/pinentrydialog.cpp (PinEntryDialog): Redesign the dialog to + be prettier. + 2009-06-19 Marcus Brinkmann * configure.ac: Post-release changes. Modified: trunk/qt4/pinentrydialog.cpp =================================================================== --- trunk/qt4/pinentrydialog.cpp 2009-06-19 07:39:10 UTC (rev 209) +++ trunk/qt4/pinentrydialog.cpp 2009-07-13 14:43:48 UTC (rev 210) @@ -44,22 +44,22 @@ QBoxLayout* top = new QVBoxLayout( this ); top->setMargin( 6 ); QBoxLayout* upperLayout = new QHBoxLayout(); - top->addLayout( upperLayout ); + top->addLayout( upperLayout, 1 ); _icon = new QLabel( this ); _icon->setPixmap( QMessageBox::standardIcon( QMessageBox::Information ) ); upperLayout->addWidget( _icon ); QBoxLayout* labelLayout = new QVBoxLayout(); - upperLayout->addLayout( labelLayout ); + upperLayout->addLayout( labelLayout, 5 ); _error = new QLabel( this ); _error->setWordWrap(true); - labelLayout->addWidget( _error ); + labelLayout->addWidget( _error, 1 ); _desc = new QLabel( this ); _desc->setWordWrap(true); - labelLayout->addWidget( _desc ); + labelLayout->addWidget( _desc, 5 ); QGridLayout* grid = new QGridLayout; top->addLayout( grid ); @@ -107,6 +107,8 @@ this, SLOT (reject ())); _edit->setFocus(); + setMinimumWidth( 450 ); + resize( minimumSizeHint() ); } void PinEntryDialog::hideEvent( QHideEvent* ev ) From cvs at cvs.gnupg.org Mon Jul 13 19:36:03 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 13 Jul 2009 19:36:03 +0200 Subject: [svn] GnuPG - r5078 - in trunk: doc g10 Message-ID: Author: wk Date: 2009-07-13 19:36:02 +0200 (Mon, 13 Jul 2009) New Revision: 5078 Modified: trunk/doc/DETAILS trunk/g10/ChangeLog trunk/g10/exec.c Log: [g10] * exec.c: Fix function name indentation. (expand_args): Simplify by using membuf functions. (exec_write): Fix memory leak on error. (w32_system): Use DETACHED_PROCESS so that a new console is not created. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-07-13 10:29:40 UTC (rev 5077) +++ trunk/g10/ChangeLog 2009-07-13 17:36:02 UTC (rev 5078) @@ -1,3 +1,11 @@ +2009-07-13 Werner Koch + + * exec.c: Fix function name indentation. + (expand_args): Simplify by using membuf functions. + (exec_write): Fix memory leak on error. + (w32_system): Use DETACHED_PROCESS so that a new console is not + created. + 2009-07-09 Werner Koch * card-util.c (card_store_subkey): Do not restrict to 1024 bit keys. Modified: trunk/doc/DETAILS =================================================================== --- trunk/doc/DETAILS 2009-07-13 10:29:40 UTC (rev 5077) +++ trunk/doc/DETAILS 2009-07-13 17:36:02 UTC (rev 5078) @@ -521,6 +521,7 @@ running as a daemon. "learncard" Send by the agent and gpgsm while learing the data of a smartcard. + "card_busy" A smartcard is still working SIG_CREATED A signature has been created using these parameters. Modified: trunk/g10/exec.c =================================================================== --- trunk/g10/exec.c 2009-07-13 10:29:40 UTC (rev 5077) +++ trunk/g10/exec.c 2009-07-13 17:36:02 UTC (rev 5078) @@ -17,6 +17,12 @@ * along with this program; if not, see . */ +/* + FIXME: We should replace most code in this module by our + spawn implementation from common/exechelp.c. + */ + + #include #include #include @@ -40,19 +46,24 @@ #include "iobuf.h" #include "util.h" #include "mkdtemp.h" /* From gnulib. */ +#include "membuf.h" #include "exec.h" #ifdef NO_EXEC -int exec_write(struct exec_info **info,const char *program, +int +exec_write(struct exec_info **info,const char *program, const char *args_in,const char *name,int writeonly,int binary) { log_error(_("no remote program execution supported\n")); return G10ERR_GENERAL; } -int exec_read(struct exec_info *info) { return G10ERR_GENERAL; } -int exec_finish(struct exec_info *info) { return G10ERR_GENERAL; } -int set_exec_path(const char *path) { return G10ERR_GENERAL; } +int +exec_read(struct exec_info *info) { return G10ERR_GENERAL; } +int +exec_finish(struct exec_info *info) { return G10ERR_GENERAL; } +int +set_exec_path(const char *path) { return G10ERR_GENERAL; } #else /* ! NO_EXEC */ @@ -60,7 +71,8 @@ /* This is a nicer system() for windows that waits for programs to return before returning control to the caller. I hate helpful computers. */ -static int w32_system(const char *command) +static int +w32_system(const char *command) { PROCESS_INFORMATION pi; STARTUPINFO si; @@ -74,7 +86,9 @@ memset(&si,0,sizeof(si)); si.cb=sizeof(si); - if(!CreateProcess(NULL,string,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) + if(!CreateProcess(NULL,string,NULL,NULL,FALSE, + DETACHED_PROCESS, + NULL,NULL,&si,&pi)) return -1; /* Wait for the child to exit */ @@ -89,7 +103,8 @@ #endif /* Replaces current $PATH */ -int set_exec_path(const char *path) +int +set_exec_path(const char *path) { char *p; @@ -111,7 +126,8 @@ } /* Makes a temp directory and filenames */ -static int make_tempdir(struct exec_info *info) +static int +make_tempdir(struct exec_info *info) { char *tmp=opt.temp_dir,*namein=info->name,*nameout; @@ -192,10 +208,11 @@ /* Expands %i and %o in the args to the full temp files within the temp directory. */ -static int expand_args(struct exec_info *info,const char *args_in) +static int +expand_args(struct exec_info *info,const char *args_in) { - const char *ch=args_in; - unsigned int size,len; + const char *ch = args_in; + membuf_t command; info->flags.use_temp_files=0; info->flags.keep_temp_files=0; @@ -203,10 +220,7 @@ if(DBG_EXTPROG) log_debug("expanding string \"%s\"\n",args_in); - size=100; - info->command=xmalloc(size); - len=0; - info->command[0]='\0'; + init_membuf (&command, 100); while(*ch!='\0') { @@ -252,37 +266,20 @@ } if(append) - { - size_t applen=strlen(append); - - if(applen+len>size-1) - { - if(applen<100) - applen=100; - - size+=applen; - info->command=xrealloc(info->command,size); - } - - strcat(info->command,append); - len+=strlen(append); - } + put_membuf_str (&command, append); } else - { - if(len==size-1) /* leave room for the \0 */ - { - size+=100; - info->command=xrealloc(info->command,size); - } + put_membuf (&command, ch, 1); - info->command[len++]=*ch; - info->command[len]='\0'; - } - ch++; } + put_membuf (&command, "", 1); /* Terminate string. */ + + info->command = get_membuf (&command, NULL); + if (!info->command) + return gpg_error_from_syserror (); + if(DBG_EXTPROG) log_debug("args expanded to \"%s\", use %u, keep %u\n",info->command, info->flags.use_temp_files,info->flags.keep_temp_files); @@ -290,10 +287,7 @@ return 0; fail: - - xfree(info->command); - info->command=NULL; - + xfree (get_membuf (&command, NULL)); return G10ERR_GENERAL; } @@ -303,8 +297,9 @@ If there are args, but no tempfiles, then it's a fork/exec/pipe via shell -c. If there are tempfiles, then it's a system. */ -int exec_write(struct exec_info **info,const char *program, - const char *args_in,const char *name,int writeonly,int binary) +int +exec_write(struct exec_info **info,const char *program, + const char *args_in,const char *name,int writeonly,int binary) { int ret=G10ERR_GENERAL; @@ -483,10 +478,16 @@ ret=0; fail: + if (ret) + { + xfree (*info); + *info = NULL; + } return ret; } -int exec_read(struct exec_info *info) +int +exec_read(struct exec_info *info) { int ret=G10ERR_GENERAL; @@ -565,7 +566,8 @@ return ret; } -int exec_finish(struct exec_info *info) +int +exec_finish(struct exec_info *info) { int ret=info->progreturn; From cvs at cvs.gnupg.org Thu Jul 16 09:40:17 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 16 Jul 2009 09:40:17 +0200 Subject: [svn] GnuPG - r5079 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2009-07-16 09:40:16 +0200 (Thu, 16 Jul 2009) New Revision: 5079 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/misc.c Log: Fix bug#1087. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-13 17:36:02 UTC (rev 5078) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-16 07:40:16 UTC (rev 5079) @@ -1,3 +1,8 @@ +2009-07-16 Werner Koch + + * misc.c (has_invalid_email_chars): Let non-ascii characters pass + through. Fixes bug#1087. + 2009-06-24 Werner Koch * passphrase.c (passphrase_to_dek): Do not deref a PW of NULL. @@ -13459,7 +13464,7 @@ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, - 2007 Free Software Foundation, Inc. + 2007, 2008, 2009 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 Modified: branches/STABLE-BRANCH-1-4/g10/misc.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/misc.c 2009-07-13 17:36:02 UTC (rev 5078) +++ branches/STABLE-BRANCH-1-4/g10/misc.c 2009-07-16 07:40:16 UTC (rev 5079) @@ -1132,6 +1132,16 @@ } +/* Check whether the string has characters not valid in an RFC-822 + address. To cope with OpenPGP we ignore non-ascii characters + so that for example umlauts are legal in an email address. An + OpenPGP user ID must be utf-8 encoded but there is no strict + requirement for RFC-822. Thus to avoid IDNA encoding we put the + address verbatim as utf-8 into the user ID under the assumption + that mail programs handle IDNA at a lower level and take OpenPGP + user IDs as utf-8. Note that we can't do an utf-8 encoding + checking here because in keygen.c this function is called with the + native encoding and native to utf-8 encoding is only done later. */ int has_invalid_email_chars (const char *s) { @@ -1142,7 +1152,7 @@ for ( ; *s; s++ ) { if ( *s & 0x80 ) - return 1; + continue; /* We only care about ASCII. */ if ( *s == '@' ) at_seen=1; else if ( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) ) From cvs at cvs.gnupg.org Thu Jul 16 17:55:00 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 16 Jul 2009 17:55:00 +0200 Subject: [svn] GnuPG - r5080 - trunk/scd Message-ID: Author: wk Date: 2009-07-16 17:54:59 +0200 (Thu, 16 Jul 2009) New Revision: 5080 Modified: trunk/scd/ChangeLog trunk/scd/apdu.c trunk/scd/apdu.h trunk/scd/app.c trunk/scd/ccid-driver.c trunk/scd/command.c trunk/scd/scdaemon.c Log: Add code to better handle unplugging of a reader. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-07-16 07:40:16 UTC (rev 5079) +++ trunk/scd/ChangeLog 2009-07-16 15:54:59 UTC (rev 5080) @@ -1,3 +1,17 @@ +2009-07-16 Werner Koch + + * command.c (update_reader_status_file): Test for unplugged reader. + (TEST_CARD_REMOVAL): Ditto. + * app.c (select_application): Ditto. + * ccid-driver.c (bulk_out): Return CCID_DRIVER_ERR_NO_READER if a + reader was unplugged. + (struct ccid_driver_s): Turn nonnull_nad into an unsigned char. + Turn apdu_level, auto_ifsd, powered_off, has_pinpad into + bitfields. Add enodev_seen. + * apdu.c (apdu_prepare_exit): New. + (get_status_ccid): Return the status word and nut just -1. + * scdaemon.c (scd_exit): Call it. + 2009-07-13 Werner Koch * ccid-driver.c (struct ccid_driver_s): Add fields last_progress, Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2009-07-16 07:40:16 UTC (rev 5079) +++ trunk/scd/apdu.c 2009-07-16 15:54:59 UTC (rev 5080) @@ -1853,7 +1853,7 @@ rc = ccid_slot_status (reader_table[slot].ccid.handle, &bits); if (rc) - return -1; + return rc; if (bits == 0) *status = (APDU_CARD_USABLE|APDU_CARD_PRESENT|APDU_CARD_ACTIVE); @@ -2523,6 +2523,33 @@ return SW_HOST_NOT_SUPPORTED; } + +/* Function suitable for a cleanup function to close all reader. It + should not be used if the reader will be opened again. The reason + for implementing this to properly close USB devices so that they + will startup the next time without error. */ +void +apdu_prepare_exit (void) +{ + static int sentinel; + int slot; + + if (!sentinel) + { + sentinel = 1; + for (slot = 0; slot < MAX_READER; slot++) + if (reader_table[slot].used) + { + apdu_disconnect (slot); + if (reader_table[slot].close_reader) + reader_table[slot].close_reader (slot); + reader_table[slot].used = 0; + } + sentinel = 0; + } +} + + /* Shutdown a reader; that is basically the same as a close but keeps the handle ready for later use. A apdu_reset_reader or apdu_connect should be used to get it active again. */ Modified: trunk/scd/apdu.h =================================================================== --- trunk/scd/apdu.h 2009-07-16 07:40:16 UTC (rev 5079) +++ trunk/scd/apdu.h 2009-07-16 15:54:59 UTC (rev 5080) @@ -94,6 +94,7 @@ void *closefnc_value); int apdu_shutdown_reader (int slot); int apdu_close_reader (int slot); +void apdu_prepare_exit (void); int apdu_enum_reader (int slot, int *used); unsigned char *apdu_get_atr (int slot, size_t *atrlen); Modified: trunk/scd/app.c =================================================================== --- trunk/scd/app.c 2009-07-16 07:40:16 UTC (rev 5079) +++ trunk/scd/app.c 2009-07-16 15:54:59 UTC (rev 5080) @@ -367,10 +367,10 @@ } /* For certain error codes, there is no need to try more. */ - if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT) + if (gpg_err_code (err) == GPG_ERR_CARD_NOT_PRESENT + || gpg_err_code (err) == GPG_ERR_ENODEV) goto leave; - /* Figure out the application to use. */ err = gpg_error (GPG_ERR_NOT_FOUND); Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2009-07-16 07:40:16 UTC (rev 5079) +++ trunk/scd/ccid-driver.c 2009-07-16 15:54:59 UTC (rev 5080) @@ -84,6 +84,7 @@ #include #include #include +#include #include @@ -244,16 +245,18 @@ int seqno; unsigned char t1_ns; unsigned char t1_nr; - int nonnull_nad; - int auto_ifsd; + unsigned char nonnull_nad; int max_ifsd; int ifsd; int ifsc; - int powered_off; - int has_pinpad; - int apdu_level; /* Reader supports short APDU level exchange. - With a value of 2 short and extended level is - supported.*/ + unsigned char apdu_level:2; /* Reader supports short APDU level + exchange. With a value of 2 short + and extended level is supported.*/ + unsigned int auto_ifsd:1; + unsigned int powered_off:1; + unsigned int has_pinpad:2; + unsigned int enodev_seen:1; + time_t last_progress; /* Last time we sent progress line. */ /* The progress callback and its first arg as supplied to @@ -1423,7 +1426,7 @@ /* Set the level of debugging to LEVEL and return the old level. -1 just returns the old level. A level of 0 disables debugging, 1 enables debugging, 2 enables additional tracing of the T=1 - protocol, 3 additionally enables debuggng for GetSlotStatus, other + protocol, 3 additionally enables debugging for GetSlotStatus, other values are not yet defined. Note that libusb may provide its own debugging feature which is @@ -1763,6 +1766,11 @@ { int rc; + /* No need to continue and clutter the log withy USB error if we + ever got an ENODEV. */ + if (handle->enodev_seen) + return CCID_DRIVER_ERR_NO_READER; + if (debug_level && (!no_debug || debug_level >= 3)) { switch (msglen? msg[0]:0) @@ -1823,8 +1831,27 @@ 5000 /* ms timeout */); if (rc == msglen) return 0; +#ifdef ENODEV + if (rc == -(ENODEV)) + { + /* The Linux libusb returns a negative error value. Catch + the most important one. */ + errno = ENODEV; + rc = -1; + } +#endif /*ENODEV*/ + if (rc == -1) - DEBUGOUT_1 ("usb_bulk_write error: %s\n", strerror (errno)); + { + DEBUGOUT_1 ("usb_bulk_write error: %s\n", strerror (errno)); +#ifdef ENODEV + if (errno == ENODEV) + { + handle->enodev_seen = 1; + return CCID_DRIVER_ERR_NO_READER; + } +#endif /*ENODEV*/ + } else DEBUGOUT_1 ("usb_bulk_write failed: %d\n", rc); } Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2009-07-16 07:40:16 UTC (rev 5079) +++ trunk/scd/command.c 2009-07-16 15:54:59 UTC (rev 5080) @@ -54,12 +54,14 @@ #define set_error(e,t) assuan_set_error (ctx, gpg_error (e), (t)) -/* Macro to flag a removed card. */ +/* Macro to flag a removed card. ENODEV is also tested to catch teh + case of a removed reader. */ #define TEST_CARD_REMOVAL(c,r) \ do { \ int _r = (r); \ if (gpg_err_code (_r) == GPG_ERR_CARD_NOT_PRESENT \ - || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED) \ + || gpg_err_code (_r) == GPG_ERR_CARD_REMOVED \ + || gpg_err_code (_r) == GPG_ERR_ENODEV ) \ update_card_removed ((c)->reader_slot, 1); \ } while (0) @@ -2159,8 +2161,14 @@ continue; /* Not valid or reader not yet open. */ sw_apdu = apdu_get_status (ss->slot, 0, &status, &changed); - if (sw_apdu) + if (sw_apdu == SW_HOST_NO_READER) { + /* Most likely the _reader_ has been unplugged. */ + status = 0; + changed = ss->changed; + } + else if (sw_apdu) + { /* Get status failed. Ignore that. */ continue; } Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2009-07-16 07:40:16 UTC (rev 5079) +++ trunk/scd/scdaemon.c 2009-07-16 15:54:59 UTC (rev 5080) @@ -48,6 +48,7 @@ #include "i18n.h" #include "sysutils.h" #include "app-common.h" +#include "apdu.h" #include "ccid-driver.h" #include "mkdtemp.h" #include "gc-opt-flags.h" @@ -858,6 +859,7 @@ void scd_exit (int rc) { + apdu_prepare_exit (); #if 0 #warning no update_random_seed_file update_random_seed_file(); From cvs at cvs.gnupg.org Fri Jul 17 03:37:42 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 17 Jul 2009 03:37:42 +0200 Subject: [svn] gpg-error - r215 - in trunk: . src Message-ID: Author: marcus Date: 2009-07-17 03:37:42 +0200 (Fri, 17 Jul 2009) New Revision: 215 Modified: trunk/ChangeLog trunk/README trunk/src/code-from-errno.c trunk/src/mkerrcodes1.awk Log: 2009-07-17 Marcus Brinkmann * src/mkerrcodes1.awk: Output code to cause WSA Errors to be transparently translated. * src/code-from-errno.c [HAVE_W32_SYSTEM]: Don't include winsock2.h. (w32_special_errnos) [HAVE_W32_SYSTEM]: Removed. (gpg_err_code_from_errno) [HAVE_W32_SYSTEM]: Remove special case. * README: Document problem with printing some WSA Errors. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-06-23 15:04:47 UTC (rev 214) +++ trunk/ChangeLog 2009-07-17 01:37:42 UTC (rev 215) @@ -1,3 +1,12 @@ +2009-07-17 Marcus Brinkmann + + * src/mkerrcodes1.awk: Output code to cause WSA Errors to be + transparently translated. + * src/code-from-errno.c [HAVE_W32_SYSTEM]: Don't include winsock2.h. + (w32_special_errnos) [HAVE_W32_SYSTEM]: Removed. + (gpg_err_code_from_errno) [HAVE_W32_SYSTEM]: Remove special case. + * README: Document problem with printing some WSA Errors. + 2009-06-23 Marcus Brinkmann Update to libtool 2.2.6a. Modified: trunk/README =================================================================== --- trunk/README 2009-06-23 15:04:47 UTC (rev 214) +++ trunk/README 2009-07-17 01:37:42 UTC (rev 215) @@ -74,3 +74,17 @@ Now check that this checksum is _exactly_ the same as the one published via the announcement list and probably via Usenet. + + +Known Problems +-------------- + +On Windows, WSA Error Codes can be provided as system error codes and +will be transparently converted to the corresponding gpg error codes. +However, not all of them have detailed description when printed with +gpg_strerror, but will default to "Unknown system error (NUMBER)" for +pretty printing. For example, WSAEHOSTDOWN will be translated to +GPG_ERR_EHOSTDOWN, but there is no corresponding EHOSTDOWN in Windows +and thus gpg_strerror will default to "Unknown system error (8029)". +(This could be fixed by adding our own error strings replacing or +extending the system error strings, including their translations). Modified: trunk/src/code-from-errno.c =================================================================== --- trunk/src/code-from-errno.c 2009-06-23 15:04:47 UTC (rev 214) +++ trunk/src/code-from-errno.c 2009-07-17 01:37:42 UTC (rev 215) @@ -23,37 +23,11 @@ #endif #include -#ifdef HAVE_W32_SYSTEM -#include -#endif #include #include "code-from-errno.h" -#ifdef HAVE_W32_SYSTEM -/* Under Windows socket related error codes are defined in a different - file and prefixed with "WSA". As their ranges don't overlap, we map - some of them to our usual error codes. */ -gpg_err_code_t -w32_special_errnos (int err) -{ - switch (err) - { - case WSAEADDRINUSE: return GPG_ERR_EADDRINUSE; - case WSAEADDRNOTAVAIL: return GPG_ERR_EADDRNOTAVAIL; - case WSAECONNABORTED: return GPG_ERR_ECONNABORTED; - case WSAECONNREFUSED: return GPG_ERR_ECONNREFUSED; - case WSAECONNRESET: return GPG_ERR_ECONNRESET; - case WSAENAMETOOLONG: return GPG_ERR_ENAMETOOLONG; - case WSAEHOSTDOWN: return GPG_ERR_EHOSTDOWN; - case WSAEHOSTUNREACH: return GPG_ERR_EHOSTUNREACH; - default: - return GPG_ERR_UNKNOWN_ERRNO; - } -} -#endif /*HAVE_W32_SYSTEM*/ - /* Retrieve the error code for the system error ERR. This returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report this). */ @@ -68,13 +42,7 @@ idx = errno_to_idx (err); if (idx < 0) - { -#ifdef HAVE_W32_SYSTEM - return w32_special_errnos (err); -#else - return GPG_ERR_UNKNOWN_ERRNO; -#endif - } + return GPG_ERR_UNKNOWN_ERRNO; return GPG_ERR_SYSTEM_ERROR | err_code_from_index[idx]; } @@ -95,13 +63,7 @@ idx = errno_to_idx (err); if (idx < 0) - { -#ifdef HAVE_W32_SYSTEM - return w32_special_errnos (err); -#else - return GPG_ERR_UNKNOWN_ERRNO; -#endif - } + return GPG_ERR_UNKNOWN_ERRNO; return GPG_ERR_SYSTEM_ERROR | err_code_from_index[idx]; } Modified: trunk/src/mkerrcodes1.awk =================================================================== --- trunk/src/mkerrcodes1.awk 2009-06-23 15:04:47 UTC (rev 214) +++ trunk/src/mkerrcodes1.awk 2009-07-17 01:37:42 UTC (rev 215) @@ -70,7 +70,10 @@ if ($1 ~ /^[0-9]/) { print "#include "; - print ""; + print "#ifdef _WIN32"; + print "#include "; + print "#endif"; + print ""; header = 0; } else @@ -87,4 +90,7 @@ print "#ifdef " $errnoidx; print $errnoidx "\tGPG_ERR_" $errnoidx; print "#endif"; + print "#ifdef WSA" $errnoidx; + print "WSA" $errnoidx "\tGPG_ERR_" $errnoidx; + print "#endif"; } From cvs at cvs.gnupg.org Fri Jul 17 03:53:20 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 17 Jul 2009 03:53:20 +0200 Subject: [svn] gpg-error - r216 - in trunk: . src Message-ID: Author: marcus Date: 2009-07-17 03:53:19 +0200 (Fri, 17 Jul 2009) New Revision: 216 Modified: trunk/ChangeLog trunk/README trunk/src/mkerrnos.awk Log: 2009-07-17 Marcus Brinkmann * src/mkerrnos.awk: Output code to cause WSA Errors to be found from gpg error codes. * README: Add problem of translating error codes back and forth. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-07-17 01:37:42 UTC (rev 215) +++ trunk/ChangeLog 2009-07-17 01:53:19 UTC (rev 216) @@ -1,5 +1,9 @@ 2009-07-17 Marcus Brinkmann + * src/mkerrnos.awk: Output code to cause WSA Errors to be found + from gpg error codes. + * README: Add problem of translating error codes back and forth. + * src/mkerrcodes1.awk: Output code to cause WSA Errors to be transparently translated. * src/code-from-errno.c [HAVE_W32_SYSTEM]: Don't include winsock2.h. Modified: trunk/README =================================================================== --- trunk/README 2009-07-17 01:37:42 UTC (rev 215) +++ trunk/README 2009-07-17 01:53:19 UTC (rev 216) @@ -81,10 +81,22 @@ On Windows, WSA Error Codes can be provided as system error codes and will be transparently converted to the corresponding gpg error codes. -However, not all of them have detailed description when printed with -gpg_strerror, but will default to "Unknown system error (NUMBER)" for -pretty printing. For example, WSAEHOSTDOWN will be translated to -GPG_ERR_EHOSTDOWN, but there is no corresponding EHOSTDOWN in Windows -and thus gpg_strerror will default to "Unknown system error (8029)". -(This could be fixed by adding our own error strings replacing or -extending the system error strings, including their translations). +There are two problems with this support: + +* Not all error codes corresponding to WSA Error codes have a detailed + description when printed with gpg_strerror. Some will default to + "Unknown error" for pretty printing. For example, WSAEHOSTDOWN will + be translated to GPG_ERR_EHOSTDOWN, but there is no corresponding + EHOSTDOWN in Windows and thus gpg_strerror will default to "Unknown + error" as printed by the system's strerror function for the argument + WSAEHOSTDOWN. (This could be fixed by adding our own error strings + replacing or extending the system error strings, including their + translations). + +* The translation to a gpg error code and back to a system error code + in some cases does not preserve information. For example, the error code + WSAEACCES translates to GPG_ERR_EACCES, which translates back to + EACCES. + +Any WSA Error code has either the first problem or the second (but not +both), depending on if there is a corresponding Windows error code. Modified: trunk/src/mkerrnos.awk =================================================================== --- trunk/src/mkerrnos.awk 2009-07-17 01:37:42 UTC (rev 215) +++ trunk/src/mkerrnos.awk 2009-07-17 01:53:19 UTC (rev 216) @@ -71,6 +71,9 @@ if ($1 ~ /^[0-9]/) { print "#include "; + print "#ifdef _WIN32"; + print "#include "; + print "#endif"; print ""; print "static const int err_code_to_errno [] = {"; header = 0; @@ -89,8 +92,12 @@ print "#ifdef " $errnoidx; print " " $errnoidx ","; print "#else"; + print "#ifdef WSA" $errnoidx; + print " WSA" $errnoidx ","; + print "#else"; print " 0,"; print "#endif"; + print "#endif"; } END { print "};"; From cvs at cvs.gnupg.org Fri Jul 17 13:24:52 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 17 Jul 2009 13:24:52 +0200 Subject: [svn] GnuPG - r5081 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2009-07-17 13:24:51 +0200 (Fri, 17 Jul 2009) New Revision: 5081 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/keyring.c Log: Repalce an assert by a proper error message. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-16 15:54:59 UTC (rev 5080) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-17 11:24:51 UTC (rev 5081) @@ -1,3 +1,8 @@ +2009-07-17 Werner Koch + + * keyring.c (keyring_rebuild_cache): Replace the assert by a + proper error message and allow to delete a bad keyblock. + 2009-07-16 Werner Koch * misc.c (has_invalid_email_chars): Let non-ascii characters pass Modified: branches/STABLE-BRANCH-1-4/g10/keyring.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keyring.c 2009-07-16 15:54:59 UTC (rev 5080) +++ branches/STABLE-BRANCH-1-4/g10/keyring.c 2009-07-17 11:24:51 UTC (rev 5081) @@ -1399,7 +1399,20 @@ log_error ("keyring_get_keyblock failed: %s\n", g10_errstr(rc)); goto leave; } - assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY); + if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY) + { + /* We had a few reports about corrupted keyrings; if we have + been called directly from the command line we delete such + a keyblock instead of bailing out. */ + log_error ("unexpected keyblock found (pkttype=%d)%s\n", + keyblock->pkt->pkttype, noisy? " - deleted":""); + if (noisy) + continue; + log_info ("Hint: backup your keys and try running `%s'\n", + "gpg --rebuild-keydb-caches"); + rc = G10ERR_INV_KEYRING; + goto leave; + } /* check all signature to set the signature's cache flags */ for (node=keyblock; node; node=node->next) From cvs at cvs.gnupg.org Fri Jul 17 19:28:15 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 17 Jul 2009 19:28:15 +0200 Subject: [svn] GpgEX - r69 - trunk/src Message-ID: Author: marcus Date: 2009-07-17 19:28:14 +0200 (Fri, 17 Jul 2009) New Revision: 69 Modified: trunk/src/ChangeLog trunk/src/gpgex.cc Log: 2009-07-17 Marcus Brinkmann * gpgex.cc (start_help): Do not cripple the browser window. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-03-24 20:10:00 UTC (rev 68) +++ trunk/src/ChangeLog 2009-07-17 17:28:14 UTC (rev 69) @@ -1,3 +1,7 @@ +2009-07-17 Marcus Brinkmann + + * gpgex.cc (start_help): Do not cripple the browser window. + 2009-03-10 Marcus Brinkmann * client.h, client.cc, gpgex.cc: Change encrypt&sign to Modified: trunk/src/gpgex.cc =================================================================== --- trunk/src/gpgex.cc 2009-03-24 20:10:00 UTC (rev 68) +++ trunk/src/gpgex.cc 2009-07-17 17:28:14 UTC (rev 69) @@ -505,10 +505,10 @@ /* FIXME: Pick a good configuration. */ // Only for IE7? // web->put_Resizable (VARIANT_TRUE); - web->put_ToolBar (FALSE); - web->put_AddressBar (VARIANT_FALSE); - web->put_MenuBar (VARIANT_FALSE); - web->put_StatusBar (VARIANT_FALSE); + // web->put_ToolBar (FALSE); + // web->put_AddressBar (VARIANT_FALSE); + // web->put_MenuBar (VARIANT_FALSE); + // web->put_StatusBar (VARIANT_FALSE); // width, height web->put_Visible (VARIANT_TRUE); From cvs at cvs.gnupg.org Mon Jul 20 12:42:46 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 20 Jul 2009 12:42:46 +0200 Subject: [svn] GnuPG - r5082 - trunk/doc Message-ID: Author: wk Date: 2009-07-20 12:42:45 +0200 (Mon, 20 Jul 2009) New Revision: 5082 Modified: trunk/doc/ChangeLog trunk/doc/gpg.texi Log: Fix bug 1090. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-07-17 11:24:51 UTC (rev 5081) +++ trunk/doc/ChangeLog 2009-07-20 10:42:45 UTC (rev 5082) @@ -1,3 +1,8 @@ +2009-07-20 Werner Koch + + * gpg.texi (Operational GPG Commands): Add a note for --send-keys. + Fixes bug#1090. + 2009-07-06 Werner Koch * debugging.texi (Common Problems): Add a note about corrupted Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2009-07-17 11:24:51 UTC (rev 5081) +++ trunk/doc/gpg.texi 2009-07-20 10:42:45 UTC (rev 5082) @@ -404,7 +404,7 @@ Fingerprints may be used instead of key IDs. Option @option{--keyserver} must be used to give the name of this keyserver. Don't send your complete keyring to a keyserver --- select only those keys which are new -or changed by you. +or changed by you. If no key IDs are given, @command{gpg} does nothing. @item --export-secret-keys @itemx --export-secret-subkeys From cvs at cvs.gnupg.org Mon Jul 20 13:02:20 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 20 Jul 2009 13:02:20 +0200 Subject: [svn] GnuPG - r5083 - trunk/g10 Message-ID: Author: wk Date: 2009-07-20 13:02:20 +0200 (Mon, 20 Jul 2009) New Revision: 5083 Modified: trunk/g10/ChangeLog trunk/g10/keygen.c trunk/g10/keyring.c trunk/g10/misc.c Log: Fix bug 1091. Doc fixes. Replace assert by error message. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-07-20 10:42:45 UTC (rev 5082) +++ trunk/g10/ChangeLog 2009-07-20 11:02:20 UTC (rev 5083) @@ -1,3 +1,13 @@ +2009-07-20 Werner Koch + + * keygen.c (generate_keypair): Allow Elgamal > 3072 in BOTH mode. + Reported by Jeroen Schot. Fixes bug#1091. + +2009-07-17 Werner Koch + + * keyring.c (keyring_rebuild_cache): Replace the assert by a + proper error message and allow to delete a bad keyblock. + 2009-07-13 Werner Koch * exec.c: Fix function name indentation. Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2009-07-20 10:42:45 UTC (rev 5082) +++ trunk/g10/keygen.c 2009-07-20 11:02:20 UTC (rev 5083) @@ -3123,7 +3123,7 @@ nbits = 0; } - nbits = ask_keysize (algo, nbits); + nbits = ask_keysize (both? subkey_algo : algo, nbits); r = xmalloc_clear( sizeof *r + 20 ); r->key = both? pSUBKEYLENGTH : pKEYLENGTH; sprintf( r->u.value, "%u", nbits); @@ -3400,6 +3400,15 @@ if (!timestamp) timestamp = make_timestamp (); + /* Note that, depending on the backend (i.e. the used scdaemon + version), the card key generation may update TIMESTAMP for each + key. Thus we need to pass TIMESTAMP to all signing function to + make sure that the binding signature is done using the timestamp + of the corresponding (sub)key and not that of the primary key. + An alternative implementation could tell the signing function the + node of the subkey but that is more work than just to pass the + current timestamp. */ + if (!card) { rc = do_create (get_parameter_algo( para, pKEYTYPE ), @@ -3413,8 +3422,6 @@ } else { - /* Note, that depending on the backend, the card key generation - may update TIMESTAMP. */ rc = gen_card_key (PUBKEY_ALGO_RSA, 1, 1, pub_root, sec_root, NULL, ×tamp, get_parameter_u32 (para, pKEYEXPIRE), para); @@ -3450,8 +3457,6 @@ if (!rc && card && get_parameter (para, pAUTHKEYTYPE)) { - /* Note, that depending on the backend, the card key generation - may update TIMESTAMP. */ rc = gen_card_key (PUBKEY_ALGO_RSA, 3, 0, pub_root, sec_root, NULL, ×tamp, get_parameter_u32 (para, pKEYEXPIRE), para); @@ -3493,8 +3498,6 @@ } else { - /* Note, that depending on the backend, the card key - generation may update TIMESTAMP. */ rc = gen_card_key (PUBKEY_ALGO_RSA, 2, 0, pub_root, sec_root, NULL, ×tamp, Modified: trunk/g10/keyring.c =================================================================== --- trunk/g10/keyring.c 2009-07-20 10:42:45 UTC (rev 5082) +++ trunk/g10/keyring.c 2009-07-20 11:02:20 UTC (rev 5083) @@ -1440,7 +1440,20 @@ log_error ("keyring_get_keyblock failed: %s\n", g10_errstr(rc)); goto leave; } - assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY); + if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY) + { + /* We had a few reports about corrupted keyrings; if we have + been called directly from the command line we delete such + a keyblock instead of bailing out. */ + log_error ("unexpected keyblock found (pkttype=%d)%s\n", + keyblock->pkt->pkttype, noisy? " - deleted":""); + if (noisy) + continue; + log_info ("Hint: backup your keys and try running `%s'\n", + "gpg --rebuild-keydb-caches"); + rc = gpg_error (GPG_ERR_INV_KEYRING); + goto leave; + } /* check all signature to set the signature's cache flags */ for (node=keyblock; node; node=node->next) Modified: trunk/g10/misc.c =================================================================== --- trunk/g10/misc.c 2009-07-20 10:42:45 UTC (rev 5082) +++ trunk/g10/misc.c 2009-07-20 11:02:20 UTC (rev 5083) @@ -1207,7 +1207,7 @@ /* Check whether the string has characters not valid in an RFC-822 - address. To cope with OpenPGP we ignore allow non-ascii characters + address. To cope with OpenPGP we ignore non-ascii characters so that for example umlauts are legal in an email address. An OpenPGP user ID must be utf-8 encoded but there is no strict requirement for RFC-822. Thus to avoid IDNA encoding we put the From cvs at cvs.gnupg.org Mon Jul 20 18:37:12 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 20 Jul 2009 18:37:12 +0200 Subject: [svn] dirmngr - r318 - trunk/src Message-ID: Author: wk Date: 2009-07-20 18:37:12 +0200 (Mon, 20 Jul 2009) New Revision: 318 Modified: trunk/src/ChangeLog trunk/src/ldap.c Log: Possible fix for bug#999. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-06-17 14:57:14 UTC (rev 317) +++ trunk/src/ChangeLog 2009-07-20 16:37:12 UTC (rev 318) @@ -1,3 +1,9 @@ +2009-07-20 Werner Koch + + * ldap.c (ldap_wrapper_thread): Print ldap worker stati. + (ldap_wrapper_release_context): Print a debug info. + (end_cert_fetch_ldap): Release the reader. Might fix bug#999. + 2009-06-17 Werner Koch * util.h: Remove unused dotlock.h. Modified: trunk/src/ldap.c =================================================================== --- trunk/src/ldap.c 2009-06-17 14:57:14 UTC (rev 317) +++ trunk/src/ldap.c 2009-07-20 16:37:12 UTC (rev 318) @@ -262,6 +262,7 @@ for (;;) { pth_event_t timeout_ev; + int any_action = 0; timeout_ev = pth_event (PTH_EVENT_TIME, pth_timeout (1, 0)); if (! timeout_ev) @@ -318,6 +319,7 @@ print_log_line (ctx, NULL); log_error (_("error reading log from ldap wrapper %d: %s\n"), ctx->pid, strerror (errno)); + any_action = 1; } else if (!n) /* EOF */ { @@ -326,6 +328,7 @@ ctx->log_fd = -1; pth_event_free (ctx->log_ev, PTH_FREE_THIS); ctx->log_ev = NULL; + any_action = 1; } else { @@ -351,11 +354,13 @@ ctx->ready = 1; dirmngr_release_process (ctx->pid); ctx->pid = (pid_t)(-1); + any_action = 1; } else if (gpg_err_code (err) != GPG_ERR_TIMEOUT) { log_error (_("waiting for ldap wrapper %d failed: %s\n"), (int)ctx->pid, gpg_strerror (err)); + any_action = 1; } } @@ -367,9 +372,26 @@ ctx->stamp = (time_t)(-1); log_info (_("ldap wrapper %d stalled - killing\n"), (int)ctx->pid); + any_action = 1; } } + /* If something has been printed to the log file or we got an + EOF from a wrapper, we now print the list of active + wrappers. */ + if (any_action && DBG_LOOKUP) + { + log_info ("ldap worker stati:\n"); + for (ctx = wrapper_list; ctx; ctx = ctx->next) + log_info (" c=%p pid=%d/%d rdr=%p ctrl=%p/%d la=%lu rdy=%d\n", + ctx, + (int)ctx->pid, (int)ctx->printable_pid, + ctx->reader, + ctx->ctrl, ctx->ctrl? ctx->ctrl->refcount:0, + (unsigned long)ctx->stamp, ctx->ready); + } + + /* 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 or we are in shutdown state. */ @@ -417,6 +439,13 @@ for (ctx=wrapper_list; ctx; ctx=ctx->next) if (ctx->reader == reader) { + if (DBG_LOOKUP) + log_info ("releasing ldap worker c=%p pid=%d/%d rdr=%p ctrl=%p/%d\n", + ctx, + (int)ctx->pid, (int)ctx->printable_pid, + ctx->reader, + ctx->ctrl, ctx->ctrl? ctx->ctrl->refcount:0); + ctx->reader = NULL; if (ctx->fd != -1) { @@ -589,8 +618,8 @@ 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 this best done using a + wrapper module to do the logging on its own. Given that we anyway + need a way to rip the child process and this is best done using a general ripping thread, that thread can do the logging too. */ *reader = NULL; @@ -1420,7 +1449,11 @@ { if (context) { + ksba_reader_t reader = context->reader; + xfree (context->tmpbuf); xfree (context); + ldap_wrapper_release_context (reader); + ksba_reader_release (reader); } } From cvs at cvs.gnupg.org Mon Jul 20 21:06:45 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 20 Jul 2009 21:06:45 +0200 Subject: [svn] dirmngr - r319 - in trunk: . jnlib src Message-ID: Author: wk Date: 2009-07-20 21:06:44 +0200 (Mon, 20 Jul 2009) New Revision: 319 Modified: trunk/ChangeLog trunk/configure.ac trunk/jnlib/ChangeLog trunk/jnlib/logging.c trunk/jnlib/logging.h trunk/src/ChangeLog trunk/src/dirmngr.c Log: Put the connection's fd into all log lines. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-07-20 16:37:12 UTC (rev 318) +++ trunk/ChangeLog 2009-07-20 19:06:44 UTC (rev 319) @@ -1,3 +1,7 @@ +2009-06-18 Werner Koch + + * configure.ac: Fix some URL hints. + 2009-06-17 Werner Koch Released 1.0.3. Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2009-07-20 16:37:12 UTC (rev 318) +++ trunk/jnlib/ChangeLog 2009-07-20 19:06:44 UTC (rev 319) @@ -1,3 +1,9 @@ +2009-07-20 Werner Koch + + * logging.c (pid_suffix_cb): New. + (log_set_pid_suffix_cb): New. + (do_logv): Use it. + 2009-06-17 Werner Koch * Makefile.am (libjnlib_a_SOURCES): Remove unused dotlock module. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-07-20 16:37:12 UTC (rev 318) +++ trunk/src/ChangeLog 2009-07-20 19:06:44 UTC (rev 319) @@ -1,5 +1,9 @@ 2009-07-20 Werner Koch + * dirmngr.c (pid_suffix_callback): New. + (main): Use log_set_pid_suffix_cb. + (start_connection_thread): Put the fd into the tls. + * ldap.c (ldap_wrapper_thread): Print ldap worker stati. (ldap_wrapper_release_context): Print a debug info. (end_cert_fetch_ldap): Release the reader. Might fix bug#999. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-07-20 16:37:12 UTC (rev 318) +++ trunk/configure.ac 2009-07-20 19:06:44 UTC (rev 319) @@ -402,7 +402,7 @@ *** *** You need libgpg-error to build this program. ** This library is for example available at -*** ftp://ftp.gnupg.org/pub/gcrypt/libgpg-error +*** ftp://ftp.gnupg.org/gcrypt/libgpg-error *** (at least version $NEED_GPG_ERROR_VERSION is required.) ***]]) fi @@ -412,7 +412,7 @@ *** *** You need libgcrypt to build this program. ** This library is for example available at -*** ftp://ftp.gnupg.org/pub/gcrypt/libgcrypt/ +*** ftp://ftp.gnupg.org/gcrypt/libgcrypt/ *** (at least version $NEED_LIBGCRYPT_VERSION using API $NEED_LIBGCRYPT_API is required.) ***]]) fi @@ -422,7 +422,7 @@ *** *** You need libassuan to build this program. *** This library is for example available at -*** ftp://ftp.gnupg.org/pub/gcrypt/libassuan/ +*** ftp://ftp.gnupg.org/gcrypt/libassuan/ *** (at least version $NEED_LIBASSUAN_VERSION is required). *** Note, that libassuan must have been build with Pth support. ***]]) @@ -433,7 +433,7 @@ *** *** You need libksba to build this program. *** This library is for example available at -*** ftp://ftp.gnupg.org/pub/gcrypt/libksba/ +*** ftp://ftp.gnupg.org/gcrypt/libksba/ *** (at least version $NEED_KSBA_VERSION using API $NEED_KSBA_API is required.) ***]]) fi Modified: trunk/jnlib/logging.c =================================================================== --- trunk/jnlib/logging.c 2009-07-20 16:37:12 UTC (rev 318) +++ trunk/jnlib/logging.c 2009-07-20 19:06:44 UTC (rev 319) @@ -61,6 +61,7 @@ static int with_time; static int with_prefix; static int with_pid; +static int (*pid_suffix_cb)(int*); static int running_detached; static int force_prefixes; @@ -84,7 +85,7 @@ } -/* The follwing 3 functions are used by funopen to write logs to a +/* The following 3 functions are used by funopen to write logs to a socket. */ #ifdef USE_FUNWRITER struct fun_cookie_s { @@ -364,6 +365,11 @@ set_file_fd (NULL, fd); } +void +log_set_pid_suffix_cb (int (*fnc)(int *pidsuf)) +{ + pid_suffix_cb = fnc; +} void log_set_prefix (const char *text, unsigned int flags) @@ -460,7 +466,15 @@ if (with_prefix || force_prefixes) fputs (prefix_buffer, logstream); if (with_pid || force_prefixes) - fprintf (logstream, "[%u]", (unsigned int)getpid ()); + { + unsigned int apid = (unsigned int)getpid (); + int pidsuf; + + if (pid_suffix_cb && pid_suffix_cb (&pidsuf)) + fprintf (logstream, "[%u.%d]", apid, pidsuf); + else + fprintf (logstream, "[%u]", apid); + } if (!with_time || force_prefixes) putc (':', logstream); /* A leading backspace suppresses the extra space so that we can Modified: trunk/jnlib/logging.h =================================================================== --- trunk/jnlib/logging.h 2009-07-20 16:37:12 UTC (rev 318) +++ trunk/jnlib/logging.h 2009-07-20 19:06:44 UTC (rev 319) @@ -35,6 +35,7 @@ void log_inc_errorcount (void); void log_set_file( const char *name ); void log_set_fd (int fd); +void log_set_pid_suffix_cb (int (*fnc)(int *pidsuf)); void log_set_prefix (const char *text, unsigned int flags); const char *log_get_prefix (unsigned int *flags); int log_test_fd (int fd); Modified: trunk/src/dirmngr.c =================================================================== --- trunk/src/dirmngr.c 2009-07-20 16:37:12 UTC (rev 318) +++ trunk/src/dirmngr.c 2009-07-20 19:06:44 UTC (rev 319) @@ -239,6 +239,13 @@ #endif +/* The key used to store the current file descriptor in the thread + local storage. We use this in conjunction with the + log_set_pid_suffix_cb feature.. */ +#ifndef HAVE_W32_SYSTEM +static int my_tlskey_current_fd; +#endif + /* Prototypes. */ static void cleanup (void); static ldap_server_t parse_ldapserver_file (const char* filename); @@ -547,7 +554,16 @@ } #endif /*HAVE_W32_SYSTEM*/ +#ifndef HAVE_W32_SYSTEM +static int +pid_suffix_callback (int *r_suffix) +{ + *r_suffix = (int)pth_key_getdata (my_tlskey_current_fd); + return (*r_suffix != -1); +} +#endif /*!HAVE_W32_SYSTEM*/ + #ifdef HAVE_W32_SYSTEM #define main real_main #endif @@ -602,7 +618,7 @@ set_strusage (my_strusage); log_set_prefix ("dirmngr", 1|4); - + /* Check that the libraries are suitable. Do it here because the option parsing may need services of the libraries. */ @@ -650,9 +666,18 @@ shell = getenv ("SHELL"); if (shell && strlen (shell) >= 3 && !strcmp (shell+strlen (shell)-3, "csh") ) csh_style = 1; - + opt.homedir = default_homedir (); + /* Now with Pth running we can set the logging callback. Our + windows implementation does not yet feature the PTh tls + functions. */ +#ifndef HAVE_W32_SYSTEM + if (pth_key_create (&my_tlskey_current_fd, NULL)) + if (pth_key_setdata (my_tlskey_current_fd, NULL)) + log_set_pid_suffix_cb (pid_suffix_callback); +#endif /*!HAVE_W32_SYSTEM*/ + /* Reset rereadable options to default values. */ parse_rereadable_options (NULL, 0); @@ -1663,6 +1688,10 @@ if (check_nonce (fd, &socket_nonce)) return NULL; +#ifndef HAVE_W32_SYSTEM + pth_key_setdata (my_tlskey_current_fd, (void*)FD2INT (fd)); +#endif + active_connections++; if (opt.verbose) log_info (_("handler for fd %d started\n"), FD2INT (fd)); @@ -1672,6 +1701,10 @@ if (opt.verbose) log_info (_("handler for fd %d terminated\n"), FD2INT (fd)); active_connections--; + +#ifndef HAVE_W32_SYSTEM + pth_key_setdata (my_tlskey_current_fd, (void*)(-1)); +#endif return NULL; } From cvs at cvs.gnupg.org Tue Jul 21 13:21:41 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 21 Jul 2009 13:21:41 +0200 Subject: [svn] GpgOL - r302 - in trunk: . src Message-ID: Author: wk Date: 2009-07-21 13:21:40 +0200 (Tue, 21 Jul 2009) New Revision: 302 Modified: trunk/NEWS trunk/src/ChangeLog trunk/src/engine-assuan.c trunk/src/engine-assuan.h trunk/src/engine.c trunk/src/engine.h trunk/src/mimemaker.c Log: Help UI servers to present a unified sign/encrypt dialog. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-06-19 23:03:39 UTC (rev 301) +++ trunk/src/ChangeLog 2009-07-21 11:21:40 UTC (rev 302) @@ -1,3 +1,11 @@ +2009-07-21 Werner Koch + + * engine.h (ENGINE_FLAG_SIGN_FOLLOWS): New macro. + * engine.c (engine_encrypt_prepare): Add arg flags. Change callers. + * engine-assuan.c (op_assuan_encrypt): Ditto. send PREP_ENCRYPT + if the sign-follows flag is used. + * mimemaker.c (mime_sign_encrypt): Pass new flag. + 2009-06-18 Werner Koch * common.h (struct opt): Add ANNOUNCE_NUMBER. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-06-19 23:03:39 UTC (rev 301) +++ trunk/NEWS 2009-07-21 11:21:40 UTC (rev 302) @@ -1,7 +1,7 @@ Noteworthy changes for version 1.0.0 (2009-06-18) ================================================= - * Show a notice about portential problems. + * Show a notice about potential problems. * After about 2 years of development, the 1.0 version is now due. Modified: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c 2009-06-19 23:03:39 UTC (rev 301) +++ trunk/src/engine-assuan.c 2009-07-21 11:21:40 UTC (rev 302) @@ -1570,6 +1570,7 @@ op_assuan_encrypt (protocol_t protocol, gpgme_data_t indata, gpgme_data_t outdata, engine_filter_t filter, void *hwnd, + unsigned int flags, const char *sender, char **recipients, protocol_t *r_used_protocol, struct engine_assuan_encstate_s **r_encstate) @@ -1634,11 +1635,16 @@ } /* If the protocol has not been given, let the UI server tell us the - protocol to use. */ + protocol to use. If we know that we will also sign the message, + send the prep_encrypt anyway to tell the server about a + forthcoming sign command. */ if (detect_protocol) { protocol = PROTOCOL_UNKNOWN; - err = assuan_transact (ctx, "PREP_ENCRYPT", NULL, NULL, NULL, NULL, + err = assuan_transact (ctx, + (flags & ENGINE_FLAG_SIGN_FOLLOWS) + ? "PREP_ENCRYPT --expect-sign": "PREP_ENCRYPT", + NULL, NULL, NULL, NULL, prep_foo_status_cb, &protocol); if (err) { @@ -1652,7 +1658,25 @@ goto leave; } } + else if ((flags & ENGINE_FLAG_SIGN_FOLLOWS)) + { + if ( !protocol_name ) + { + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + snprintf (line, sizeof line, "PREP_ENCRYPT --protocol=%s --expect-sign", + protocol_name); + err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_ASS_UNKNOWN_CMD) + err = gpg_error (GPG_ERR_INV_VALUE); + goto leave; + } + } + *r_used_protocol = protocol; /* Note: We don't use real descriptor passing but a hack: We Modified: trunk/src/engine-assuan.h =================================================================== --- trunk/src/engine-assuan.h 2009-06-19 23:03:39 UTC (rev 301) +++ trunk/src/engine-assuan.h 2009-07-21 11:21:40 UTC (rev 302) @@ -40,6 +40,7 @@ int op_assuan_encrypt (protocol_t protocol, gpgme_data_t indata, gpgme_data_t outdata, engine_filter_t notify_data, void *hwnd, + unsigned int flags, const char *sender, char **recipients, protocol_t *r_used_protocol, struct engine_assuan_encstate_s **r_encstate); Modified: trunk/src/engine.c =================================================================== --- trunk/src/engine.c 2009-06-19 23:03:39 UTC (rev 301) +++ trunk/src/engine.c 2009-07-21 11:21:40 UTC (rev 302) @@ -837,12 +837,18 @@ latter command has just one argument CANCEL which can be set to true to cancel the prepared command. + FLAGS modifies the operation. Valid flags are: + + ENGINE_FLAG_SIGN_FOLLOWS + Expect that we are part of a sign+encrypt operaion. This + allows the UI-server to presetn a better dialog. + SENDER is the sender's mailbox or NULL; this information may be used by the UI-server for role selection. */ int engine_encrypt_prepare (engine_filter_t filter, HWND hwnd, - protocol_t req_protocol, + protocol_t req_protocol, unsigned int flags, const char *sender, char **recipients, protocol_t *r_protocol) { @@ -853,7 +859,7 @@ if (filter->use_assuan) { err = op_assuan_encrypt (req_protocol, filter->indata, filter->outdata, - filter, hwnd, sender, recipients, + filter, hwnd, flags, sender, recipients, &used_protocol, &filter->encstate); if (!err) *r_protocol = used_protocol; Modified: trunk/src/engine.h =================================================================== --- trunk/src/engine.h 2009-06-19 23:03:39 UTC (rev 301) +++ trunk/src/engine.h 2009-07-21 11:21:40 UTC (rev 302) @@ -44,6 +44,8 @@ struct engine_filter_s; typedef struct engine_filter_s *engine_filter_t; +/* Flag values used by the engine functions. */ +#define ENGINE_FLAG_SIGN_FOLLOWS 1 /* Expect a sign+encrypt operation. */ @@ -72,7 +74,7 @@ void engine_cancel (engine_filter_t filter); int engine_encrypt_prepare (engine_filter_t filter, HWND hwnd, - protocol_t req_protocol, + protocol_t req_protocol, unsigned int flags, const char *sender, char **recipients, protocol_t *r_protocol); int engine_encrypt_start (engine_filter_t filter, int cancel); Modified: trunk/src/mimemaker.c =================================================================== --- trunk/src/mimemaker.c 2009-06-19 23:03:39 UTC (rev 301) +++ trunk/src/mimemaker.c 2009-07-21 11:21:40 UTC (rev 302) @@ -1648,7 +1648,7 @@ } sender = mapi_get_sender (message); - if (engine_encrypt_prepare (filter, hwnd, protocol, + if (engine_encrypt_prepare (filter, hwnd, protocol, 0, sender, recipients, &protocol)) goto failure; if (engine_encrypt_start (filter, 0)) @@ -1829,7 +1829,8 @@ sender = mapi_get_sender (message); if ((rc=engine_encrypt_prepare (filter, hwnd, - protocol, sender, recipients, &protocol))) + protocol, ENGINE_FLAG_SIGN_FOLLOWS, + sender, recipients, &protocol))) goto failure; protocol = check_protocol (protocol); From cvs at cvs.gnupg.org Tue Jul 21 16:21:05 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 21 Jul 2009 16:21:05 +0200 Subject: [svn] GnuPG - r5084 - in trunk: . agent g10 kbx scd sm tools Message-ID: Author: wk Date: 2009-07-21 16:21:05 +0200 (Tue, 21 Jul 2009) New Revision: 5084 Modified: trunk/AUTHORS trunk/THANKS trunk/agent/gpg-agent.c trunk/agent/preset-passphrase.c trunk/agent/protect-tool.c trunk/configure.ac trunk/g10/gpg.c trunk/g10/gpgv.c trunk/kbx/kbxutil.c trunk/scd/ChangeLog trunk/scd/apdu.c trunk/scd/ccid-driver.c trunk/scd/sc-copykeys.c trunk/scd/scdaemon.c trunk/sm/gpgsm.c trunk/tools/gpg-check-pattern.c trunk/tools/gpg-connect-agent.c trunk/tools/gpgconf.c trunk/tools/gpgsplit.c trunk/tools/symcryptrun.c Log: Make bug reporting address easier changeable. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/scd/ChangeLog 2009-07-21 14:21:05 UTC (rev 5084) @@ -1,3 +1,13 @@ +2009-07-21 Werner Koch + + * ccid-driver.c [HAVE_PTH]: Include pth.h. + (my_sleep): New. + (bulk_in): s/gnupg_sleep/my_sleep/. + +2009-07-20 Werner Koch + + * apdu.c [GNUPG_MAJOR_VERSION==1]: Include dynload.h. + 2009-07-16 Werner Koch * command.c (update_reader_status_file): Test for unplugged reader. Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/AUTHORS 2009-07-21 14:21:05 UTC (rev 5084) @@ -1,7 +1,7 @@ Program: GnuPG Homepage: http://www.gnupg.org Maintainer: Werner Koch -Bug reports: +Bug reports: http://bugs.gnupg.org Security related bug reports: License: GPLv3+ Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/THANKS 2009-07-21 14:21:05 UTC (rev 5084) @@ -118,6 +118,7 @@ Jens Bachem bachem at rrz.uni-koeln.de Jens Seidel jensseidel at users.sf.net Jeroen C. van Gelderen jeroen at vangelderen.org +Jeroen Schot schot at a-eskwadraat nl J Horacio MG homega at ciberia.es J. Michael Ashley jashley at acm.org Jim Bauer jfbauer at home.com Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/agent/gpg-agent.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -326,8 +326,11 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; + /* TRANSLATORS: @EMAIL@ will get replaced by the actual bug + reporting address. This is so that we can change the + reporting address without breaking the translations. */ + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 20: if (!ver_gcry) ver_gcry = make_libversion ("libgcrypt", gcry_check_version); Modified: trunk/agent/preset-passphrase.c =================================================================== --- trunk/agent/preset-passphrase.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/agent/preset-passphrase.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -91,8 +91,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 1: case 40: p = _("Usage: gpg-preset-passphrase [options] KEYGRIP (-h for help)\n"); Modified: trunk/agent/protect-tool.c =================================================================== --- trunk/agent/protect-tool.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/agent/protect-tool.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -157,8 +157,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 1: case 40: p = _("Usage: gpg-protect-tool [options] (-h for help)\n"); break; Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/configure.ac 2009-07-21 14:21:05 UTC (rev 5084) @@ -31,7 +31,7 @@ | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) AC_INIT([gnupg], [my_version[]m4_if(my_issvn,[yes],[-svn[]svn_revision])], - [bug-gnupg at gnupg.org]) + [http://bugs.gnupg.org]) # Set development_version to yes if the minor number is odd or you # feel that the default check for a development version is not # sufficient. Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/g10/gpg.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -804,9 +804,7 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = - _("Please report bugs to .\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; case 20: if (!ver_gcry) Modified: trunk/g10/gpgv.c =================================================================== --- trunk/g10/gpgv.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/g10/gpgv.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -111,8 +111,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to .\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 1: case 40: p = _("Usage: gpgv [options] [files] (-h for help)"); break; Modified: trunk/kbx/kbxutil.c =================================================================== --- trunk/kbx/kbxutil.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/kbx/kbxutil.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -110,9 +110,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = - _("Please report bugs to " PACKAGE_BUGREPORT ".\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 1: case 40: p = _("Usage: kbxutil [options] [files] (-h for help)"); Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/scd/apdu.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -54,6 +54,7 @@ #include "memory.h" #include "util.h" #include "i18n.h" +#include "dynload.h" #include "cardglue.h" #else /* GNUPG_MAJOR_VERSION != 1 */ #include "scdaemon.h" Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/scd/ccid-driver.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -85,6 +85,9 @@ #include #include #include +#ifdef HAVE_PTH +# include +#endif /*HAVE_PTH*/ #include @@ -312,6 +315,30 @@ static void +my_sleep (int seconds) +{ +#ifdef HAVE_PTH + /* With Pth we also call the standard sleep(0) so that the process + may give up its timeslot. */ + if (!seconds) + { +# ifdef HAVE_W32_SYSTEM + Sleep (0); +# else + sleep (0); +# endif + } + pth_sleep (seconds); +#else +# ifdef HAVE_W32_SYSTEM + Sleep (seconds*1000); +# else + sleep (seconds); +# endif +#endif +} + +static void print_progress (ccid_driver_t handle) { time_t ct = time (NULL); @@ -1766,8 +1793,8 @@ { int rc; - /* No need to continue and clutter the log withy USB error if we - ever got an ENODEV. */ + /* No need to continue and clutter the log with USB write error + messages after we got the first ENODEV. */ if (handle->enodev_seen) return CCID_DRIVER_ERR_NO_READER; @@ -1900,9 +1927,7 @@ DEBUGOUT_1 ("usb_bulk_read error: %s\n", strerror (rc)); if (rc == EAGAIN && eagain_retries++ < 3) { -#ifndef TEST - gnupg_sleep (1); -#endif + my_sleep (1); goto retry; } return CCID_DRIVER_ERR_CARD_IO_ERROR; @@ -1919,9 +1944,7 @@ handle->dev_fd, strerror (rc)); if (rc == EAGAIN && eagain_retries++ < 5) { -#ifndef TEST - gnupg_sleep (1); -#endif + my_sleep (1); goto retry; } return CCID_DRIVER_ERR_CARD_IO_ERROR; Modified: trunk/scd/sc-copykeys.c =================================================================== --- trunk/scd/sc-copykeys.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/scd/sc-copykeys.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -76,8 +76,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 1: case 40: p = _("Usage: sc-copykeys [options] (-h for help)\n"); break; Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/scd/scdaemon.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -242,8 +242,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 20: if (!ver_gcry) ver_gcry = make_libversion ("libgcrypt", gcry_check_version); Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/sm/gpgsm.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -509,8 +509,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 1: case 40: p = _("Usage: gpgsm [options] [files] (-h for help)"); break; Modified: trunk/tools/gpg-check-pattern.c =================================================================== --- trunk/tools/gpg-check-pattern.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/tools/gpg-check-pattern.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -138,8 +138,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 1: case 40: p = _("Usage: gpg-check-pattern [options] patternfile (-h for help)\n"); Modified: trunk/tools/gpg-connect-agent.c =================================================================== --- trunk/tools/gpg-connect-agent.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/tools/gpg-connect-agent.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -177,8 +177,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 1: case 40: p = _("Usage: gpg-connect-agent [options] (-h for help)"); break; Modified: trunk/tools/gpgconf.c =================================================================== --- trunk/tools/gpgconf.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/tools/gpgconf.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -99,8 +99,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 1: case 40: p = _("Usage: gpgconf [options] (-h for help)"); break; Modified: trunk/tools/gpgsplit.c =================================================================== --- trunk/tools/gpgsplit.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/tools/gpgsplit.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -85,9 +85,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = - "Please report bugs to .\n"; - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 1: case 40: p = "Usage: gpgsplit [options] [files] (-h for help)"; Modified: trunk/tools/symcryptrun.c =================================================================== --- trunk/tools/symcryptrun.c 2009-07-20 11:02:20 UTC (rev 5083) +++ trunk/tools/symcryptrun.c 2009-07-21 14:21:05 UTC (rev 5084) @@ -201,8 +201,8 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <" PACKAGE_BUGREPORT ">.\n"); - break; + case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 1: case 40: p = _("Usage: symcryptrun [options] (-h for help)"); break; From cvs at cvs.gnupg.org Tue Jul 21 16:30:14 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 21 Jul 2009 16:30:14 +0200 Subject: [svn] GnuPG - r5085 - in branches/STABLE-BRANCH-1-4: . g10 include m4 util Message-ID: Author: wk Date: 2009-07-21 16:30:13 +0200 (Tue, 21 Jul 2009) New Revision: 5085 Added: branches/STABLE-BRANCH-1-4/include/estream-printf.h branches/STABLE-BRANCH-1-4/m4/estream.m4 branches/STABLE-BRANCH-1-4/util/convert.c branches/STABLE-BRANCH-1-4/util/estream-printf.c Modified: branches/STABLE-BRANCH-1-4/AUTHORS branches/STABLE-BRANCH-1-4/ChangeLog branches/STABLE-BRANCH-1-4/NEWS branches/STABLE-BRANCH-1-4/configure.ac branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/apdu.c branches/STABLE-BRANCH-1-4/g10/apdu.h branches/STABLE-BRANCH-1-4/g10/app-common.h branches/STABLE-BRANCH-1-4/g10/app-openpgp.c branches/STABLE-BRANCH-1-4/g10/card-util.c branches/STABLE-BRANCH-1-4/g10/cardglue.c branches/STABLE-BRANCH-1-4/g10/cardglue.h branches/STABLE-BRANCH-1-4/g10/ccid-driver.c branches/STABLE-BRANCH-1-4/g10/ccid-driver.h branches/STABLE-BRANCH-1-4/g10/gpg.c branches/STABLE-BRANCH-1-4/g10/iso7816.c branches/STABLE-BRANCH-1-4/g10/iso7816.h branches/STABLE-BRANCH-1-4/g10/keyedit.c branches/STABLE-BRANCH-1-4/g10/keygen.c branches/STABLE-BRANCH-1-4/g10/main.h branches/STABLE-BRANCH-1-4/g10/options.h branches/STABLE-BRANCH-1-4/include/ChangeLog branches/STABLE-BRANCH-1-4/include/distfiles branches/STABLE-BRANCH-1-4/include/memory.h branches/STABLE-BRANCH-1-4/include/types.h branches/STABLE-BRANCH-1-4/include/util.h branches/STABLE-BRANCH-1-4/m4/ChangeLog branches/STABLE-BRANCH-1-4/m4/Makefile.am branches/STABLE-BRANCH-1-4/util/ChangeLog branches/STABLE-BRANCH-1-4/util/Makefile.am branches/STABLE-BRANCH-1-4/util/memory.c branches/STABLE-BRANCH-1-4/util/strgutil.c branches/STABLE-BRANCH-1-4/util/ttyio.c Log: First set of changes to backport the new card code from 2.0. For compatibility reasons a few new files had to be added. Also added estream-printf as this is now used in app-openpgp.c and provides a better and generic asprintf implementation than the hack we used for the W32 code in ttyio.c. Card code is not yet finished. [The diff below has been truncated] Modified: branches/STABLE-BRANCH-1-4/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/ChangeLog 2009-07-21 14:21:05 UTC (rev 5084) +++ branches/STABLE-BRANCH-1-4/ChangeLog 2009-07-21 14:30:13 UTC (rev 5085) @@ -1,3 +1,8 @@ +2009-07-21 Werner Koch + + * configure.ac (AH_BOTTOM): Add macros for estream-printf. + (estream_PRINTF_INIT): Add it. + 2009-06-05 David Shaw * configure.ac: Remove Camellia restriction. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-21 14:21:05 UTC (rev 5084) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-21 14:30:13 UTC (rev 5085) @@ -1,3 +1,31 @@ +2009-07-21 Werner Koch + + * app-common.h, app-openpgp.c, iso7816.c, iso7816.h, apdu.c, + * apdu.h, ccid-driver.c, ccid-driver.h, card-util.c: Update from + GnuPG 2.0 SVN revision 5084. + + * cardglue.h (GCRY_MD_SHA256): Add more GCRY_MD constants. + (gcry_handler_progress_t): Add definition. + (struct agent_card_info_s): Add fields apptype, is_v2, key_attr. + * cardglue.c (learn_status_cb): Set them. + (agent_release_card_info): Release APPTYPE. + (unescape_status_string, send_status_direct): New. + (gcry_mpi_release, gcry_mpi_set_opaque): New. + (gcry_md_algo_name): New. + (open_card): s/initialized/ref_count/. + (agent_learn): Pass new new flag arg to learn_status. + (agent_scd_genkey): Add new arg createtime. + * keygen.c (gen_card_key, gen_card_key_with_backup): Add new arg + TIMESTAMP. + (write_direct_sig, write_selfsigs, write_keybinding) + (make_backsig): Ditto. + (do_generate_keypair): Pass timestamp to all signing functions. + (generate_card_subkeypair): Ditto. + * keyedit.c (menu_backsign): Pass a new timestamp to all backsisg. + + * gpg.c (main): Disable keypad support. + * options.h (struct): Add field disable_keypad. + 2009-07-17 Werner Koch * keyring.c (keyring_rebuild_cache): Replace the assert by a Modified: branches/STABLE-BRANCH-1-4/include/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/include/ChangeLog 2009-07-21 14:21:05 UTC (rev 5084) +++ branches/STABLE-BRANCH-1-4/include/ChangeLog 2009-07-21 14:30:13 UTC (rev 5085) @@ -1,3 +1,15 @@ +2009-07-21 Werner Koch + + * estream-printf.h: New. Taken from libestream.x + +2009-07-20 Werner Koch + + * types.h (strlist_t): Add new alias for STRLIST. + + * memory.h (xtrymalloc,xtrystrdup): New. + + * util.h: Add prototypes for util/convert.c. + 2009-05-26 David Shaw * http.h: Pass in a STRLIST for additional headers on http_open Modified: branches/STABLE-BRANCH-1-4/m4/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/m4/ChangeLog 2009-07-21 14:21:05 UTC (rev 5084) +++ branches/STABLE-BRANCH-1-4/m4/ChangeLog 2009-07-21 14:30:13 UTC (rev 5085) @@ -1,3 +1,7 @@ +2009-07-21 Werner Koch + + * estream.m4: New. Taken from libestream. + 2007-12-17 Werner Koch * ldap.m4: Test for ldap_start_tls_sA. Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-07-21 14:21:05 UTC (rev 5084) +++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-07-21 14:30:13 UTC (rev 5085) @@ -1,3 +1,20 @@ +2009-07-21 Werner Koch + + * ttyio.c (tty_printf): Replace vasprintf by xtryasprintf. + (tty_fprintf): Ditto. + + * strgutil.c: Include estream-printf.h. + (xasprintf, xtryasprintf): New. + (vasprintf, asprintf): Remove. + + * estream-printf.c: New. Taken from libestream. + * Makefile.am (libutil_a_SOURCES): Add it. + + * memory.c (trymalloc,trystrdup): New. + + * convert.c: New. Taken from GnuPG 2.0 SVN. + * Makefile.am (libutil_a_SOURCES): Add it. + 2009-05-26 David Shaw * http.c (send_request): Pass in a STRLIST for additional headers. Modified: branches/STABLE-BRANCH-1-4/AUTHORS =================================================================== --- branches/STABLE-BRANCH-1-4/AUTHORS 2009-07-21 14:21:05 UTC (rev 5084) +++ branches/STABLE-BRANCH-1-4/AUTHORS 2009-07-21 14:30:13 UTC (rev 5085) @@ -1,6 +1,6 @@ Program: GnuPG Maintainer: Werner Koch -Bug reports: +Bug reports: http://bugs.gnupg.org Security related bug reports: License: GPLv3+ Modified: branches/STABLE-BRANCH-1-4/NEWS =================================================================== --- branches/STABLE-BRANCH-1-4/NEWS 2009-07-21 14:21:05 UTC (rev 5084) +++ branches/STABLE-BRANCH-1-4/NEWS 2009-07-21 14:30:13 UTC (rev 5085) @@ -8,7 +8,11 @@ * Fixed a memory leak which made imports of many keys very slow. + * Support v2 OpenPGP cards. + * FIXME: Anything else? + + Noteworthy changes in version 1.4.9 (2008-03-26) ------------------------------------------------ Modified: branches/STABLE-BRANCH-1-4/configure.ac =================================================================== --- branches/STABLE-BRANCH-1-4/configure.ac 2009-07-21 14:21:05 UTC (rev 5084) +++ branches/STABLE-BRANCH-1-4/configure.ac 2009-07-21 14:30:13 UTC (rev 5085) @@ -499,6 +499,11 @@ #define SAFE_VERSION_DOT '.' #define SAFE_VERSION_DASH '-' +/* We want to use our memory allocator for estream-printf. */ +#define _ESTREAM_PRINTF_MALLOC xtrymalloc +#define _ESTREAM_PRINTF_FREE xfree +#define _ESTREAM_PRINTF_EXTRA_INCLUDE "memory.h" + #endif /*GNUPG_CONFIG_H_INCLUDED*/ ]) @@ -1049,6 +1054,12 @@ GNUPG_CHECK_MLOCK GNUPG_FUNC_MKDIR_TAKES_ONE_ARG +# +# Prepare building of estream-printf +# +estream_PRINTF_INIT + + dnl dnl Check whether we can use Linux capabilities as requested dnl Modified: branches/STABLE-BRANCH-1-4/g10/apdu.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/apdu.c 2009-07-21 14:21:05 UTC (rev 5084) +++ branches/STABLE-BRANCH-1-4/g10/apdu.c 2009-07-21 14:30:13 UTC (rev 5085) @@ -1,5 +1,5 @@ /* apdu.c - ISO 7816 APDU functions and low level I/O - * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * Copyright (C) 2003, 2004, 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -31,9 +31,9 @@ #include #include #ifdef USE_GNU_PTH -# include # include # include +# include #endif @@ -54,13 +54,14 @@ #include "memory.h" #include "util.h" #include "i18n.h" +#include "dynload.h" #include "cardglue.h" #else /* GNUPG_MAJOR_VERSION != 1 */ #include "scdaemon.h" +#include "exechelp.h" #endif /* GNUPG_MAJOR_VERSION != 1 */ #include "apdu.h" -#include "dynload.h" #include "ccid-driver.h" @@ -82,13 +83,8 @@ #define DLSTDCALL #endif -#ifdef _POSIX_OPEN_MAX -#define MAX_OPEN_FDS _POSIX_OPEN_MAX -#else -#define MAX_OPEN_FDS 20 -#endif -/* Helper to pass patrameters related to keypad based operations. */ +/* Helper to pass parameters related to keypad based operations. */ struct pininfo_s { int mode; @@ -104,6 +100,8 @@ unsigned short port; /* Port number: 0 = unused, 1 - dev/tty */ /* Function pointers intialized to the various backends. */ + int (*connect_card)(int); + int (*disconnect_card)(int); int (*close_reader)(int); int (*shutdown_reader)(int); int (*reset_reader)(int); @@ -112,6 +110,7 @@ unsigned char *, size_t *, struct pininfo_s *); int (*check_keypad)(int, int, int, int, int, int); void (*dump_status_reader)(int); + int (*set_progress_cb)(int, gcry_handler_progress_t, void*); struct { ccid_driver_t handle; @@ -132,6 +131,7 @@ } rapdu; #endif /*USE_G10CODE_RAPDU*/ char *rdrname; /* Name of the connected reader or NULL if unknown. */ + int any_status; /* True if we have seen any status. */ int last_status; int status; int is_t0; /* True if we know that we are running T=0. */ @@ -220,7 +220,12 @@ #define PCSC_E_READER_UNAVAILABLE 0x80100017 #define PCSC_W_REMOVED_CARD 0x80100069 +/* The PC/SC error is defined as a long as per specs. Due to left + shifts bit 31 will get sign extended. We use this mask to fix + it. */ +#define PCSC_ERR_MASK(a) ((a) & 0xffffffff) + struct pcsc_io_request_s { unsigned long protocol; @@ -272,7 +277,8 @@ unsigned long *r_protocol, unsigned char *atr, unsigned long *atrlen); long (* DLSTDCALL pcsc_begin_transaction) (unsigned long card); -long (* DLSTDCALL pcsc_end_transaction) (unsigned long card); +long (* DLSTDCALL pcsc_end_transaction) (unsigned long card, + unsigned long disposition); long (* DLSTDCALL pcsc_transmit) (unsigned long card, const pcsc_io_request_t send_pci, const unsigned char *send_buffer, @@ -286,6 +292,10 @@ /* Prototypes. */ static int pcsc_get_status (int slot, unsigned int *status); +static int reset_pcsc_reader (int slot); +static int apdu_get_status_internal (int slot, int hang, int no_atr_reset, + unsigned int *status, + unsigned int *changed); @@ -322,6 +332,8 @@ reader_table[reader].lock_initialized = 1; } #endif /*USE_GNU_PTH*/ + reader_table[reader].connect_card = NULL; + reader_table[reader].disconnect_card = NULL; reader_table[reader].close_reader = NULL; reader_table[reader].shutdown_reader = NULL; reader_table[reader].reset_reader = NULL; @@ -329,8 +341,10 @@ reader_table[reader].send_apdu_reader = NULL; reader_table[reader].check_keypad = NULL; reader_table[reader].dump_status_reader = NULL; + reader_table[reader].set_progress_cb = NULL; - reader_table[reader].used = 1; + reader_table[reader].used = 1; + reader_table[reader].any_status = 0; reader_table[reader].last_status = 0; reader_table[reader].is_t0 = 1; #ifdef NEED_PCSC_WRAPPER @@ -381,6 +395,7 @@ case SW_HOST_NO_READER: return "no reader"; case SW_HOST_ABORTED: return "aborted"; case SW_HOST_NO_KEYPAD: return "no keypad"; + case SW_HOST_ALREADY_CONNECTED: return "already connected"; default: return "unknown host status error"; } } @@ -402,6 +417,7 @@ case SW_FILE_NOT_FOUND : return "file not found"; case SW_RECORD_NOT_FOUND:return "record not found"; case SW_REF_NOT_FOUND : return "reference not found"; + case SW_BAD_LC : return "bad Lc"; case SW_BAD_P0_P1 : return "bad P0 or P1"; case SW_INS_NOT_SUP : return "instruction not supported"; case SW_CLA_NOT_SUP : return "class not supported"; @@ -531,10 +547,11 @@ static int ct_get_status (int slot, unsigned int *status) { - *status = 1|2|4; /* FIXME */ + (void)slot; + /* The status we returned is wrong but we don't care becuase ctAPI + is not anymore required. */ + *status = APDU_CARD_USABLE|APDU_CARD_PRESENT|APDU_CARD_ACTIVE; return 0; - - return SW_HOST_NOT_SUPPORTED; } /* Actually send the APDU of length APDULEN to SLOT and return a @@ -548,6 +565,8 @@ unsigned char dad[1], sad[1]; unsigned short ctbuflen; + (void)pininfo; + /* If we don't have an ATR, we need to reset the reader first. */ if (!reader_table[slot].atrlen && (rc = reset_ct_reader (slot))) @@ -655,6 +674,9 @@ while (nleft > 0) { #ifdef USE_GNU_PTH +# ifdef HAVE_W32_SYSTEM +# error Cannot use pth_read here because it expects a system HANDLE. +# endif n = pth_read (fd, buf, nleft); #else n = read (fd, buf, nleft); @@ -736,7 +758,7 @@ { int rc; - switch (ec) + switch ( PCSC_ERR_MASK (ec) ) { case 0: rc = 0; break; @@ -762,177 +784,87 @@ static void dump_pcsc_reader_status (int slot) { - log_info ("reader slot %d: active protocol:", slot); - if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T0)) - log_printf (" T0"); - else if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T1)) - log_printf (" T1"); - else if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_RAW)) - log_printf (" raw"); - log_printf ("\n"); + if (reader_table[slot].pcsc.card) + { + log_info ("reader slot %d: active protocol:", slot); + if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T0)) + log_printf (" T0"); + else if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T1)) + log_printf (" T1"); + else if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_RAW)) + log_printf (" raw"); + log_printf ("\n"); + } + else + log_info ("reader slot %d: not connected\n", slot); } -/* Send an PC/SC reset command and return a status word on error or 0 - on success. */ +#ifndef NEED_PCSC_WRAPPER static int -reset_pcsc_reader (int slot) +pcsc_get_status_direct (int slot, unsigned int *status) { -#ifdef NEED_PCSC_WRAPPER long err; - reader_table_t slotp; - size_t len; - int i, n; - unsigned char msgbuf[9]; - unsigned int dummy_status; - int sw = SW_HOST_CARD_IO_ERROR; + struct pcsc_readerstate_s rdrstates[1]; - slotp = reader_table + slot; - - if (slotp->pcsc.req_fd == -1 - || slotp->pcsc.rsp_fd == -1 - || slotp->pcsc.pid == (pid_t)(-1) ) - { - log_error ("pcsc_get_status: pcsc-wrapper not running\n"); - return sw; - } - - msgbuf[0] = 0x05; /* RESET command. */ - len = 0; - msgbuf[1] = (len >> 24); - msgbuf[2] = (len >> 16); - msgbuf[3] = (len >> 8); - msgbuf[4] = (len ); - if ( writen (slotp->pcsc.req_fd, msgbuf, 5) ) - { - log_error ("error sending PC/SC RESET request: %s\n", - strerror (errno)); - goto command_failed; - } - - /* Read the response. */ - if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9) - { - log_error ("error receiving PC/SC RESET response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; - if (msgbuf[0] != 0x81 || len < 4) - { - log_error ("invalid response header from PC/SC received\n"); - goto command_failed; - } - len -= 4; /* Already read the error code. */ - if (len > DIM (slotp->atr)) - { - log_error ("PC/SC returned a too large ATR (len=%lx)\n", - (unsigned long)len); - sw = SW_HOST_GENERAL_ERROR; - goto command_failed; - } - err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; + memset (rdrstates, 0, sizeof *rdrstates); + rdrstates[0].reader = reader_table[slot].rdrname; + rdrstates[0].current_state = PCSC_STATE_UNAWARE; + err = pcsc_get_status_change (reader_table[slot].pcsc.context, + 0, + rdrstates, 1); + if (err == PCSC_E_TIMEOUT) + err = 0; /* Timeout is no error error here. */ if (err) { - log_error ("PC/SC RESET failed: %s (0x%lx)\n", + log_error ("pcsc_get_status_change failed: %s (0x%lx)\n", pcsc_error_string (err), err); - /* If the error code is no smart card, we should not considere - this a major error and close the wrapper. */ - sw = pcsc_error_to_sw (err); - if (err == PCSC_E_NO_SMARTCARD) - return sw; - goto command_failed; - } - - /* The open function may return a zero for the ATR length to - indicate that no card is present. */ - n = len; - if (n) - { - if ((i=readn (slotp->pcsc.rsp_fd, slotp->atr, n, &len)) || len != n) - { - log_error ("error receiving PC/SC RESET response: %s\n", - i? strerror (errno) : "premature EOF"); - goto command_failed; - } - } - slotp->atrlen = len; - - /* Read the status so that IS_T0 will be set. */ - pcsc_get_status (slot, &dummy_status); - - return 0; - - command_failed: - close (slotp->pcsc.req_fd); - close (slotp->pcsc.rsp_fd); - slotp->pcsc.req_fd = -1; - slotp->pcsc.rsp_fd = -1; - kill (slotp->pcsc.pid, SIGTERM); - slotp->pcsc.pid = (pid_t)(-1); - slotp->used = 0; - return sw; - -#else /* !NEED_PCSC_WRAPPER */ - long err; - char reader[250]; - unsigned long nreader, atrlen; - unsigned long card_state, card_protocol; - - if (reader_table[slot].pcsc.card) - { - err = pcsc_disconnect (reader_table[slot].pcsc.card, PCSC_LEAVE_CARD); - if (err) - { - log_error ("pcsc_disconnect failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - return SW_HOST_CARD_IO_ERROR; - } - reader_table[slot].pcsc.card = 0; - } - - err = pcsc_connect (reader_table[slot].pcsc.context, - reader_table[slot].rdrname, - PCSC_SHARE_EXCLUSIVE, - PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1, - &reader_table[slot].pcsc.card, - &reader_table[slot].pcsc.protocol); - if (err) - { - log_error ("pcsc_connect failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - reader_table[slot].pcsc.card = 0; return pcsc_error_to_sw (err); } + /* log_debug */ + /* ("pcsc_get_status_change: %s%s%s%s%s%s%s%s%s%s\n", */ + /* (rdrstates[0].event_state & PCSC_STATE_IGNORE)? " ignore":"", */ + /* (rdrstates[0].event_state & PCSC_STATE_CHANGED)? " changed":"", */ + /* (rdrstates[0].event_state & PCSC_STATE_UNKNOWN)? " unknown":"", */ + /* (rdrstates[0].event_state & PCSC_STATE_UNAVAILABLE)?" unavail":"", */ + /* (rdrstates[0].event_state & PCSC_STATE_EMPTY)? " empty":"", */ + /* (rdrstates[0].event_state & PCSC_STATE_PRESENT)? " present":"", */ + /* (rdrstates[0].event_state & PCSC_STATE_ATRMATCH)? " atr":"", */ + /* (rdrstates[0].event_state & PCSC_STATE_EXCLUSIVE)? " excl":"", */ + /* (rdrstates[0].event_state & PCSC_STATE_INUSE)? " unuse":"", */ + /* (rdrstates[0].event_state & PCSC_STATE_MUTE)? " mute":"" ); */ - atrlen = 33; - nreader = sizeof reader - 1; - err = pcsc_status (reader_table[slot].pcsc.card, - reader, &nreader, - &card_state, &card_protocol, - reader_table[slot].atr, &atrlen); - if (err) - { - log_error ("pcsc_status failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - reader_table[slot].atrlen = 0; - return pcsc_error_to_sw (err); - } - if (atrlen >= DIM (reader_table[0].atr)) - log_bug ("ATR returned by pcsc_status is too large\n"); - reader_table[slot].atrlen = atrlen; - reader_table[slot].is_t0 = !!(card_protocol & PCSC_PROTOCOL_T0); + *status = 0; + if ( (rdrstates[0].event_state & PCSC_STATE_PRESENT) ) + *status |= APDU_CARD_PRESENT; + if ( !(rdrstates[0].event_state & PCSC_STATE_MUTE) ) + *status |= APDU_CARD_ACTIVE; +#ifndef HAVE_W32_SYSTEM + /* We indicate a useful card if it is not in use by another + application. This is because we only use exclusive access + mode. */ + if ( (*status & (APDU_CARD_PRESENT|APDU_CARD_ACTIVE)) + == (APDU_CARD_PRESENT|APDU_CARD_ACTIVE) + && !(rdrstates[0].event_state & PCSC_STATE_INUSE) ) + *status |= APDU_CARD_USABLE; +#else + /* Some winscard drivers may set EXCLUSIVE and INUSE at the same + time when we are the only user (SCM SCR335) under Windows. */ + if ((*status & (APDU_CARD_PRESENT|APDU_CARD_ACTIVE)) + == (APDU_CARD_PRESENT|APDU_CARD_ACTIVE)) + *status |= APDU_CARD_USABLE; +#endif return 0; -#endif /* !NEED_PCSC_WRAPPER */ } +#endif /*!NEED_PCSC_WRAPPER*/ +#ifdef NEED_PCSC_WRAPPER static int -pcsc_get_status (int slot, unsigned int *status) +pcsc_get_status_wrapped (int slot, unsigned int *status) { -#ifdef NEED_PCSC_WRAPPER long err; reader_table_t slotp; size_t len, full_len; @@ -978,7 +910,8 @@ goto command_failed; } len -= 4; /* Already read the error code. */ - err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; + err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) + | (msgbuf[7] << 8 ) | msgbuf[8]); if (err) { log_error ("pcsc_status failed: %s (0x%lx)\n", @@ -1023,7 +956,6 @@ /* We are lucky: The wrapper already returns the data in the required format. */ *status = buffer[3]; - return 0; command_failed: @@ -1035,67 +967,63 @@ slotp->pcsc.pid = (pid_t)(-1); slotp->used = 0; return sw; +} +#endif /*NEED_PCSC_WRAPPER*/ -#else /*!NEED_PCSC_WRAPPER*/ +static int +pcsc_get_status (int slot, unsigned int *status) +{ +#ifdef NEED_PCSC_WRAPPER + return pcsc_get_status_wrapped (slot, status); +#else + return pcsc_get_status_direct (slot, status); +#endif +} + + +#ifndef NEED_PCSC_WRAPPER +static int +pcsc_send_apdu_direct (int slot, unsigned char *apdu, size_t apdulen, + unsigned char *buffer, size_t *buflen, + struct pininfo_s *pininfo) +{ long err; - struct pcsc_readerstate_s rdrstates[1]; + struct pcsc_io_request_s send_pci; + unsigned long recv_len; - memset (rdrstates, 0, sizeof *rdrstates); - rdrstates[0].reader = reader_table[slot].rdrname; - rdrstates[0].current_state = PCSC_STATE_UNAWARE; - err = pcsc_get_status_change (reader_table[slot].pcsc.context, - 0, - rdrstates, 1); - if (err == PCSC_E_TIMEOUT) - err = 0; /* Timeout is no error error here. */ - if (err) - { - log_error ("pcsc_get_status_change failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - return pcsc_error_to_sw (err); - } + if (!reader_table[slot].atrlen + && (err = reset_pcsc_reader (slot))) + return err; + if (DBG_CARD_IO) + log_printhex (" PCSC_data:", apdu, apdulen); - /* log_debug */ - /* ("pcsc_get_status_change: %s%s%s%s%s%s%s%s%s%s\n", */ - /* (rdrstates[0].event_state & PCSC_STATE_IGNORE)? " ignore":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_CHANGED)? " changed":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_UNKNOWN)? " unknown":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_UNAVAILABLE)?" unavail":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_EMPTY)? " empty":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_PRESENT)? " present":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_ATRMATCH)? " atr":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_EXCLUSIVE)? " excl":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_INUSE)? " unuse":"", */ - /* (rdrstates[0].event_state & PCSC_STATE_MUTE)? " mute":"" ); */ + if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T1)) + send_pci.protocol = PCSC_PROTOCOL_T1; + else + send_pci.protocol = PCSC_PROTOCOL_T0; + send_pci.pci_len = sizeof send_pci; + recv_len = *buflen; + err = pcsc_transmit (reader_table[slot].pcsc.card, + &send_pci, apdu, apdulen, + NULL, buffer, &recv_len); + *buflen = recv_len; + if (err) + log_error ("pcsc_transmit failed: %s (0x%lx)\n", + pcsc_error_string (err), err); - *status = 0; - if ( (rdrstates[0].event_state & PCSC_STATE_PRESENT) ) - *status |= 2; - if ( !(rdrstates[0].event_state & PCSC_STATE_MUTE) ) - *status |= 4; - /* We indicate a useful card if it is not in use by another - application. This is because we only use exclusive access - mode. */ - if ( (*status & 6) == 6 - && !(rdrstates[0].event_state & PCSC_STATE_INUSE) ) - *status |= 1; - - return 0; + return pcsc_error_to_sw (err); +} #endif /*!NEED_PCSC_WRAPPER*/ -} -/* Actually send the APDU of length APDULEN to SLOT and return a - maximum of *BUFLEN data in BUFFER, the actual returned size will be - set to BUFLEN. Returns: CT API error code. */ +#ifdef NEED_PCSC_WRAPPER static int -pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, - unsigned char *buffer, size_t *buflen, - struct pininfo_s *pininfo) +pcsc_send_apdu_wrapped (int slot, unsigned char *apdu, size_t apdulen, + unsigned char *buffer, size_t *buflen, + struct pininfo_s *pininfo) { -#ifdef NEED_PCSC_WRAPPER long err; reader_table_t slotp; size_t len, full_len; @@ -1103,6 +1031,8 @@ unsigned char msgbuf[9]; int sw = SW_HOST_CARD_IO_ERROR; + (void)pininfo; + if (!reader_table[slot].atrlen && (err = reset_pcsc_reader (slot))) return err; @@ -1148,7 +1078,8 @@ goto command_failed; } len -= 4; /* Already read the error code. */ - err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; + err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) + | (msgbuf[7] << 8 ) | msgbuf[8]); if (err) { log_error ("pcsc_transmit failed: %s (0x%lx)\n", @@ -1174,7 +1105,7 @@ err = SW_HOST_INV_VALUE; } /* We need to read any rest of the response, to keep the - protocol runnng. */ + protocol running. */ while (full_len) { unsigned char dummybuf[128]; @@ -1200,43 +1131,43 @@ slotp->pcsc.pid = (pid_t)(-1); slotp->used = 0; return sw; +} +#endif /*NEED_PCSC_WRAPPER*/ -#else /*!NEED_PCSC_WRAPPER*/ - long err; - struct pcsc_io_request_s send_pci; - unsigned long recv_len; +/* Send the APDU of length APDULEN to SLOT and return a maximum of + *BUFLEN data in BUFFER, the actual returned size will be stored at + BUFLEN. Returns: A status word. */ +static int +pcsc_send_apdu (int slot, unsigned char *apdu, size_t apdulen, + unsigned char *buffer, size_t *buflen, + struct pininfo_s *pininfo) +{ +#ifdef NEED_PCSC_WRAPPER + return pcsc_send_apdu_wrapped (slot, apdu, apdulen, buffer, buflen, pininfo); +#else + return pcsc_send_apdu_direct (slot, apdu, apdulen, buffer, buflen, pininfo); +#endif +} - if (!reader_table[slot].atrlen - && (err = reset_pcsc_reader (slot))) - return err; - if (DBG_CARD_IO) - log_printhex (" PCSC_data:", apdu, apdulen); - - if ((reader_table[slot].pcsc.protocol & PCSC_PROTOCOL_T1)) - send_pci.protocol = PCSC_PROTOCOL_T1; - else - send_pci.protocol = PCSC_PROTOCOL_T0; - send_pci.pci_len = sizeof send_pci; - recv_len = *buflen; - err = pcsc_transmit (reader_table[slot].pcsc.card, - &send_pci, apdu, apdulen, - NULL, buffer, &recv_len); - *buflen = recv_len; - if (err) - log_error ("pcsc_transmit failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - - return pcsc_error_to_sw (err); +#ifndef NEED_PCSC_WRAPPER +static int +close_pcsc_reader_direct (int slot) +{ + pcsc_release_context (reader_table[slot].pcsc.context); + xfree (reader_table[slot].rdrname); + reader_table[slot].rdrname = NULL; + reader_table[slot].used = 0; + return 0; +} #endif /*!NEED_PCSC_WRAPPER*/ -} +#ifdef NEED_PCSC_WRAPPER static int -close_pcsc_reader (int slot) +close_pcsc_reader_wrapped (int slot) { -#ifdef NEED_PCSC_WRAPPER long err; reader_table_t slotp; size_t len; @@ -1280,7 +1211,8 @@ goto command_failed; } len -= 4; /* Already read the error code. */ - err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; + err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) + | (msgbuf[7] << 8 ) | msgbuf[8]); if (err) log_error ("pcsc_close failed: %s (0x%lx)\n", pcsc_error_string (err), err); @@ -1297,25 +1229,348 @@ slotp->pcsc.pid = (pid_t)(-1); slotp->used = 0; return 0; +} +#endif /*NEED_PCSC_WRAPPER*/ -#else /*!NEED_PCSC_WRAPPER*/ - pcsc_release_context (reader_table[slot].pcsc.context); - xfree (reader_table[slot].rdrname); - reader_table[slot].rdrname = NULL; - reader_table[slot].used = 0; +static int +close_pcsc_reader (int slot) +{ +#ifdef NEED_PCSC_WRAPPER + return close_pcsc_reader_wrapped (slot); +#else + return close_pcsc_reader_direct (slot); +#endif +} + + +/* Connect a PC/SC card. */ +#ifndef NEED_PCSC_WRAPPER +static int +connect_pcsc_card (int slot) +{ + long err; + + assert (slot >= 0 && slot < MAX_READER); + + if (reader_table[slot].pcsc.card) + return SW_HOST_ALREADY_CONNECTED; + + reader_table[slot].atrlen = 0; + reader_table[slot].last_status = 0; + reader_table[slot].is_t0 = 0; + + err = pcsc_connect (reader_table[slot].pcsc.context, + reader_table[slot].rdrname, + PCSC_SHARE_EXCLUSIVE, + PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1, + &reader_table[slot].pcsc.card, + &reader_table[slot].pcsc.protocol); + if (err) + { + reader_table[slot].pcsc.card = 0; + if (err != PCSC_E_NO_SMARTCARD) + log_error ("pcsc_connect failed: %s (0x%lx)\n", + pcsc_error_string (err), err); + } + else + { + char reader[250]; + unsigned long readerlen, atrlen; + unsigned long card_state, card_protocol; + + atrlen = DIM (reader_table[0].atr); + readerlen = sizeof reader -1 ; + err = pcsc_status (reader_table[slot].pcsc.card, + reader, &readerlen, + &card_state, &card_protocol, + reader_table[slot].atr, &atrlen); + if (err) + log_error ("pcsc_status failed: %s (0x%lx) %lu\n", + pcsc_error_string (err), err, readerlen); + else + { + if (atrlen > DIM (reader_table[0].atr)) + log_bug ("ATR returned by pcsc_status is too large\n"); + reader_table[slot].atrlen = atrlen; + /* If we got to here we know that a card is present + and usable. Remember this. */ + reader_table[slot].last_status = ( APDU_CARD_USABLE + | APDU_CARD_PRESENT + | APDU_CARD_ACTIVE); + reader_table[slot].is_t0 = !!(card_protocol & PCSC_PROTOCOL_T0); + } + } + + dump_reader_status (slot); + return pcsc_error_to_sw (err); +} +#endif /*!NEED_PCSC_WRAPPER*/ + + +/* Disconnect a PC/SC card. Note that this succeeds even if the card + is not connected. */ +#ifndef NEED_PCSC_WRAPPER +static int +disconnect_pcsc_card (int slot) +{ + long err; + + assert (slot >= 0 && slot < MAX_READER); + + if (!reader_table[slot].pcsc.card) + return 0; + + err = pcsc_disconnect (reader_table[slot].pcsc.card, PCSC_LEAVE_CARD); + if (err) + { + log_error ("pcsc_disconnect failed: %s (0x%lx)\n", + pcsc_error_string (err), err); + return SW_HOST_CARD_IO_ERROR; + } + reader_table[slot].pcsc.card = 0; return 0; +} #endif /*!NEED_PCSC_WRAPPER*/ + + +#ifndef NEED_PCSC_WRAPPER +static int +reset_pcsc_reader_direct (int slot) +{ + int sw; + + sw = disconnect_pcsc_card (slot); + if (!sw) + sw = connect_pcsc_card (slot); + + return sw; } +#endif /*NEED_PCSC_WRAPPER*/ -/* Note: It is a pitty that we can't return proper error codes. */ + +#ifdef NEED_PCSC_WRAPPER static int -open_pcsc_reader (const char *portstr) +reset_pcsc_reader_wrapped (int slot) { + long err; + reader_table_t slotp; + size_t len; + int i, n; + unsigned char msgbuf[9]; + unsigned int dummy_status; + int sw = SW_HOST_CARD_IO_ERROR; + + slotp = reader_table + slot; + + if (slotp->pcsc.req_fd == -1 + || slotp->pcsc.rsp_fd == -1 + || slotp->pcsc.pid == (pid_t)(-1) ) + { + log_error ("pcsc_get_status: pcsc-wrapper not running\n"); + return sw; + } + + msgbuf[0] = 0x05; /* RESET command. */ + len = 0; + msgbuf[1] = (len >> 24); + msgbuf[2] = (len >> 16); + msgbuf[3] = (len >> 8); + msgbuf[4] = (len ); + if ( writen (slotp->pcsc.req_fd, msgbuf, 5) ) + { + log_error ("error sending PC/SC RESET request: %s\n", + strerror (errno)); + goto command_failed; + } + + /* Read the response. */ + if ((i=readn (slotp->pcsc.rsp_fd, msgbuf, 9, &len)) || len != 9) + { + log_error ("error receiving PC/SC RESET response: %s\n", + i? strerror (errno) : "premature EOF"); + goto command_failed; + } + len = (msgbuf[1] << 24) | (msgbuf[2] << 16) | (msgbuf[3] << 8 ) | msgbuf[4]; + if (msgbuf[0] != 0x81 || len < 4) + { + log_error ("invalid response header from PC/SC received\n"); + goto command_failed; + } + len -= 4; /* Already read the error code. */ + if (len > DIM (slotp->atr)) + { + log_error ("PC/SC returned a too large ATR (len=%lx)\n", + (unsigned long)len); + sw = SW_HOST_GENERAL_ERROR; + goto command_failed; + } + err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) + | (msgbuf[7] << 8 ) | msgbuf[8]); + if (err) + { + log_error ("PC/SC RESET failed: %s (0x%lx)\n", + pcsc_error_string (err), err); + /* If the error code is no smart card, we should not considere + this a major error and close the wrapper. */ + sw = pcsc_error_to_sw (err); + if (err == PCSC_E_NO_SMARTCARD) + return sw; + goto command_failed; + } + + /* The open function may return a zero for the ATR length to + indicate that no card is present. */ + n = len; + if (n) + { + if ((i=readn (slotp->pcsc.rsp_fd, slotp->atr, n, &len)) || len != n) + { + log_error ("error receiving PC/SC RESET response: %s\n", + i? strerror (errno) : "premature EOF"); + goto command_failed; + } + } + slotp->atrlen = len; + + /* Read the status so that IS_T0 will be set. */ + pcsc_get_status (slot, &dummy_status); + + return 0; + + command_failed: + close (slotp->pcsc.req_fd); + close (slotp->pcsc.rsp_fd); + slotp->pcsc.req_fd = -1; + slotp->pcsc.rsp_fd = -1; + kill (slotp->pcsc.pid, SIGTERM); + slotp->pcsc.pid = (pid_t)(-1); + slotp->used = 0; + return sw; +} +#endif /* !NEED_PCSC_WRAPPER */ + + +/* Send an PC/SC reset command and return a status word on error or 0 + on success. */ +static int +reset_pcsc_reader (int slot) +{ #ifdef NEED_PCSC_WRAPPER + return reset_pcsc_reader_wrapped (slot); +#else + return reset_pcsc_reader_direct (slot); +#endif +} + + +/* Open the PC/SC reader without using the wrapper. Returns -1 on + error or a slot number for the reader. */ +#ifndef NEED_PCSC_WRAPPER +static int +open_pcsc_reader_direct (const char *portstr) +{ + long err; + int slot; + char *list = NULL; + unsigned long nreader, listlen; + char *p; + + slot = new_reader_slot (); + if (slot == -1) + return -1; + + /* Fixme: Allocating a context for each slot is not required. One + global context should be sufficient. */ + err = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL, + &reader_table[slot].pcsc.context); + if (err) + { + log_error ("pcsc_establish_context failed: %s (0x%lx)\n", + pcsc_error_string (err), err); + reader_table[slot].used = 0; + return -1; + } + + err = pcsc_list_readers (reader_table[slot].pcsc.context, + NULL, NULL, &nreader); + if (!err) + { + list = xtrymalloc (nreader+1); /* Better add 1 for safety reasons. */ + if (!list) + { + log_error ("error allocating memory for reader list\n"); + pcsc_release_context (reader_table[slot].pcsc.context); + reader_table[slot].used = 0; + return -1 /*SW_HOST_OUT_OF_CORE*/; + } + err = pcsc_list_readers (reader_table[slot].pcsc.context, + NULL, list, &nreader); + } + if (err) + { + log_error ("pcsc_list_readers failed: %s (0x%lx)\n", + pcsc_error_string (err), err); + pcsc_release_context (reader_table[slot].pcsc.context); + reader_table[slot].used = 0; + xfree (list); + return -1; + } + + listlen = nreader; + p = list; + while (nreader) + { + if (!*p && !p[1]) + break; + if (*p) + log_info ("detected reader `%s'\n", p); + if (nreader < (strlen (p)+1)) + { + log_error ("invalid response from pcsc_list_readers\n"); + break; + } + nreader -= strlen (p)+1; + p += strlen (p) + 1; + } + + reader_table[slot].rdrname = xtrymalloc (strlen (portstr? portstr : list)+1); + if (!reader_table[slot].rdrname) + { + log_error ("error allocating memory for reader name\n"); + pcsc_release_context (reader_table[slot].pcsc.context); + reader_table[slot].used = 0; + return -1; + } + strcpy (reader_table[slot].rdrname, portstr? portstr : list); + xfree (list); + list = NULL; + + reader_table[slot].pcsc.card = 0; + reader_table[slot].atrlen = 0; + reader_table[slot].last_status = 0; + + reader_table[slot].connect_card = connect_pcsc_card; + reader_table[slot].disconnect_card = disconnect_pcsc_card; + reader_table[slot].close_reader = close_pcsc_reader; + reader_table[slot].reset_reader = reset_pcsc_reader; + reader_table[slot].get_status_reader = pcsc_get_status; + reader_table[slot].send_apdu_reader = pcsc_send_apdu; + reader_table[slot].dump_status_reader = dump_pcsc_reader_status; + + dump_reader_status (slot); + return slot; +} +#endif /*!NEED_PCSC_WRAPPER */ + + /* Open the PC/SC reader using the pcsc_wrapper program. This is needed to cope with different thread models and other peculiarities of libpcsclite. */ +#ifdef NEED_PCSC_WRAPPER +static int +open_pcsc_reader_wrapped (const char *portstr) +{ int slot; reader_table_t slotp; int fd, rp[2], wp[2]; @@ -1326,14 +1581,24 @@ int err; unsigned int dummy_status; int sw = SW_HOST_CARD_IO_ERROR; + /* Note that we use the constant and not the fucntion because this + code won't be be used under Windows. */ + const char *wrapperpgm = GNUPG_LIBEXECDIR "/gnupg-pcsc-wrapper"; + if (access (wrapperpgm, X_OK)) + { + log_error ("can't run PC/SC access module `%s': %s\n", + wrapperpgm, strerror (errno)); + return -1; + } + slot = new_reader_slot (); if (slot == -1) return -1; slotp = reader_table + slot; - /* Fire up the pcsc wrapper. We don't use any fork/exec code from - the common directy but implement it direclty so that this file + /* Fire up the PC/SCc wrapper. We don't use any fork/exec code from + the common directy but implement it directly so that this file may still be source copied. */ if (pipe (rp) == -1) @@ -1391,14 +1656,9 @@ log_fatal ("dup2 stderr failed: %s\n", strerror (errno)); /* Close all other files. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; - for (i=3; i < n; i++) - close(i); - errno = 0; + close_all_fds (3, NULL); - execl (GNUPG_LIBDIR "/pcsc-wrapper", + execl (wrapperpgm, "pcsc-wrapper", "--", "1", /* API version */ @@ -1423,7 +1683,7 @@ #endif while ( (i=WAIT (pid, NULL, 0)) == -1 && errno == EINTR) ; -#undef X +#undef WAIT /* Now send the open request. */ msgbuf[0] = 0x01; /* OPEN command. */ @@ -1459,7 +1719,8 @@ (unsigned long)len); goto command_failed; } - err = (msgbuf[5] << 24) | (msgbuf[6] << 16) | (msgbuf[7] << 8 ) | msgbuf[8]; + err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16) + | (msgbuf[7] << 8 ) | msgbuf[8]); if (err) { log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err)); @@ -1482,7 +1743,9 @@ } /* If we got to here we know that a card is present and usable. Thus remember this. */ - slotp->last_status = (1|2|4| 0x8000); + slotp->last_status = ( APDU_CARD_USABLE + | APDU_CARD_PRESENT + | APDU_CARD_ACTIVE); } slotp->atrlen = len; @@ -1490,7 +1753,6 @@ reader_table[slot].reset_reader = reset_pcsc_reader; reader_table[slot].get_status_reader = pcsc_get_status; reader_table[slot].send_apdu_reader = pcsc_send_apdu; - reader_table[slot].check_keypad = NULL; reader_table[slot].dump_status_reader = dump_pcsc_reader_status; /* Read the status so that IS_T0 will be set. */ @@ -1510,146 +1772,21 @@ /* There is no way to return SW. */ return -1; -#else /*!NEED_PCSC_WRAPPER */ - long err; - int slot; - char *list = NULL; - unsigned long nreader, listlen, atrlen; - char *p; - unsigned long card_state, card_protocol; +} +#endif /*NEED_PCSC_WRAPPER*/ - slot = new_reader_slot (); - if (slot == -1) - return -1; - err = pcsc_establish_context (PCSC_SCOPE_SYSTEM, NULL, NULL, - &reader_table[slot].pcsc.context); - if (err) - { - log_error ("pcsc_establish_context failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - reader_table[slot].used = 0; - return -1; - } - - err = pcsc_list_readers (reader_table[slot].pcsc.context, - NULL, NULL, &nreader); - if (!err) - { - list = xtrymalloc (nreader+1); /* Better add 1 for safety reasons. */ - if (!list) - { - log_error ("error allocating memory for reader list\n"); - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - return -1 /*SW_HOST_OUT_OF_CORE*/; - } - err = pcsc_list_readers (reader_table[slot].pcsc.context, - NULL, list, &nreader); - } - if (err) - { - log_error ("pcsc_list_readers failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - xfree (list); - return -1 /*pcsc_error_to_sw (err)*/; - } - - listlen = nreader; - p = list; - while (nreader) - { - if (!*p && !p[1]) - break; - if (*p) - log_info ("detected reader `%s'\n", p); - if (nreader < (strlen (p)+1)) - { - log_error ("invalid response from pcsc_list_readers\n"); - break; - } - nreader -= strlen (p)+1; - p += strlen (p) + 1; - } - - reader_table[slot].rdrname = xtrymalloc (strlen (portstr? portstr : list)+1); - if (!reader_table[slot].rdrname) - { - log_error ("error allocating memory for reader name\n"); - pcsc_release_context (reader_table[slot].pcsc.context); - reader_table[slot].used = 0; - return -1 /*SW_HOST_OUT_OF_CORE*/; - } - strcpy (reader_table[slot].rdrname, portstr? portstr : list); - xfree (list); - list = NULL; - - err = pcsc_connect (reader_table[slot].pcsc.context, - reader_table[slot].rdrname, - PCSC_SHARE_EXCLUSIVE, - PCSC_PROTOCOL_T0|PCSC_PROTOCOL_T1, - &reader_table[slot].pcsc.card, - &reader_table[slot].pcsc.protocol); - if (err == PCSC_E_NO_SMARTCARD) - reader_table[slot].pcsc.card = 0; - else if (err) - { - log_error ("pcsc_connect failed: %s (0x%lx)\n", - pcsc_error_string (err), err); - pcsc_release_context (reader_table[slot].pcsc.context); - xfree (reader_table[slot].rdrname); - reader_table[slot].rdrname = NULL; - reader_table[slot].used = 0; - return -1 /*pcsc_error_to_sw (err)*/; - } - - reader_table[slot].atrlen = 0; - reader_table[slot].last_status = 0; - if (!err) - { - char reader[250]; - unsigned long readerlen; - - atrlen = 32; - readerlen = sizeof reader -1 ; - err = pcsc_status (reader_table[slot].pcsc.card, - reader, &readerlen, - &card_state, &card_protocol, - reader_table[slot].atr, &atrlen); - if (err) - log_error ("pcsc_status failed: %s (0x%lx) %lu\n", - pcsc_error_string (err), err, readerlen); - else - { - if (atrlen >= DIM (reader_table[0].atr)) - log_bug ("ATR returned by pcsc_status is too large\n"); - reader_table[slot].atrlen = atrlen; - /* If we got to here we know that a card is present - and usable. Thus remember this. */ - reader_table[slot].last_status = (1|2|4| 0x8000); - reader_table[slot].is_t0 = !!(card_protocol & PCSC_PROTOCOL_T0); - } - } - - reader_table[slot].close_reader = close_pcsc_reader; - reader_table[slot].reset_reader = reset_pcsc_reader; - reader_table[slot].get_status_reader = pcsc_get_status; - reader_table[slot].send_apdu_reader = pcsc_send_apdu; - reader_table[slot].check_keypad = NULL; - reader_table[slot].dump_status_reader = dump_pcsc_reader_status; - -/* log_debug ("state from pcsc_status: 0x%lx\n", card_state); */ -/* log_debug ("protocol from pcsc_status: 0x%lx\n", card_protocol); */ - - dump_reader_status (slot); - return slot; -#endif /*!NEED_PCSC_WRAPPER */ +static int +open_pcsc_reader (const char *portstr) +{ +#ifdef NEED_PCSC_WRAPPER + return open_pcsc_reader_wrapped (portstr); +#else + return open_pcsc_reader_direct (portstr); +#endif } - #ifdef HAVE_LIBUSB /* @@ -1701,6 +1838,15 @@ static int +set_progress_cb_ccid_reader (int slot, gcry_handler_progress_t cb, void *cb_arg) +{ + reader_table_t slotp = reader_table + slot; + + return ccid_set_progress_cb (slotp->ccid.handle, cb, cb_arg); +} + + +static int get_status_ccid (int slot, unsigned int *status) { int rc; @@ -1708,12 +1854,12 @@ rc = ccid_slot_status (reader_table[slot].ccid.handle, &bits); if (rc) - return -1; + return rc; if (bits == 0) - *status = 1|2|4; + *status = (APDU_CARD_USABLE|APDU_CARD_PRESENT|APDU_CARD_ACTIVE); else if (bits == 1) - *status = 2; + *status = APDU_CARD_PRESENT; else *status = 0; @@ -1738,7 +1884,7 @@ return err; if (DBG_CARD_IO) - log_printhex (" APDU_data:", apdu, apdulen); + log_printhex (" raw apdu:", apdu, apdulen); maxbuflen = *buflen; if (pininfo) @@ -1809,7 +1955,9 @@ { /* If we got to here we know that a card is present and usable. Thus remember this. */ - reader_table[slot].last_status = (1|2|4| 0x8000); + reader_table[slot].last_status = (APDU_CARD_USABLE + | APDU_CARD_PRESENT + | APDU_CARD_ACTIVE); } reader_table[slot].close_reader = close_ccid_reader; @@ -1819,6 +1967,10 @@ reader_table[slot].send_apdu_reader = send_apdu_ccid; reader_table[slot].check_keypad = check_ccid_keypad; reader_table[slot].dump_status_reader = dump_ccid_reader_status; + reader_table[slot].set_progress_cb = set_progress_cb_ccid_reader; + /* Our CCID reader code does not support T=0 at all, thus reset the + flag. */ + reader_table[slot].is_t0 = 0; dump_reader_status (slot); return slot; @@ -1913,7 +2065,7 @@ rapdu_msg_release (msg); return sw; } - if (msg->datalen >= DIM (slotp->atr)) + if (msg->datalen > DIM (slotp->atr)) { log_error ("ATR returned by the RAPDU layer is too large\n"); rapdu_msg_release (msg); @@ -2094,7 +2246,7 @@ rapdu_strerror (msg->cmd)); goto failure; } - if (msg->datalen >= DIM (slotp->atr)) + if (msg->datalen > DIM (slotp->atr)) { log_error ("ATR returned by the RAPDU layer is too large\n"); goto failure; @@ -2338,6 +2490,15 @@ writefnc, writefnc_value, closefnc, closefnc_value); #else + (void)portstr; + (void)cookie; + (void)length; + (void)readfnc; + (void)readfnc_value; + (void)writefnc; + (void)writefnc_value; + (void)closefnc; + (void)closefnc_value; #ifdef _WIN32 errno = ENOENT; #else @@ -2351,21 +2512,58 @@ int apdu_close_reader (int slot) { + int sw; + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; + sw = apdu_disconnect (slot); + if (sw) + return sw; if (reader_table[slot].close_reader) return reader_table[slot].close_reader (slot); return SW_HOST_NOT_SUPPORTED; } + +/* Function suitable for a cleanup function to close all reader. It + should not be used if the reader will be opened again. The reason + for implementing this to properly close USB devices so that they + will startup the next time without error. */ +void +apdu_prepare_exit (void) +{ + static int sentinel; + int slot; + + if (!sentinel) + { + sentinel = 1; + for (slot = 0; slot < MAX_READER; slot++) + if (reader_table[slot].used) + { + apdu_disconnect (slot); + if (reader_table[slot].close_reader) + reader_table[slot].close_reader (slot); + reader_table[slot].used = 0; + } + sentinel = 0; + } +} + + /* Shutdown a reader; that is basically the same as a close but keeps - the handle ready for later use. A apdu_reset_header should be used - to get it active again. */ + the handle ready for later use. A apdu_reset_reader or apdu_connect + should be used to get it active again. */ int apdu_shutdown_reader (int slot) { + int sw; + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) return SW_HOST_NO_DRIVER; + sw = apdu_disconnect (slot); + if (sw) + return sw; if (reader_table[slot].shutdown_reader) return reader_table[slot].shutdown_reader (slot); return SW_HOST_NOT_SUPPORTED; @@ -2383,6 +2581,91 @@ return 0; } + +/* Connect a card. This is used to power up the card and make sure + that an ATR is available. */ +int +apdu_connect (int slot) +{ + int sw; + + if (slot < 0 || slot >= MAX_READER || !reader_table[slot].used ) + return SW_HOST_NO_DRIVER; + + /* Only if the access method provides a connect function we use it. From cvs at cvs.gnupg.org Tue Jul 21 17:38:48 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 21 Jul 2009 17:38:48 +0200 Subject: [svn] GpgOL - r303 - trunk/src Message-ID: Author: wk Date: 2009-07-21 17:38:47 +0200 (Tue, 21 Jul 2009) New Revision: 303 Modified: trunk/src/ChangeLog trunk/src/mapihelp.cpp Log: Release data returned by GetIDsFromNames Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-07-21 11:21:40 UTC (rev 302) +++ trunk/src/ChangeLog 2009-07-21 15:38:47 UTC (rev 303) @@ -1,5 +1,8 @@ 2009-07-21 Werner Koch + * mapihelp.cpp (create_gpgol_tag, get_internetcharsetbody_tag) + (mapi_set_header): Release data returned from GetIDsFromNames. + * engine.h (ENGINE_FLAG_SIGN_FOLLOWS): New macro. * engine.c (engine_encrypt_prepare): Add arg flags. Change callers. * engine-assuan.c (op_assuan_encrypt): Ditto. send PREP_ENCRYPT Modified: trunk/src/mapihelp.cpp =================================================================== --- trunk/src/mapihelp.cpp 2009-07-21 11:21:40 UTC (rev 302) +++ trunk/src/mapihelp.cpp 2009-07-21 15:38:47 UTC (rev 303) @@ -117,21 +117,28 @@ /* {31805ab8-3e92-11dc-879c-00061b031004}: GpgOL custom properties. */ GUID guid = {0x31805ab8, 0x3e92, 0x11dc, {0x87, 0x9c, 0x00, 0x06, 0x1b, 0x03, 0x10, 0x04}}; - + ULONG result; + memset (&mnid, 0, sizeof mnid); mnid.lpguid = &guid; mnid.ulKind = MNID_STRING; mnid.Kind.lpwstrName = name; pmnid = &mnid; hr = message->GetIDsFromNames (1, &pmnid, MAPI_CREATE, &proparr); + if (FAILED (hr)) + proparr = NULL; if (FAILED (hr) || !(proparr->aulPropTag[0] & 0xFFFF0000) ) { log_error ("%s:%s: can't map GpgOL property: hr=%#lx\n", SRCNAME, func, hr); - return 0; + result = 0; } + else + result = (proparr->aulPropTag[0] & 0xFFFF0000); + if (proparr) + MAPIFreeBuffer (proparr); - return (proparr->aulPropTag[0] & 0xFFFF0000); + return result; } @@ -246,6 +253,7 @@ /* {4E3A7680-B77A-11D0-9DA5-00C04FD65685} */ GUID guid = {0x4E3A7680, 0xB77A, 0x11D0, {0x9D, 0xA5, 0x00, 0xC0, 0x4F, 0xD6, 0x56, 0x85}}; + int result; memset (&mnid, 0, sizeof mnid); mnid.lpguid = &guid; @@ -253,17 +261,24 @@ mnid.Kind.lpwstrName = L"Internet Charset Body"; pmnid = &mnid; hr = message->GetIDsFromNames (1, &pmnid, 0, &proparr); + if (FAILED (hr)) + proparr = NULL; if (FAILED (hr) || !(proparr->aulPropTag[0] & 0xFFFF0000) ) { log_error ("%s:%s: can't get the Internet Charset Body property:" " hr=%#lx\n", SRCNAME, __func__, hr); - return -1; + result = -1; } - - if (!(proparr->aulPropTag[0] & 0xFFFF0000)) - return -1; - *r_tag = ((proparr->aulPropTag[0] & 0xFFFF0000) | PT_BINARY); - return 0; + else + { + result = 0; + *r_tag = ((proparr->aulPropTag[0] & 0xFFFF0000) | PT_BINARY); + } + + if (proparr) + MAPIFreeBuffer (proparr); + + return result; } @@ -327,7 +342,8 @@ /* {00020386-0000-0000-C000-000000000046} -> GUID For X-Headers */ GUID guid = {0x00020386, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} }; - + int result; + if (!msg) return -1; @@ -340,21 +356,30 @@ xfree (mnid.Kind.lpwstrName); if (FAILED (hr)) { + pProps = NULL; log_error ("%s:%s: can't get mapping for header `%s': hr=%#lx\n", SRCNAME, __func__, name, hr); - return -1; + result = -1; } - - pv.ulPropTag = (pProps->aulPropTag[0] & 0xFFFF0000) | PT_STRING8; - pv.Value.lpszA = (char *)val; - hr = HrSetOneProp(msg, &pv); - if (hr) + else { - log_error ("%s:%s: can't set header `%s': hr=%#lx\n", - SRCNAME, __func__, name, hr); - return -1; + pv.ulPropTag = (pProps->aulPropTag[0] & 0xFFFF0000) | PT_STRING8; + pv.Value.lpszA = (char *)val; + hr = HrSetOneProp(msg, &pv); + if (hr) + { + log_error ("%s:%s: can't set header `%s': hr=%#lx\n", + SRCNAME, __func__, name, hr); + result = -1; + } + else + result = 0; } - return 0; + + if (pProps) + MAPIFreeBuffer (pProps); + + return result; } From cvs at cvs.gnupg.org Tue Jul 21 17:44:31 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 21 Jul 2009 17:44:31 +0200 Subject: [svn] GnuPG - r5086 - trunk/tools Message-ID: Author: wk Date: 2009-07-21 17:44:30 +0200 (Tue, 21 Jul 2009) New Revision: 5086 Modified: trunk/tools/ChangeLog trunk/tools/gpgsplit.c Log: Fix i18n bug. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2009-07-21 14:30:13 UTC (rev 5085) +++ trunk/tools/ChangeLog 2009-07-21 15:44:30 UTC (rev 5086) @@ -1,3 +1,7 @@ +2009-07-21 Werner Koch + + * gpgsplit.c (my_strusage): Remove i18n stuff. + 2009-07-07 Werner Koch * gpg-connect-agent.c (start_agent): Adjust for changed args of Modified: trunk/tools/gpgsplit.c =================================================================== --- trunk/tools/gpgsplit.c 2009-07-21 14:30:13 UTC (rev 5085) +++ trunk/tools/gpgsplit.c 2009-07-21 15:44:30 UTC (rev 5086) @@ -85,7 +85,7 @@ break; case 13: p = VERSION; break; case 17: p = PRINTABLE_OS_NAME; break; - case 19: p = _("Please report bugs to <@EMAIL@>.\n"); break; + case 19: p = "Please report bugs to <@EMAIL@>.\n"; break; case 1: case 40: p = From cvs at cvs.gnupg.org Wed Jul 22 11:43:10 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 22 Jul 2009 11:43:10 +0200 Subject: [svn] GnuPG - r5087 - trunk/g10 Message-ID: Author: wk Date: 2009-07-22 11:43:10 +0200 (Wed, 22 Jul 2009) New Revision: 5087 Modified: trunk/g10/ChangeLog trunk/g10/gpg.c trunk/g10/tdbio.c trunk/g10/tdbio.h trunk/g10/trustdb.c trunk/g10/trustdb.h Log: Print verbose instructions in case of a corrupted trustdb. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-07-21 15:44:30 UTC (rev 5086) +++ trunk/g10/ChangeLog 2009-07-22 09:43:10 UTC (rev 5087) @@ -1,3 +1,10 @@ +2009-07-22 Werner Koch + + * gpg.c (main) : Show commands to run. + * trustdb.c (how_to_fix_the_trustdb): New. + * tdbio.c (tdbio_invalid): Show commands to re-create the trustdb. + Fixes bug#929. + 2009-07-20 Werner Koch * keygen.c (generate_keypair): Allow Elgamal > 3072 in BOTH mode. Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2009-07-21 15:44:30 UTC (rev 5086) +++ trunk/g10/gpg.c 2009-07-22 09:43:10 UTC (rev 5087) @@ -3372,8 +3372,8 @@ case aGenRandom: case aDeArmor: case aEnArmor: - case aFixTrustDB: break; + case aFixTrustDB: case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break; case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break; default: rc = setup_trustdb(1, trustdb_name ); break; @@ -3895,9 +3895,7 @@ break; case aFixTrustDB: - log_error("this command is not yet implemented.\n"); - log_error("A workaround is to use \"--export-ownertrust\", remove\n"); - log_error("the trustdb file and do an \"--import-ownertrust\".\n" ); + how_to_fix_the_trustdb (); break; case aListTrustPath: Modified: trunk/g10/tdbio.c =================================================================== --- trunk/g10/tdbio.c 2009-07-21 15:44:30 UTC (rev 5086) +++ trunk/g10/tdbio.c 2009-07-22 09:43:10 UTC (rev 5087) @@ -1499,12 +1499,11 @@ } - void tdbio_invalid(void) { - log_error(_( - "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n") ); - g10_exit(2); + log_error (_("Error: The trustdb is corrupted.\n")); + how_to_fix_the_trustdb (); + g10_exit (2); } Modified: trunk/g10/tdbio.h =================================================================== --- trunk/g10/tdbio.h 2009-07-21 15:44:30 UTC (rev 5086) +++ trunk/g10/tdbio.h 2009-07-22 09:43:10 UTC (rev 5087) @@ -111,6 +111,7 @@ int tdbio_search_trust_byfpr(const byte *fingerprint, TRUSTREC *rec ); int tdbio_search_trust_bypk(PKT_public_key *pk, TRUSTREC *rec ); +void tdbio_how_to_fix (void); void tdbio_invalid(void); #endif /*G10_TDBIO_H*/ Modified: trunk/g10/trustdb.c =================================================================== --- trunk/g10/trustdb.c 2009-07-21 15:44:30 UTC (rev 5086) +++ trunk/g10/trustdb.c 2009-07-22 09:43:10 UTC (rev 5087) @@ -408,6 +408,27 @@ } void +how_to_fix_the_trustdb () +{ + const char *name = trustdb_args.dbname; + + if (!name) + name = "trustdb.gpg"; + + log_info (_("You may try to re-create the trustdb using the commands:\n")); + log_info (" cd %s\n", default_homedir ()); + log_info (" gpg2 --export-ownertrust > otrust.tmp\n"); +#ifdef HAVE_W32_SYSTEM + log_info (" del %s\n", name); +#else + log_info (" rm %s\n", name); +#endif + log_info (" gpg2 --import-ownertrust < otrust.tmp\n"); + log_info (_("If that does not work, please consult the manual\n")); +} + + +void init_trustdb() { int level = trustdb_args.level; Modified: trunk/g10/trustdb.h =================================================================== --- trunk/g10/trustdb.h 2009-07-21 15:44:30 UTC (rev 5086) +++ trunk/g10/trustdb.h 2009-07-22 09:43:10 UTC (rev 5087) @@ -44,6 +44,7 @@ void check_trustdb (void); void update_trustdb (void); int setup_trustdb( int level, const char *dbname ); +void how_to_fix_the_trustdb (void); void init_trustdb( void ); void check_trustdb_stale(void); void sync_trustdb( void ); From cvs at cvs.gnupg.org Wed Jul 22 12:24:46 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 22 Jul 2009 12:24:46 +0200 Subject: [svn] GnuPG - r5088 - trunk/doc Message-ID: Author: wk Date: 2009-07-22 12:24:46 +0200 (Wed, 22 Jul 2009) New Revision: 5088 Modified: trunk/doc/ChangeLog trunk/doc/gpg-agent.texi trunk/doc/gpg.texi trunk/doc/gpgsm.texi trunk/doc/sysnotes.texi Log: Give hints on files to backup. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-07-22 09:43:10 UTC (rev 5087) +++ trunk/doc/ChangeLog 2009-07-22 10:24:46 UTC (rev 5088) @@ -1,3 +1,8 @@ +2009-07-22 Werner Koch + + * gpg.texi (GPG Configuration Options): Tell what files to backup. + * sysnotes.texi: Remove some warning notes for W32. + 2009-07-20 Werner Koch * gpg.texi (Operational GPG Commands): Add a note for --send-keys. Modified: trunk/doc/gpg-agent.texi =================================================================== --- trunk/doc/gpg-agent.texi 2009-07-22 09:43:10 UTC (rev 5087) +++ trunk/doc/gpg-agent.texi 2009-07-22 10:24:46 UTC (rev 5088) @@ -514,16 +514,19 @@ two dashes may not be entered and the option may not be abbreviated. This file is also read after a @code{SIGHUP} however only a few options will actually have an effect. This default name may be - changed on the command line (@pxref{option --options}). + changed on the command line (@pxref{option --options}). + You should backup this file. @item trustlist.txt - This is the list of trusted keys. Comment lines, indicated by a leading - hash mark, as well as empty lines are ignored. To mark a key as trusted - you need to enter its fingerprint followed by a space and a capital - letter @code{S}. Colons may optionally be used to separate the bytes of - a fingerprint; this allows to cut and paste the fingerprint from a key - listing output. If the line is prefixed with a @code{!} the key is - explicitly marked as not trusted. + This is the list of trusted keys. You should backup this file. + + Comment lines, indicated by a leading hash mark, as well as empty + lines are ignored. To mark a key as trusted you need to enter its + fingerprint followed by a space and a capital letter @code{S}. Colons + may optionally be used to separate the bytes of a fingerprint; this + allows to cut and paste the fingerprint from a key listing output. If + the line is prefixed with a @code{!} the key is explicitly marked as + not trusted. Here is an example where two keys are marked as ultimately trusted and one as not trusted: @@ -574,16 +577,17 @@ @item sshcontrol This file is used when support for the secure shell agent protocol has -been enabled (@pxref{option --enable-ssh-support}). Only keys present -in this file are used in the SSH protocol. The @command{ssh-add} tool -may be used to add new entries to this file; you may also add them -manually. Comment lines, indicated by a leading hash mark, as well as -empty lines are ignored. An entry starts with optional whitespace, -followed by the keygrip of the key given as 40 hex digits, optionally -followed by the caching TTL in seconds and another optional field for -arbitrary flags. A non-zero TTL overrides the global default as -set by @option{--default-cache-ttl-ssh}. +been enabled (@pxref{option --enable-ssh-support}). Only keys present in +this file are used in the SSH protocol. You should backup this file. +The @command{ssh-add} tool may be used to add new entries to this file; +you may also add them manually. Comment lines, indicated by a leading +hash mark, as well as empty lines are ignored. An entry starts with +optional whitespace, followed by the keygrip of the key given as 40 hex +digits, optionally followed by the caching TTL in seconds and another +optional field for arbitrary flags. A non-zero TTL overrides the global +default as set by @option{--default-cache-ttl-ssh}. + The keygrip may be prefixed with a @code{!} to disable an entry entry. The following example lists exactly one key. Note that keys available @@ -599,7 +603,8 @@ This is the directory where gpg-agent stores the private keys. Each key is stored in a file with the name made up of the keygrip and the - suffix @file{key}. + suffix @file{key}. You should backup all files in this directory + and take great care to keep this backup closed away. @end table Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2009-07-22 09:43:10 UTC (rev 5087) +++ trunk/doc/gpg.texi 2009-07-22 10:24:46 UTC (rev 5088) @@ -485,17 +485,35 @@ a check is needed. To force a run even in batch mode add the option @option{--yes}. + at anchor{option --export-ownertrust} @item --export-ownertrust @opindex export-ownertrust Send the ownertrust values to STDOUT. This is useful for backup purposes as these values are the only ones which can't be re-created from a -corrupted trust DB. +corrupted trustdb. Example: + at c man:.RS + at example + @gpgname{} --export-ownertrust > otrust.txt + at end example + at c man:.RE + @item --import-ownertrust @opindex import-ownertrust Update the trustdb with the ownertrust values stored in @code{files} (or -STDIN if not given); existing values will be overwritten. +STDIN if not given); existing values will be overwritten. In case of a +severely damaged trustdb and if you have a recent backup of the +ownertrust values (e.g. in the file @file{otrust.txt}, you may re-create +the trustdb using these commands: + at c man:.RS + at example + cd ~/.gnupg + rm trustdb.gpg + @gpgname{} --import-ownertrust < otrust.txt + at end example + at c man:.RE + @item --rebuild-keydb-caches @opindex rebuild-keydb-caches When updating from version 1.0.6 to 1.0.7 this command should be used @@ -2614,12 +2632,12 @@ @table @file @item gpg.conf - at cindex gpgsm.conf + at cindex gpg.conf This is the standard configuration file read by @command{@gpgname} on startup. It may contain any valid long option; the leading two dashes may not be entered and the option may not be abbreviated. This default -name may be changed on the command line (@pxref{option - --options}). +name may be changed on the command line (@pxref{option --options}). +You should backup this file. @end table @@ -2639,31 +2657,32 @@ @table @file @item ~/.gnupg/secring.gpg -The secret keyring. +The secret keyring. You should backup this file. @item ~/.gnupg/secring.gpg.lock -and the lock file +The lock file for teh secret keyring. @item ~/.gnupg/pubring.gpg -The public keyring +The public keyring. You should backup this file. @item ~/.gnupg/pubring.gpg.lock -and the lock file +The lock file for the public keyring. @item ~/.gnupg/trustdb.gpg -The trust database +The trust database. There is no need to backup this file; it is better +to backup the ownertrust values (@pxref{option --export-ownertrust}). @item ~/.gnupg/trustdb.gpg.lock -and the lock file +The lock file for the trust database. @item ~/.gnupg/random_seed -used to preserve the internal random pool +A file used to preserve the state of theinternal random pool. @item /usr[/local]/share/gnupg/options.skel -Skeleton options file +The skeleton options file. @item /usr[/local]/lib/gnupg/ -Default location for extensions +Default location for extensions. @end table Modified: trunk/doc/gpgsm.texi =================================================================== --- trunk/doc/gpgsm.texi 2009-07-22 09:43:10 UTC (rev 5087) +++ trunk/doc/gpgsm.texi 2009-07-22 10:24:46 UTC (rev 5088) @@ -734,8 +734,9 @@ startup. It may contain any valid long option; the leading two dashes may not be entered and the option may not be abbreviated. This default name may be changed on the command line (@pxref{option - --options}). + --options}). You should backup this file. + @item policies.txt @cindex policies.txt This is a list of allowed CA policies. This file should list the @@ -743,7 +744,8 @@ lines starting with a hash mark are ignored. Policies missing in this file and not marked as critical in the certificate will print only a warning; certificates with policies marked as critical and not listed -in this file will fail the signature verification. +in this file will fail the signature verification. You should backup +this file. For example, to allow only the policy 2.289.9.9, the file should look like this: @@ -831,7 +833,8 @@ @cindex pubring.kbx This a database file storing the certificates as well as meta information. For debugging purposes the tool @command{kbxutil} may be -used to show the internal structure of this file. +used to show the internal structure of this file. You should backup +this file. @item random_seed @cindex random_seed Modified: trunk/doc/sysnotes.texi =================================================================== --- trunk/doc/sysnotes.texi 2009-07-22 09:43:10 UTC (rev 5087) +++ trunk/doc/sysnotes.texi 2009-07-22 10:24:46 UTC (rev 5088) @@ -60,31 +60,11 @@ @node W32 Notes @section Microsoft Windows Notes -The port to Microsoft Windows based OSes is pretty new and has some -limitations we might remove over time. Note, that we have not yet done -any security audit and you should not use any valuable private key. In -particular, @strong{using it on a box with more than one user, might -lead to a key compromise}. - - at strong{It is quite possible that the current version does not even -build.} - @noindent Current limitations are: @itemize - at item -The @code{LISTKEYS} Assuan command of @command{gpgsm} is not supported. -Using the command line options @option{--list-keys} or - at option{--list-secret-keys} does however work. - at item -No support for CRL checks. By default the option - at option{--disable-crl-checks} has been turned on and the log will show -an appropriate warning message. The reason for this is that the -separate CRL checking daemin (@command{dirmngr}) has not been ported to -W32. - @item @command{gpgconf} does not create backup files, so in case of trouble your configuration file might get lost. @@ -97,10 +77,6 @@ The periodical smartcard status checking done by @command{scdaemon} is not yet supported. - at item -Detached running of the gpg-agent is not directly supported. It needs -to be started in a console and left alone then. - @end itemize From cvs at cvs.gnupg.org Wed Jul 22 15:33:46 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 22 Jul 2009 15:33:46 +0200 Subject: [svn] GnuPG - r5089 - trunk/doc Message-ID: Author: wk Date: 2009-07-22 15:33:46 +0200 (Wed, 22 Jul 2009) New Revision: 5089 Modified: trunk/doc/ChangeLog trunk/doc/debugging.texi trunk/doc/glossary.texi trunk/doc/gpg-agent.texi trunk/doc/gpg.texi trunk/doc/gpgsm.texi trunk/doc/howto-create-a-server-cert.texi trunk/doc/instguide.texi trunk/doc/scdaemon.texi trunk/doc/sysnotes.texi trunk/doc/tools.texi Log: Typo fixes. Fixes bug#1093 Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-07-22 10:24:46 UTC (rev 5088) +++ trunk/doc/ChangeLog 2009-07-22 13:33:46 UTC (rev 5089) @@ -1,5 +1,10 @@ 2009-07-22 Werner Koch + * scdaemon.texi, instguide.texi, gpgsm.texi, sysnotes.texi + * glossary.texi, howto-create-a-server-cert.texi, tools.texi + * gpg-agent.texi, gpg.texi, debugging.texi: Typo fixes. Reported + by Jeroen Schot. Fixes bug#1093. + * gpg.texi (GPG Configuration Options): Tell what files to backup. * sysnotes.texi: Remove some warning notes for W32. Modified: trunk/doc/debugging.texi =================================================================== --- trunk/doc/debugging.texi 2009-07-22 10:24:46 UTC (rev 5088) +++ trunk/doc/debugging.texi 2009-07-22 13:33:46 UTC (rev 5089) @@ -10,7 +10,7 @@ reminiscent to the moth jamming a relay in a Mark II box back in 1947. Most of the problems a merely configuration and user problems but -nevertheless there are the most annoying ones and reponsible for many +nevertheless there are the most annoying ones and responsible for many gray hairs. We try to give some guidelines here on how to identify and solve the problem at hand. @@ -36,7 +36,7 @@ @node kbxutil @subsection Scrutinizing a keybox file -A keybox is a file fomat used to store public keys along with meta +A keybox is a file format used to store public keys along with meta information and indices. The commonly used one is the file @file{pubring.kbx} in the @file{.gnupg} directory. It contains all X.509 certificates as well as OpenPGP keys at footnote{Well, OpenPGP keys @@ -72,10 +72,10 @@ @end example In this example you see that the keybox does not have any OpenPGP keys -but contains 98 X.509 cerificates and a total of 17 keys or certificates -are flagges as ephemeral, meaning that they are only temporary stored +but contains 98 X.509 certificates and a total of 17 keys or certificates +are flagged as ephemeral, meaning that they are only temporary stored (cached) in the keybox and won't get listed using the usual commands -provided by @command{gpgsm} or @command{gpg}. 81 certifcates are stored +provided by @command{gpgsm} or @command{gpg}. 81 certificates are stored in a standard way and directly available from @command{gpgsm}. @noindent @@ -137,7 +137,7 @@ SSH has no way to tell the gpg-agent what terminal or X display it is running on. So when remotely logging into a box where a gpg-agent with SSH support is running, the pinentry will get popped up on whatever -display t he gpg-agent has been started. To solve this problem you may +display the gpg-agent has been started. To solve this problem you may issue the command @smallexample @@ -171,7 +171,7 @@ /usr/local/libexec/gpg-protect-tool --p12-export ~/.gnupg/private-keys-v1.d/@var{foo} >@var{foo}.p12 @end smallexample -(Please adjust the path to @command{gpg-protect-tool} to the approriate +(Please adjust the path to @command{gpg-protect-tool} to the appropriate location). @var{foo} is the name of the key file you picked (it should have the suffix @file{.key}). A Pinentry box will pop up and ask you for the current passphrase of the key and a new passphrase to protect it @@ -205,7 +205,7 @@ The signature is broken. You may try the option @option{--extra-digest-algo SHA256} to workaround the problem. The -number N is the internal algorighm indentifier; for example 8 refers to +number N is the internal algorithm identifier; for example 8 refers to SHA-256. Modified: trunk/doc/glossary.texi =================================================================== --- trunk/doc/glossary.texi 2009-07-22 10:24:46 UTC (rev 5088) +++ trunk/doc/glossary.texi 2009-07-22 13:33:46 UTC (rev 5089) @@ -17,7 +17,7 @@ signature as the date the validation starts and in turn checks that each certificate has been issued within the time frame, the issuing certificate was valid. This allows the verification of signatures after -the the CA's certificate expired. The validation test also required an +the CA's certificate expired. The validation test also required an online check of the certificate status. The chain model is required by the German signature law. See also @emph{Shell model}. @@ -39,7 +39,7 @@ @item OpenPGP A data format used to build a PKI and to exchange encrypted or signed messages. In contrast to X.509, OpenPGP also includes the -message format but does not explicilty demand a specific PKI. However +message format but does not explicitly demand a specific PKI. However any kind of PKI may be build upon the OpenPGP protocol. @item Keygrip @@ -60,7 +60,7 @@ @item Shell model The standard model for validation of certificates under X.509. At the -time of the verification all certifciates must be valid and not expired. +time of the verification all certificates must be valid and not expired. See also @emph{Chain mode}. Modified: trunk/doc/gpg-agent.texi =================================================================== --- trunk/doc/gpg-agent.texi 2009-07-22 10:24:46 UTC (rev 5088) +++ trunk/doc/gpg-agent.texi 2009-07-22 13:33:46 UTC (rev 5089) @@ -61,7 +61,7 @@ sure that only one is running: @command{gpg-agent} uses an environment variable to inform clients about the communication parameters. You can write the content of this environment variable to a file so that you can -test for a running agent. Here is an example using Bourne shell synax: +test for a running agent. Here is an example using Bourne shell syntax: @smallexample gpg-agent --daemon --enable-ssh-support \ @@ -727,7 +727,7 @@ protocol. To identify a key we use a thing called keygrip which is the SHA-1 hash -of an canoncical encoded S-Expression of the the public key as used in +of an canonical encoded S-Expression of the public key as used in Libgcrypt. For the purpose of this interface the keygrip is given as a hex string. The advantage of using this and not the hash of a certificate is that it will be possible to use the same keypair for @@ -855,7 +855,7 @@ PKSIGN @end example -Options are not yet defined, but my later be used to choosen among +Options are not yet defined, but my later be used to choose among different algorithms. The agent does then some checks, asks for the passphrase and as a result the server returns the signature as an SPKI like S-expression in "D" lines: @@ -957,7 +957,7 @@ @node Agent IMPORT @subsection Importing a Secret Key -This operation is not yet supportted by GpgAgent. Specialized tools +This operation is not yet supported by GpgAgent. Specialized tools are to be used for this. There is no actual need because we can expect that secret keys @@ -976,7 +976,7 @@ Actually we do not import a Root Cert but provide a way to validate any piece of data by storing its Hash along with a description and -an identifier in the PSE. Here is the interface desription: +an identifier in the PSE. Here is the interface description: @example ISTRUSTED @@ -1017,7 +1017,7 @@ @end example The first item on a line is the hexified fingerprint where MD5 -ingerprints are @code{00} padded to the left and the second item is a +fingerprints are @code{00} padded to the left and the second item is a flag to indicate the type of key (so that gpg is able to only take care of PGP keys). P = OpenPGP, S = S/MIME. A client should ignore the rest of the line, so that we can extend the format in the future. @@ -1114,7 +1114,7 @@ @subsection Ask for confirmation This command may be used to ask for a simple confirmation by -presenting a text and 2 bottonts: Okay and Cancel. +presenting a text and 2 buttons: Okay and Cancel. @example GET_CONFIRMATION @var{description} @@ -1164,7 +1164,7 @@ @end example This command is used to interactively change the passphrase of the key -indentified by the hex string @var{keygrip}. +identified by the hex string @var{keygrip}. @node Agent UPDATESTARTUPTTY Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2009-07-22 10:24:46 UTC (rev 5088) +++ trunk/doc/gpg.texi 2009-07-22 13:33:46 UTC (rev 5089) @@ -328,7 +328,7 @@ the "sig" tag (and thus before the flags described above for @option{--list-sigs}). A "!" indicates that the signature has been successfully verified, a "-" denotes a bad signature and a "%" is used -if an error occured while checking the signature (e.g. a non supported +if an error occurred while checking the signature (e.g. a non supported algorithm). @ifclear gpgone @@ -2660,7 +2660,7 @@ The secret keyring. You should backup this file. @item ~/.gnupg/secring.gpg.lock -The lock file for teh secret keyring. +The lock file for the secret keyring. @item ~/.gnupg/pubring.gpg The public keyring. You should backup this file. @@ -2676,7 +2676,7 @@ The lock file for the trust database. @item ~/.gnupg/random_seed -A file used to preserve the state of theinternal random pool. +A file used to preserve the state of the internal random pool. @item /usr[/local]/share/gnupg/options.skel The skeleton options file. @@ -2710,7 +2710,7 @@ @item PINENTRY_USER_DATA This value is passed via gpg-agent to pinentry. It is useful to convey -extra information to a custom pinentry +extra information to a custom pinentry. @item COLUMNS @itemx LINES @@ -2719,11 +2719,11 @@ @item LANGUAGE Apart from its use by GNU, it is used in the W32 version to override the -language selection done through the Registry. If used and set to a a +language selection done through the Registry. If used and set to a valid and available language name (@var{langid}), the file with the translation is loaded from @code{@var{gpgdir}/gnupg.nls/@var{langid}.mo}. Here @var{gpgdir} is the -directory out of which the gpg binary has been laoded. If it can't be +directory out of which the gpg binary has been loaded. If it can't be loaded the Registry is tried and as last resort the native Windows locale system is used. Modified: trunk/doc/gpgsm.texi =================================================================== --- trunk/doc/gpgsm.texi 2009-07-22 10:24:46 UTC (rev 5088) +++ trunk/doc/gpgsm.texi 2009-07-22 13:33:46 UTC (rev 5089) @@ -29,7 +29,7 @@ @mansect description @command{gpgsm} is a tool similar to @command{gpg} to provide digital -encryption and signing servicesd on X.509 certificates and the CMS +encryption and signing services on X.509 certificates and the CMS protocol. It is mainly used as a backend for S/MIME mail processing. @command{gpgsm} includes a full features certificate management and complies with all rules defined for the German Sphinx project. @@ -82,7 +82,7 @@ @item --help, -h @opindex help -Print a usage message summarizing the most usefule command-line options. +Print a usage message summarizing the most useful command-line options. Note that you cannot abbreviate this command. @item --warranty @@ -123,7 +123,7 @@ @item --verify @opindex verify Check a signature file for validity. Depending on the arguments a -detached signatrue may also be checked. +detached signature may also be checked. @item --server @opindex server @@ -134,7 +134,7 @@ Behave as a Dirmngr client issuing the request @var{command} with the optional list of @var{args}. The output of the Dirmngr is printed stdout. Please note that file names given as arguments should have an -absulte file name (i.e. commencing with @code{/} because they are +absolute file name (i.e. commencing with @code{/} because they are passed verbatim to the Dirmngr and the working directory of the Dirmngr might not be the same as the one of this client. Currently it is not possible to pass data via stdin to the Dirmngr. @var{command} @@ -219,7 +219,7 @@ @opindex keydb-clear-some-cert-flags This is a debugging aid to reset certain flags in the key database which are used to cache certain certificate stati. It is especially -useful if a bad CRL or a weird running OCSP reponder did accidently +useful if a bad CRL or a weird running OCSP responder did accidentally revoke certificate. There is no security issue with this command because @command{gpgsm} always make sure that the validity of a certificate is checked right before it is used. @@ -286,7 +286,7 @@ @node GPGSM Options @section Option Summary - at command{GPGSM} comes features a bunch ofoptions to control the exact behaviour + at command{GPGSM} comes features a bunch of options to control the exact behaviour and to change the default configuration. @menu @@ -304,7 +304,7 @@ @node Configuration Options @subsection How to change the configuration -These options are used to change the configuraton and are usually found +These options are used to change the configuration and are usually found in the option file. @table @gnupgtabopt @@ -335,7 +335,7 @@ @opindex agent-program Specify an agent program to be used for secret key operations. The default value is the @file{/usr/local/bin/gpg-agent}. This is only used -as a fallback when the envrionment variable @code{GPG_AGENT_INFO} is not +as a fallback when the environment variable @code{GPG_AGENT_INFO} is not set or a running agent can't be connected. @item --dirmngr-program @var{file} @@ -408,7 +408,7 @@ @opindex force-crl-refresh Tell the dirmngr to reload the CRL for each request. For better performance, the dirmngr will actually optimize this by suppressing -the loading for short time intervalls (e.g. 30 minutes). This option +the loading for short time intervals (e.g. 30 minutes). This option is useful to make sure that a fresh CRL is available for certificates hold in the keybox. The suggested way of doing this is by using it along with the option @option{--with-validation} for a key listing @@ -430,7 +430,7 @@ @opindex auto-issuer-key-retrieve If a required certificate is missing while validating the chain of certificates, try to load that certificate from an external location. -This usually means that Dirmngr is employed t search for the +This usually means that Dirmngr is employed to search for the certificate. Note that this option makes a "web bug" like behavior possible. LDAP server operators can see which keys you request, so by sending you a message signed by a brand new key (which you naturally @@ -537,7 +537,7 @@ When used along with --import, a validation of the certificate to import is done and only imported if it succeeds the test. Note that -this does not affect an already available cwertificate in the DB. +this does not affect an already available certificate in the DB. This option is therefore useful to simply verify a certificate. @@ -592,7 +592,7 @@ @opindex extra-digest-algo Sometimes signatures are broken in that they announce a different digest algorithm than actually used. @command{gpgsm} uses a one-pass data -processing model and thus needs to rely on the announcde digest +processing model and thus needs to rely on the announced digest algorithms to properly hash the data. As a workaround this option may be used to tell gpg to also hash the data using the algorithm @var{name}; this slows processing down a little bit but allows to verify @@ -605,7 +605,7 @@ @opindex faked-system-time This option is only useful for testing; it sets the system time back or forth to @var{epoch} which is the number of seconds elapsed since the year -1970. Alternativly @var{epoch} may be given as a full ISO time string +1970. Alternatively @var{epoch} may be given as a full ISO time string (e.g. "20070924T154812"). @item --with-ephemeral-keys @@ -662,7 +662,7 @@ trace Assuan protocol @end table -Note, that all flags set using this option may get overriden by +Note, that all flags set using this option may get overridden by @code{--debug-level}. @item --debug-all @@ -685,7 +685,7 @@ @item --debug-ignore-expiration @opindex debug-ignore-expiration This is actually not a debugging option but only useful as such. It -lets @command{gpgsm} ignore all notAfter dates, this is used by the regresssion +lets @command{gpgsm} ignore all notAfter dates, this is used by the regression tests. @item --fixed-passphrase @var{string} @@ -820,10 +820,10 @@ @c man:.RE Note that on larger installations, it is useful to put predefined files into the directory @file{/etc/skel/.gnupg/} so that newly created users -start up with a working configuration. For existing users the a small +start up with a working configuration. For existing users a small helper script is provided to create these files (@pxref{addgnupghome}). -For internal purposes gpgsm creates and maintaines a few other files; +For internal purposes gpgsm creates and maintains a few other files; they all live in in the current home directory (@pxref{option --homedir}). Only @command{gpgsm} may modify these files. @@ -839,7 +839,7 @@ @item random_seed @cindex random_seed This content of this file is used to maintain the internal state of the -random number generator accross invocations. The same file is used by +random number generator across invocations. The same file is used by other programs of this software too. @item S.gpg-agent @@ -848,7 +848,7 @@ not set, @command{gpgsm} will first try to connect to this socket for accessing @command{gpg-agent} before starting a new @command{gpg-agent} instance. Under Windows this socket (which in reality be a plain file -describing a regular TCP litening port) is the standard way of +describing a regular TCP listening port) is the standard way of connecting the @command{gpg-agent}. @end table @@ -894,7 +894,7 @@ It is very important to understand the semantics used with signature verification. Checking a signature is not as simple as it may sound and -so the ooperation si a bit complicated. In mosted cases it is required +so the operation is a bit complicated. In most cases it is required to look at several status lines. Here is a table of all cases a signed message may have: @@ -919,7 +919,7 @@ @item The signature is invalid This means that the signature verification failed (this is an indication -of af a transfer error, a programm error or tampering with the message). +of af a transfer error, a program error or tampering with the message). @command{gpgsm} issues one of these status codes sequences: @table @code @item @code{BADSIG} @@ -971,7 +971,7 @@ @node GPGSM ENCRYPT @subsection Encrypting a Message -Before encrytion can be done the recipient must be set using the +Before encryption can be done the recipient must be set using the command: @example @@ -1086,7 +1086,7 @@ OUTPUT. With @code{--detached}, a detached signature is created (surprise). -The key used for signining is the default one or the one specified in +The key used for signing is the default one or the one specified in the configuration file. To get finer control over the keys, it is possible to use the command @@ -1226,7 +1226,7 @@ @end example is used. The data is expected on the file descriptor set with the - at code{INPUT} command. Certain checks are performend on the + at code{INPUT} command. Certain checks are performed on the certificate. Note that the code will also handle PKCS#12 files and import private keys; a helper program is used for that. Modified: trunk/doc/howto-create-a-server-cert.texi =================================================================== --- trunk/doc/howto-create-a-server-cert.texi 2009-07-22 10:24:46 UTC (rev 5088) +++ trunk/doc/howto-create-a-server-cert.texi 2009-07-22 13:33:46 UTC (rev 5089) @@ -251,7 +251,7 @@ To make actual use of the certificate you need to install it on your -server. Server software usally expects a PKCS\#12 file with key and +server. Server software usually expects a PKCS\#12 file with key and certificate. To create such a file, run: @cartouche Modified: trunk/doc/instguide.texi =================================================================== --- trunk/doc/instguide.texi 2009-07-22 10:24:46 UTC (rev 5088) +++ trunk/doc/instguide.texi 2009-07-22 13:33:46 UTC (rev 5089) @@ -36,15 +36,15 @@ @itemize @item Use the list which comes with GnuPG. However this list only -contains a few root certifciates. Most installations will need more. +contains a few root certificates. Most installations will need more. @item Let @command{gpgsm} ask you whether you want to insert a new root certificate. To enable this feature you need to set the option @option{allow-mark-trusted} into @file{gpg-agent.conf}. In general it is not a good idea to do it this way. Checking whether a root -certificate is really trustworthy requires a decsions, which casual -usuers are not up to. Thus, by default this option is not enabled. +certificate is really trustworthy requires decisions, which casual +users are not up to. Thus, by default this option is not enabled. @item Manually maintain the list of trusted root certificates. For a multi Modified: trunk/doc/scdaemon.texi =================================================================== --- trunk/doc/scdaemon.texi 2009-07-22 10:24:46 UTC (rev 5088) +++ trunk/doc/scdaemon.texi 2009-07-22 13:33:46 UTC (rev 5089) @@ -69,7 +69,7 @@ @item --help, -h @opindex help -Print a usage message summarizing the most usefule command-line options. +Print a usage message summarizing the most useful command-line options. Not that you can abbreviate this command. @item --dump-options @@ -91,7 +91,7 @@ @item --daemon @opindex daemon Run the program in the background. This option is required to prevent -it from being accidently running in the background. +it from being accidentally running in the background. @end table @@ -267,7 +267,7 @@ PIN again after the next power up. Note that with the current version of Scdaemon the card is powered -down immediatley at the next timer tick for any value of @var{n} other +down immediately at the next timer tick for any value of @var{n} other than 0. @@ -342,7 +342,7 @@ @node PKCS#15 Card @subsection The PKCS#15 card application ``p15'' -This is common fraqmework for smart card applications. It is used by +This is common framework for smart card applications. It is used by @command{gpgsm}. @node Geldkarte Card @@ -413,7 +413,7 @@ The SC-Daemon should be started by the system to provide access to external tokens. Using Smartcards on a multi-user system does not -make much sense expcet for system services, but in this case no +make much sense expect for system services, but in this case no regular user accounts are hosted on the machine. A client connects to the SC-Daemon by connecting to the socket named @@ -421,7 +421,7 @@ @var{/etc/scdaemon.conf} Each connection acts as one session, SC-Daemon takes care of -syncronizing access to a token between sessions. +synchronizing access to a token between sessions. @menu * Scdaemon SERIALNO:: Return the serial number. @@ -457,7 +457,7 @@ SERIALNO @end example -Return the serial number of the card using a status reponse like: +Return the serial number of the card using a status response like: @example S SERIALNO D27600000000000000000000 0 @@ -505,7 +505,7 @@ This function is used to read a certificate identified by @var{hexified_certid} from the card. With OpenPGP cards the keyid - at code{OpenPGP.3} may be used to rad the certticate of version 2 cards. + at code{OpenPGP.3} may be used to rad the certificate of version 2 cards. @node Scdaemon READKEY @@ -584,7 +584,7 @@ WRITEKEY [--force] @var{keyid} @end example -This command is used to store a secret key on a a smartcard. The +This command is used to store a secret key on a smartcard. The allowed keyids depend on the currently selected smartcard application. The actual keydata is requested using the inquiry @code{KEYDATA} and need to be provided without any protection. With @@ -592,7 +592,7 @@ overwritten. The key data is expected to be the usual canonical encoded S-expression. -A PIN will be requested in most saes. This however depends on the +A PIN will be requested in most cases. This however depends on the actual card application. @@ -687,7 +687,7 @@ @end example Using the option @code{--more} handles the card status word MORE_DATA -(61xx) and concatenate all reponses to one block. +(61xx) and concatenate all responses to one block. Using the option @code{--exlen} the returned APDU may use extended length up to N bytes. If N is not given a default value is used Modified: trunk/doc/sysnotes.texi =================================================================== --- trunk/doc/sysnotes.texi 2009-07-22 10:24:46 UTC (rev 5088) +++ trunk/doc/sysnotes.texi 2009-07-22 13:33:46 UTC (rev 5089) @@ -6,7 +6,7 @@ @chapter Notes pertaining to certain OSes. GnuPG has been developed on GNU/Linux systems and is know to work on -almost all Free OSes. All modern POSIX systems should be supproted +almost all Free OSes. All modern POSIX systems should be supported right now, however there are probably a lot of smaller glitches we need to fix first. The major problem areas are: @@ -14,14 +14,14 @@ @item For logging to sockets and other internal operations the @code{fopencookie} function (@code{funopen} under *BSD) is used. This -is a very convient function which makes it possible to create outputs in +is a very convenient function which makes it possible to create outputs in a structures and easy maintainable way. The drawback however is that most proprietary OSes don't support this function. At g10 at tie{}Code we have looked into several ways on how to overcome this limitation but no sufficiently easy and maintainable way has been found. Porting @emph{glibc} to a general POSIX system is of course an option and would make writing portable software much easier; this it has not yet been -done and the system administrator wouldneed to cope with the GNU +done and the system administrator would need to cope with the GNU specific admin things in addition to the generic ones of his system. We have now settled to use explicit stdio wrappers with a functionality @@ -30,19 +30,19 @@ This means that on systems not supporting either @code{funopen} or @code{fopencookie}, logging to a socket won't work, prompts are not -formatted as pretty as theyshould be and @command{gpgsm}'s +formatted as pretty as they should be and @command{gpgsm}'s @code{LISTKEYS} Assuan command does not work. @item We are planning to use file descriptor passing for interprocess communication. This will allow us save a lot of resources and improve performance of certain operations a lot. Systems not supporting this -won't gain these benefits but we try to keep them working the satndard +won't gain these benefits but we try to keep them working the standard way as it is done today. @item We require more or less full POSIX compatibility. This has been -arround for 15 years now and thus we don't believe it makes sense to +around for 15 years now and thus we don't believe it makes sense to support non POSIX systems anymore. Well, we of course the usual workarounds for near POSIX systems well be applied. Modified: trunk/doc/tools.texi =================================================================== --- trunk/doc/tools.texi 2009-07-22 10:24:46 UTC (rev 5088) +++ trunk/doc/tools.texi 2009-07-22 13:33:46 UTC (rev 5089) @@ -334,7 +334,7 @@ Some fields contain strings that are described to be @emph{percent-escaped}. Such strings need to be de-escaped before their content can be presented to the user. A percent-escaped string -is de-escaped by replacing all occurences of @code{%XY} by the byte +is de-escaped by replacing all occurrences of @code{%XY} by the byte that has the hexadecimal value @code{XY}. @code{X} and @code{Y} are from the set @code{0-9a-f}. @@ -477,7 +477,7 @@ The command @code{--check-programs} is similar to @code{--list-components} but works on backend programs and not on -components. It runs each program to test wether it is installed and +components. It runs each program to test whether it is installed and runnable. This also includes a syntax check of all config file options of the program. @@ -514,17 +514,17 @@ config file is syntactically okay. @item cfgfile -If an error occured in the configuraion file (as indicated by a false +If an error occurred in the configuration file (as indicated by a false value in the field @code{okay}), this field has the name of the failing configuration file. It is @emph{percent-escaped}. @item line -If an error occured in the configuration file, this field has the line +If an error occurred in the configuration file, this field has the line number of the failing statement in the configuration file. It is an @emph{unsigned number}. @item error -If an error occured in the configuration file, this field has the error +If an error occurred in the configuration file, this field has the error text of the failing statement in the configuration file. It is @emph{percent-escaped} and @emph{localized}. @@ -747,7 +747,7 @@ @item value This field is defined only for options. Its format is that of an @emph{option argument}. If it is empty, then the option is not -explicitely set in the current configuration, and the default applies +explicitly set in the current configuration, and the default applies (if any). Otherwise, it contains the current value of the option. Note that this field is also meaningful if the option itself does not take a real argument (in this case, it contains the number of times @@ -865,7 +865,7 @@ @end table @noindent -Unknown record typs should be ignored. Note that there is intentionally +Unknown record types should be ignored. Note that there is intentionally no feature to change the global option file through @command{gpgconf}. @@ -947,7 +947,7 @@ @end ifset @mansect description -This is a simple tool to interactivly generate a certificate request +This is a simple tool to interactively generate a certificate request which will be printed to stdout. @manpause @@ -1089,7 +1089,7 @@ The @command{gpg-connect-agent} is a utility to communicate with a running @command{gpg-agent}. It is useful to check out the commands gpg-agent provides using the Assuan interface. It might also be useful -for scripting simple applications. Inputis expected at stdin and out +for scripting simple applications. Input is expected at stdin and out put gets printed to stdout. It is very similar to running @command{gpg-agent} in server mode; but @@ -1192,7 +1192,7 @@ @item /let @var{name} @var{value} Set the variable @var{name} to @var{value}. Variables are only substituted on the input if the @command{/subst} has been used. -Variables are referenced by prefixing the name with a dollr sign and +Variables are referenced by prefixing the name with a dollar sign and optionally include the name in curly braces. The rules for a valid name are identically to those of the standard bourne shell. This is not yet enforced but may be in the future. When used with curly braces no @@ -1237,14 +1237,14 @@ @item unpercent @var{args} @itemx unpercent+ @var{args} -Remove percent style ecaping from @var{args}. Note that @code{%00} +Remove percent style escaping from @var{args}. Note that @code{%00} terminates the string implicitly. The string to be converted are the entire arguments right behind the delimiting space of the function name. @code{unpercent+} also maps plus signs to a spaces. @item percent @var{args} @itemx percent+ @var{args} -Escape the @var{args} using percent style ecaping. Tabs, formfeeds, +Escape the @var{args} using percent style escaping. Tabs, formfeeds, linefeeds, carriage returns and colons are escaped. @code{percent+} also maps spaces to plus signs. @@ -1290,9 +1290,9 @@ @item /datafile @var{name} Write all data lines from the server to the file @var{name}. The file -is opened for writing and created if it does not exists. An existsing +is opened for writing and created if it does not exists. An existing file is first truncated to 0. The data written to the file fully -decoded. Using a singel dash for @var{name} writes to stdout. The +decoded. Using a single dash for @var{name} writes to stdout. The file is kept open until a new file is set using this command or this command is used without an argument. @@ -1466,7 +1466,7 @@ For decryption vice versa. @var{CLASS} describes the calling conventions of the external tool. -Currently it must be given as @samp{confucius}. @var{PROGRAM} is the +Currently it must be given as @samp{confucius}. @var{PROGRAM} is the full filename of that external tool. For the class @samp{confucius} the option @option{--keyfile} is @@ -1499,7 +1499,7 @@ @item --log-file @var{file} @opindex log-file Append all logging output to @var{file}. Default is to write logging -informaton to STDERR. +information to STDERR. @end table From cvs at cvs.gnupg.org Wed Jul 22 18:08:59 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 22 Jul 2009 18:08:59 +0200 Subject: [svn] GnuPG - r5090 - trunk/g10 Message-ID: Author: wk Date: 2009-07-22 18:08:58 +0200 (Wed, 22 Jul 2009) New Revision: 5090 Modified: trunk/g10/ChangeLog trunk/g10/call-agent.c Log: Emit CARDCTRL status lines. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-07-22 13:33:46 UTC (rev 5089) +++ trunk/g10/ChangeLog 2009-07-22 16:08:58 UTC (rev 5090) @@ -1,5 +1,13 @@ 2009-07-22 Werner Koch + * call-agent.c (agent_learn): Use a direct SCD command. + (did_early_card_test): New. + (start_agent): Perform an early test for the card. Add arg FOR_CARD. + (status_sc_op_failure): New. + (agent_scd_setattr, agent_scd_writekey, agent_scd_genkey) + (agent_scd_pksign, agent_scd_pkdecrypt, agent_scd_change_pin) + (agent_scd_checkpin): Call new function. + * gpg.c (main) : Show commands to run. * trustdb.c (how_to_fix_the_trustdb): New. * tdbio.c (tdbio_invalid): Show commands to re-create the trustdb. Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2009-07-22 13:33:46 UTC (rev 5089) +++ trunk/g10/call-agent.c 2009-07-22 16:08:58 UTC (rev 5090) @@ -39,12 +39,14 @@ #include "asshelp.h" #include "sysutils.h" #include "call-agent.h" +#include "status.h" #ifndef DBG_ASSUAN # define DBG_ASSUAN 1 #endif static assuan_context_t agent_ctx = NULL; +static int did_early_card_test; struct cipher_parm_s { @@ -75,35 +77,104 @@ }; +static int learn_status_cb (void *opaque, const char *line); + + +/* If RC is not 0, write an appropriate status message. */ +static void +status_sc_op_failure (int rc) +{ + switch (gpg_err_code (rc)) + { + case 0: + break; + case GPG_ERR_CANCELED: + write_status_text (STATUS_SC_OP_FAILURE, "1"); + break; + case GPG_ERR_BAD_PIN: + write_status_text (STATUS_SC_OP_FAILURE, "2"); + break; + default: + write_status (STATUS_SC_OP_FAILURE); + break; + } +} + + + + /* Try to connect to the agent via socket or fork it off and work by pipes. Handle the server's initial greeting */ static int -start_agent (void) +start_agent (int for_card) { int rc; + /* Fixme: We need a context for each thread or serialize the access + to the agent. */ if (agent_ctx) - return 0; /* Fixme: We need a context for each thread or serialize - the access to the agent. */ + rc = 0; + else + { + rc = start_new_gpg_agent (&agent_ctx, + GPG_ERR_SOURCE_DEFAULT, + opt.homedir, + opt.agent_program, + opt.lc_ctype, opt.lc_messages, + opt.session_env, + opt.verbose, DBG_ASSUAN, + NULL, NULL); + if (!rc) + { + /* Tell the agent that we support Pinentry notifications. + No error checking so that it will work also with older + agents. */ + assuan_transact (agent_ctx, "OPTION allow-pinentry-notify", + NULL, NULL, NULL, NULL, NULL, NULL); + } + } - rc = start_new_gpg_agent (&agent_ctx, - GPG_ERR_SOURCE_DEFAULT, - opt.homedir, - opt.agent_program, - opt.lc_ctype, opt.lc_messages, - opt.session_env, - opt.verbose, DBG_ASSUAN, - NULL, NULL); - if (!rc) + if (!rc && for_card && !did_early_card_test) { - /* Tell the agent that we support Pinentry notifications. No - error checking so that it will work also with older - agents. */ - assuan_transact (agent_ctx, "OPTION allow-pinentry-notify", - NULL, NULL, NULL, NULL, NULL, NULL); + /* Request the serial number of the card for an early test. */ + struct agent_card_info_s info; + + memset (&info, 0, sizeof info); + rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp", + NULL, NULL, NULL, NULL, + learn_status_cb, &info); + if (rc) + { + switch (gpg_err_code (rc)) + { + case GPG_ERR_NOT_SUPPORTED: + case GPG_ERR_NO_SCDAEMON: + write_status_text (STATUS_CARDCTRL, "6"); + break; + default: + write_status_text (STATUS_CARDCTRL, "4"); + log_info ("selecting openpgp failed: %s\n", gpg_strerror (rc)); + break; + } + } + + if (!rc && is_status_enabled () && info.serialno) + { + char *buf; + + buf = xasprintf ("3 %s", info.serialno); + write_status_text (STATUS_CARDCTRL, buf); + xfree (buf); + } + + agent_release_card_info (&info); + + if (!rc) + did_early_card_test = 1; } + return rc; } @@ -345,12 +416,12 @@ { int rc; - rc = start_agent (); + rc = start_agent (1); if (rc) return rc; memset (info, 0, sizeof *info); - rc = assuan_transact (agent_ctx, "LEARN --send", + rc = assuan_transact (agent_ctx, "SCD LEARN --force", dummy_data_cb, NULL, default_inq_cb, NULL, learn_status_cb, info); /* Also try to get the key attributes. */ @@ -377,7 +448,7 @@ return gpg_error (GPG_ERR_TOO_LARGE); stpcpy (stpcpy (line, "SCD GETATTR "), name); - rc = start_agent (); + rc = start_agent (1); if (rc) return rc; @@ -427,12 +498,14 @@ } *p = 0; - rc = start_agent (); - if (rc) - return rc; + rc = start_agent (1); + if (!rc) + { + rc = assuan_transact (agent_ctx, line, NULL, NULL, + default_inq_cb, NULL, NULL, NULL); + } - rc = assuan_transact (agent_ctx, line, NULL, NULL, - default_inq_cb, NULL, NULL, NULL); + status_sc_op_failure (rc); return rc; } @@ -467,7 +540,7 @@ char line[ASSUAN_LINELENGTH]; struct writecert_parm_s parms; - rc = start_agent (); + rc = start_agent (1); if (rc) return rc; @@ -517,7 +590,7 @@ (void)serialno; - rc = start_agent (); + rc = start_agent (1); if (rc) return rc; @@ -532,6 +605,7 @@ rc = assuan_transact (agent_ctx, line, NULL, NULL, inq_writekey_parms, &parms, NULL, NULL); + status_sc_op_failure (rc); return rc; } @@ -601,7 +675,7 @@ (void)serialno; - rc = start_agent (); + rc = start_agent (1); if (rc) return rc; @@ -622,6 +696,7 @@ NULL, NULL, default_inq_cb, NULL, scd_genkey_cb, info); + status_sc_op_failure (rc); return rc; } @@ -653,7 +728,7 @@ *r_buf = NULL; *r_buflen = 0; - rc = start_agent (); + rc = start_agent (1); if (rc) return rc; @@ -692,11 +767,12 @@ if (rc) { xfree (get_membuf (&data, &len)); - return rc; } - *r_buf = get_membuf (&data, r_buflen); + else + *r_buf = get_membuf (&data, r_buflen); - return 0; + status_sc_op_failure (rc); + return rc; } @@ -717,7 +793,7 @@ size_t len; *r_buf = NULL; - rc = start_agent (); + rc = start_agent (1); if (rc) return rc; @@ -751,13 +827,16 @@ if (rc) { xfree (get_membuf (&data, &len)); - return rc; } - *r_buf = get_membuf (&data, r_buflen); - if (!*r_buf) - return gpg_error (GPG_ERR_ENOMEM); + else + { + *r_buf = get_membuf (&data, r_buflen); + if (!*r_buf) + rc = gpg_error (GPG_ERR_ENOMEM); + } - return 0; + status_sc_op_failure (rc); + return rc; } @@ -773,7 +852,7 @@ size_t len; *r_buf = NULL; - rc = start_agent (); + rc = start_agent (1); if (rc) return rc; @@ -821,7 +900,7 @@ reset = "--reset"; chvno %= 100; - rc = start_agent (); + rc = start_agent (1); if (rc) return rc; @@ -829,6 +908,7 @@ line[DIM(line)-1] = 0; rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, NULL, NULL, NULL); + status_sc_op_failure (rc); return rc; } @@ -842,15 +922,17 @@ int rc; char line[ASSUAN_LINELENGTH]; - rc = start_agent (); + rc = start_agent (1); if (rc) return rc; snprintf (line, DIM(line)-1, "SCD CHECKPIN %s", serialno); line[DIM(line)-1] = 0; - return assuan_transact (agent_ctx, line, - NULL, NULL, - default_inq_cb, NULL, NULL, NULL); + rc = assuan_transact (agent_ctx, line, + NULL, NULL, + default_inq_cb, NULL, NULL, NULL); + status_sc_op_failure (rc); + return rc; } @@ -887,7 +969,7 @@ *r_passphrase = NULL; - rc = start_agent (); + rc = start_agent (0); if (rc) return rc; @@ -958,7 +1040,7 @@ if (!cache_id || !*cache_id) return 0; - rc = start_agent (); + rc = start_agent (0); if (rc) return rc; From cvs at cvs.gnupg.org Wed Jul 22 19:21:48 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 22 Jul 2009 19:21:48 +0200 Subject: [svn] GnuPG - r5091 - trunk/g10 Message-ID: Author: wk Date: 2009-07-22 19:21:47 +0200 (Wed, 22 Jul 2009) New Revision: 5091 Modified: trunk/g10/ChangeLog trunk/g10/call-agent.c trunk/g10/call-agent.h trunk/g10/card-util.c Log: Make use of the card's extended capabilities. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-07-22 16:08:58 UTC (rev 5090) +++ trunk/g10/ChangeLog 2009-07-22 17:21:47 UTC (rev 5091) @@ -1,5 +1,11 @@ 2009-07-22 Werner Koch + * card-util.c (generate_card_keys): Ask for off-card keys only if + the card supports it. + (get_info_for_key_operation): Read EXTCAP. + (card_store_subkey): Check for non matching sizes. + + * call-agent.h (struct agent_card_info_s): Add field EXTCAP. * call-agent.c (agent_learn): Use a direct SCD command. (did_early_card_test): New. (start_agent): Perform an early test for the card. Add arg FOR_CARD. @@ -7,6 +13,7 @@ (agent_scd_setattr, agent_scd_writekey, agent_scd_genkey) (agent_scd_pksign, agent_scd_pkdecrypt, agent_scd_change_pin) (agent_scd_checkpin): Call new function. + (learn_status_cb): Parse KEY_TIME and EXTCAP. * gpg.c (main) : Show commands to run. * trustdb.c (how_to_fix_the_trustdb): New. Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2009-07-22 16:08:58 UTC (rev 5090) +++ trunk/g10/call-agent.c 2009-07-22 17:21:47 UTC (rev 5091) @@ -366,6 +366,30 @@ xfree (buf); } } + else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen)) + { + char *p, *p2, *buf; + int abool; + + buf = p = unescape_status_string (line); + if (buf) + { + for (p = strtok (buf, " "); p; p = strtok (NULL, " ")) + { + p2 = strchr (p, '='); + if (p2) + { + *p2++ = 0; + abool = (*p2 == '1'); + if (!strcmp (p, "ki")) + parm->extcap.ki = abool; + else if (!strcmp (p, "aac")) + parm->extcap.aac = abool; + } + } + xfree (buf); + } + } else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen)) { int no = atoi (line); @@ -380,6 +404,20 @@ else if (no == 3) parm->fpr3valid = unhexify_fpr (line, parm->fpr3); } + else if (keywordlen == 8 && !memcmp (keyword, "KEY-TIME", keywordlen)) + { + int no = atoi (line); + while (* line && !spacep (line)) + line++; + while (spacep (line)) + line++; + if (no == 1) + parm->fpr1time = strtoul (line, NULL, 10); + else if (no == 2) + parm->fpr2time = strtoul (line, NULL, 10); + else if (no == 3) + parm->fpr3time = strtoul (line, NULL, 10); + } else if (keywordlen == 6 && !memcmp (keyword, "CA-FPR", keywordlen)) { int no = atoi (line); Modified: trunk/g10/call-agent.h =================================================================== --- trunk/g10/call-agent.h 2009-07-22 16:08:58 UTC (rev 5090) +++ trunk/g10/call-agent.h 2009-07-22 17:21:47 UTC (rev 5091) @@ -57,6 +57,10 @@ int algo; /* Algorithm identifier. */ unsigned int nbits; /* Supported keysize. */ } key_attr[3]; + struct { + unsigned int ki:1; /* Key import available. */ + unsigned int aac:1; /* Algorithm attributes are changeable. */ + } extcap; }; struct agent_card_genkey_s { Modified: trunk/g10/card-util.c =================================================================== --- trunk/g10/card-util.c 2009-07-22 16:08:58 UTC (rev 5090) +++ trunk/g10/card-util.c 2009-07-22 17:21:47 UTC (rev 5091) @@ -1156,6 +1156,8 @@ rc = agent_scd_getattr ("CHV-STATUS", info); if (!rc) rc = agent_scd_getattr ("DISP-NAME", info); + if (!rc) + rc = agent_scd_getattr ("EXTCAP", info); if (rc) log_error (_("error getting current key info: %s\n"), gpg_strerror (rc)); return rc; @@ -1261,21 +1263,27 @@ if (get_info_for_key_operation (&info)) return; + if (info.extcap.ki) + { #if GNUPG_MAJOR_VERSION == 1 - { - char *answer=cpr_get("cardedit.genkeys.backup_enc", - _("Make off-card backup of encryption key? (Y/n) ")); + char *answer; - want_backup=answer_is_yes_no_default(answer,1); - cpr_kill_prompt(); - xfree(answer); - } + + answer = cpr_get ("cardedit.genkeys.backup_enc", + _("Make off-card backup of encryption key? (Y/n) ")); + + want_backup=answer_is_yes_no_default(answer,1); + cpr_kill_prompt(); + xfree(answer); #else - want_backup = cpr_get_answer_is_yes - ( "cardedit.genkeys.backup_enc", + want_backup = cpr_get_answer_is_yes + ( "cardedit.genkeys.backup_enc", _("Make off-card backup of encryption key? (Y/n) ")); /*FIXME: we need answer_is_yes_no_default()*/ #endif + } + else + want_backup = 0; if ( (info.fpr1valid && !fpr_is_zero (info.fpr1)) || (info.fpr2valid && !fpr_is_zero (info.fpr2)) @@ -1383,7 +1391,9 @@ size_t n; const char *s; int allow_keyno[3]; + unsigned int nbits; + assert (node->pkt->pkttype == PKT_SECRET_KEY || node->pkt->pkttype == PKT_SECRET_SUBKEY); sk = node->pkt->pkt.secret_key; @@ -1391,10 +1401,18 @@ if (get_info_for_key_operation (&info)) return 0; + if (!info.extcap.ki) + { + tty_printf ("The card does not support the import of keys\n"); + tty_printf ("\n"); + goto leave; + } + show_card_key_info (&info); - if (!is_RSA (sk->pubkey_algo) - || (!info.is_v2 && nbits_from_sk (sk) != 1024) ) + nbits = nbits_from_sk (sk); + + if (!is_RSA (sk->pubkey_algo) || (!info.is_v2 && nbits != 1024) ) { tty_printf ("You may only store a 1024 bit RSA key on the card\n"); tty_printf ("\n"); @@ -1427,8 +1445,17 @@ keyno = *answer? atoi(answer): 0; xfree(answer); if (keyno >= 1 && keyno <= 3 && allow_keyno[keyno-1]) - break; /* Okay. */ - tty_printf(_("Invalid selection.\n")); + { + if (info.is_v2 && !info.extcap.aac + && info.key_attr[keyno-1].nbits != nbits) + { + tty_printf ("Key does not match the card's capability.\n"); + } + else + break; /* Okay. */ + } + else + tty_printf(_("Invalid selection.\n")); } if (replace_existing_key_p (&info, keyno)) From cvs at cvs.gnupg.org Thu Jul 23 10:00:40 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 23 Jul 2009 10:00:40 +0200 Subject: [svn] GnuPG - r5092 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2009-07-23 10:00:39 +0200 (Thu, 23 Jul 2009) New Revision: 5092 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/cardglue.c branches/STABLE-BRANCH-1-4/g10/cardglue.h branches/STABLE-BRANCH-1-4/g10/gpg.c branches/STABLE-BRANCH-1-4/g10/tdbio.c branches/STABLE-BRANCH-1-4/g10/trustdb.c branches/STABLE-BRANCH-1-4/g10/trustdb.h Log: Parse EXTCAP lines from the card. Change messages for a corrupt trustdb. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-22 17:21:47 UTC (rev 5091) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-23 08:00:39 UTC (rev 5092) @@ -1,3 +1,15 @@ +2009-07-23 Werner Koch + + * trustdb.c (how_to_fix_the_trustdb): New. + * tdbio.c (tdbio_invalid): Print hints on how to fix the trustdb. + * gpg.c (main) : Print hints. + +2009-07-22 Werner Koch + + * cardglue.h (struct agent_card_info_s): Add field EXTCAP. + * cardglue.c (agent_learn): Read KEY-ATTR. + (learn_status_cb): Parse EXTCAP. + 2009-07-21 Werner Koch * app-common.h, app-openpgp.c, iso7816.c, iso7816.h, apdu.c, Modified: branches/STABLE-BRANCH-1-4/g10/cardglue.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/cardglue.c 2009-07-22 17:21:47 UTC (rev 5091) +++ branches/STABLE-BRANCH-1-4/g10/cardglue.c 2009-07-23 08:00:39 UTC (rev 5092) @@ -1,5 +1,5 @@ /* cardglue.c - mainly dispatcher for card related functions. - * Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc. + * Copyright (C) 2003, 2004, 2005, 2006, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -382,7 +382,7 @@ if (!ctx) return NULL; - /* Request the serialbnumber of the card. If we get + /* Request the serialnumber of the card. If we get NOT_SUPPORTED or NO_SCDAEMON back, the gpg-agent either has disabled scdaemon or it can't be used. We close the connection in this case and use our own code. This may happen if just the @@ -438,7 +438,7 @@ if (app) goto ready; /* Yes, there is a agent with a usable card, go that way. */ if (scd_available) - return NULL; /* agent avilabale but card problem. */ + return NULL; /* Agent available but card problem. */ } @@ -770,6 +770,30 @@ xfree (buf); } } + else if (keywordlen == 6 && !memcmp (keyword, "EXTCAP", keywordlen)) + { + char *p, *p2, *buf; + int abool; + + buf = p = unescape_status_string (line); + if (buf) + { + for (p = strtok (buf, " "); p; p = strtok (NULL, " ")) + { + p2 = strchr (p, '='); + if (p2) + { + *p2++ = 0; + abool = (*p2 == '1'); + if (!strcmp (p, "ki")) + parm->extcap.ki = abool; + else if (!strcmp (p, "aac")) + parm->extcap.aac = abool; + } + } + xfree (buf); + } + } else if (keywordlen == 7 && !memcmp (keyword, "KEY-FPR", keywordlen)) { int no = atoi (line); @@ -876,6 +900,9 @@ } } + if (!rc) + agent_scd_getattr ("KEY-ATTR", info); + return rc; } Modified: branches/STABLE-BRANCH-1-4/g10/cardglue.h =================================================================== --- branches/STABLE-BRANCH-1-4/g10/cardglue.h 2009-07-22 17:21:47 UTC (rev 5091) +++ branches/STABLE-BRANCH-1-4/g10/cardglue.h 2009-07-23 08:00:39 UTC (rev 5092) @@ -69,6 +69,10 @@ int algo; /* Algorithm identifier. */ unsigned int nbits; /* Supported keysize. */ } key_attr[3]; + struct { + unsigned int ki:1; /* Key import available. */ + unsigned int aac:1; /* Algorithm attributes are changeable. */ + } extcap; }; struct agent_card_genkey_s { Modified: branches/STABLE-BRANCH-1-4/g10/gpg.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/gpg.c 2009-07-22 17:21:47 UTC (rev 5091) +++ branches/STABLE-BRANCH-1-4/g10/gpg.c 2009-07-23 08:00:39 UTC (rev 5092) @@ -3343,8 +3343,8 @@ case aGenRandom: case aDeArmor: case aEnArmor: - case aFixTrustDB: break; + case aFixTrustDB: case aExportOwnerTrust: rc = setup_trustdb( 0, trustdb_name ); break; case aListTrustDB: rc = setup_trustdb( argc? 1:0, trustdb_name ); break; default: rc = setup_trustdb(1, trustdb_name ); break; @@ -3874,9 +3874,7 @@ break; case aFixTrustDB: - log_error("this command is not yet implemented.\n"); - log_error("A workaround is to use \"--export-ownertrust\", remove\n"); - log_error("the trustdb file and do an \"--import-ownertrust\".\n" ); + how_to_fix_the_trustdb (); break; case aListTrustPath: Modified: branches/STABLE-BRANCH-1-4/g10/tdbio.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/tdbio.c 2009-07-22 17:21:47 UTC (rev 5091) +++ branches/STABLE-BRANCH-1-4/g10/tdbio.c 2009-07-23 08:00:39 UTC (rev 5092) @@ -1499,9 +1499,9 @@ void tdbio_invalid(void) { - log_error(_( - "the trustdb is corrupted; please run \"gpg --fix-trustdb\".\n") ); - g10_exit(2); + log_error (_("Error: The trustdb is corrupted.\n")); + how_to_fix_the_trustdb (); + g10_exit (2); } /* Modified: branches/STABLE-BRANCH-1-4/g10/trustdb.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/trustdb.c 2009-07-22 17:21:47 UTC (rev 5091) +++ branches/STABLE-BRANCH-1-4/g10/trustdb.c 2009-07-23 08:00:39 UTC (rev 5092) @@ -412,6 +412,27 @@ } void +how_to_fix_the_trustdb () +{ + const char *name = trustdb_args.dbname; + + if (!name) + name = "trustdb.gpg"; + + log_info (_("You may try to re-create the trustdb using the commands:\n")); + log_info (" cd %s\n", default_homedir ()); + log_info (" gpg2 --export-ownertrust > otrust.tmp\n"); +#ifdef HAVE_W32_SYSTEM + log_info (" del %s\n", name); +#else + log_info (" rm %s\n", name); +#endif + log_info (" gpg2 --import-ownertrust < otrust.tmp\n"); + log_info (_("If that does not work, please consult the manual\n")); +} + + +void init_trustdb() { int level = trustdb_args.level; Modified: branches/STABLE-BRANCH-1-4/g10/trustdb.h =================================================================== --- branches/STABLE-BRANCH-1-4/g10/trustdb.h 2009-07-22 17:21:47 UTC (rev 5091) +++ branches/STABLE-BRANCH-1-4/g10/trustdb.h 2009-07-23 08:00:39 UTC (rev 5092) @@ -45,6 +45,7 @@ void check_trustdb (void); void update_trustdb (void); int setup_trustdb( int level, const char *dbname ); +void how_to_fix_the_trustdb (void); void init_trustdb( void ); void check_trustdb_stale(void); void sync_trustdb( void ); From cvs at cvs.gnupg.org Thu Jul 23 17:02:00 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 23 Jul 2009 17:02:00 +0200 Subject: [svn] gpg-error - r217 - in trunk: . src Message-ID: Author: wk Date: 2009-07-23 17:02:00 +0200 (Thu, 23 Jul 2009) New Revision: 217 Added: trunk/doc/ Modified: trunk/AUTHORS trunk/ChangeLog trunk/NEWS trunk/src/err-codes.h.in Log: Add new code GPG_ERR_NOT_ENABLED Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-07-17 01:53:19 UTC (rev 216) +++ trunk/ChangeLog 2009-07-23 15:02:00 UTC (rev 217) @@ -1,3 +1,7 @@ +2009-07-23 Werner Koch + + * src/err-codes.h.in: Add GPG_ERR_NOT_ENABLED. + 2009-07-17 Marcus Brinkmann * src/mkerrnos.awk: Output code to cause WSA Errors to be found Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2009-07-17 01:53:19 UTC (rev 216) +++ trunk/AUTHORS 2009-07-23 15:02:00 UTC (rev 217) @@ -2,7 +2,8 @@ Maintainer: Marcus Brinkmann Bug reports: bug-gnupg at gnupg.org Security related bug reports: security at gnupg.org -License: LGPLv2.1+ +License (library): LGPLv2.1+ +License (tools): GPLv2+ with exception g10 Code GmbH Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-07-17 01:53:19 UTC (rev 216) +++ trunk/NEWS 2009-07-23 15:02:00 UTC (rev 217) @@ -3,6 +3,7 @@ * Interface changes relative to the 1.7 release: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + GPG_ERR_NOT_ENABLED NEW Noteworthy changes in version 1.7 (2008-11-26) Modified: trunk/src/err-codes.h.in =================================================================== --- trunk/src/err-codes.h.in 2009-07-17 01:53:19 UTC (rev 216) +++ trunk/src/err-codes.h.in 2009-07-23 15:02:00 UTC (rev 217) @@ -208,7 +208,8 @@ 176 GPG_ERR_NOT_OPERATIONAL Not operational 177 GPG_ERR_NO_PASSPHRASE No passphrase given 178 GPG_ERR_NO_PIN No PIN given -# 179 to 198 are free to be used. +179 GPG_ERR_NOT_ENABLED Not enabled +# 180 to 198 are free to be used. 199 GPG_ERR_UNFINISHED Operation not yet finished 200 GPG_ERR_BUFFER_TOO_SHORT Buffer too short From cvs at cvs.gnupg.org Thu Jul 23 17:18:59 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 23 Jul 2009 17:18:59 +0200 Subject: [svn] GnuPG - r5093 - in trunk: common doc g10 sm Message-ID: Author: wk Date: 2009-07-23 17:18:58 +0200 (Thu, 23 Jul 2009) New Revision: 5093 Modified: trunk/common/ChangeLog trunk/common/audit.c trunk/common/audit.h trunk/common/util.h trunk/doc/ChangeLog trunk/doc/DETAILS trunk/doc/help.txt trunk/g10/keygen.c trunk/sm/ChangeLog trunk/sm/certchain.c Log: Print status of CRL checks in the audit log. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-07-23 08:00:39 UTC (rev 5092) +++ trunk/common/ChangeLog 2009-07-23 15:18:58 UTC (rev 5093) @@ -1,3 +1,9 @@ +2009-07-23 Werner Koch + + * util.h (GPG_ERR_NOT_ENABLED): New. + * audit.h (enum): Add AUDIT_CRL_CHECK. + * audit.c (proc_type_verify): Show CRL check result. + 2009-07-06 Werner Koch * get-passphrase.c (struct agentargs): Add SESSION_ENV and remove Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-07-23 08:00:39 UTC (rev 5092) +++ trunk/doc/ChangeLog 2009-07-23 15:18:58 UTC (rev 5093) @@ -1,3 +1,7 @@ +2009-07-23 Werner Koch + + * help.txt (gpgsm.crl-problem): New. + 2009-07-22 Werner Koch * scdaemon.texi, instguide.texi, gpgsm.texi, sysnotes.texi Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-07-23 08:00:39 UTC (rev 5092) +++ trunk/sm/ChangeLog 2009-07-23 15:18:58 UTC (rev 5093) @@ -1,3 +1,7 @@ +2009-07-23 Werner Koch + + * certchain.c (is_cert_still_valid): Emit AUDIT_CRL_CHECK. + 2009-07-07 Werner Koch * server.c (command_has_option): New. Modified: trunk/common/audit.c =================================================================== --- trunk/common/audit.c 2009-07-23 08:00:39 UTC (rev 5092) +++ trunk/common/audit.c 2009-07-23 15:18:58 UTC (rev 5093) @@ -251,8 +251,8 @@ } /* Add a new event to the audit log. If CTX is NULL, this function - does nothing. This version also adds the result of the oepration - to the log.. */ + does nothing. This version also adds the result of the operation + to the log. */ void audit_log_ok (audit_ctx_t ctx, audit_event_t event, gpg_error_t err) { @@ -479,6 +479,8 @@ oktext = _("|audit-log-result|Not supported"); else if (!strcmp (oktext, "no-cert")) oktext = _("|audit-log-result|No certificate"); + else if (!strcmp (oktext, "disabled")) + oktext = _("|audit-log-result|Not enabled"); else if (!strcmp (oktext, "error")) oktext = _("|audit-log-result|Error"); else @@ -923,10 +925,32 @@ } /* Show result of the CRL/OCSP check. */ - writeout_li (ctx, "-", "%s", _("CRL/OCSP check of certificates")); - /* add_helptag (ctx, "gpgsm.ocsp-problem"); */ + item = find_next_log_item (ctx, loopitem, + AUDIT_CRL_CHECK, AUDIT_NEW_SIG); + if (item) + { + const char *ok; + switch (gpg_err_code (item->err)) + { + case 0: ok = "good"; break; + case GPG_ERR_CERT_REVOKED: ok = "bad"; break; + case GPG_ERR_NOT_ENABLED: ok = "disabled"; break; + case GPG_ERR_NO_CRL_KNOWN: + ok = _("no CRL found for certificate"); + break; + case GPG_ERR_CRL_TOO_OLD: + ok = _("the available CRL is too old"); + break; + default: ok = gpg_strerror (item->err); break; + } + + writeout_li (ctx, ok, "%s", _("CRL/OCSP check of certificates")); + if (item->err + && gpg_err_code (item->err) != GPG_ERR_CERT_REVOKED + && gpg_err_code (item->err) != GPG_ERR_NOT_ENABLED) + add_helptag (ctx, "gpgsm.crl-problem"); + } - leave_li (ctx); } while ((loopitem = find_next_log_item (ctx, loopitem, AUDIT_NEW_SIG, 0))); Modified: trunk/common/audit.h =================================================================== --- trunk/common/audit.h 2009-07-23 08:00:39 UTC (rev 5092) +++ trunk/common/audit.h 2009-07-23 15:18:58 UTC (rev 5093) @@ -139,6 +139,9 @@ /* Tells whether the root certificate is trusted. This event is emmited durcing chain validation. */ + AUDIT_CRL_CHECK, /* err */ + /* Tells the status of a CRL or OCSP check. */ + AUDIT_GOT_RECIPIENTS, /* int */ /* Records the number of recipients to be used for encryption. This includes the recipients set by --encrypt-to but records 0 Modified: trunk/common/util.h =================================================================== --- trunk/common/util.h 2009-07-23 08:00:39 UTC (rev 5092) +++ trunk/common/util.h 2009-07-23 15:18:58 UTC (rev 5093) @@ -25,6 +25,11 @@ #include /* We need errno. */ #include /* We need gpg_error_t. */ +/* Add error codes available only in newer versions of libgpg-error. */ +#ifndef GPG_ERR_NOT_ENABLED +#define GPG_ERR_NOT_ENABLED 179 +#endif + /* Hash function used with libksba. */ #define HASH_FNC ((void (*)(void *, const void*,size_t))gcry_md_write) Modified: trunk/doc/DETAILS =================================================================== --- trunk/doc/DETAILS 2009-07-23 08:00:39 UTC (rev 5092) +++ trunk/doc/DETAILS 2009-07-23 15:18:58 UTC (rev 5093) @@ -628,13 +628,13 @@ This is used to control smartcard operations. Defined values for WHAT are: 1 = Request insertion of a card. Serialnumber may be given - to request a specific card. - 2 = Request removal of a card. + to request a specific card. Used by gpg 1.4 w/o scdaemon. + 2 = Request removal of a card. Used by gpg 1.4 w/o scdaemon. 3 = Card with serialnumber detected 4 = No card available. 5 = No card reader available + 6 = No card support available - PLAINTEXT This indicates the format of the plaintext that is about to be written. The format is a 1 byte hex code that shows the Modified: trunk/doc/help.txt =================================================================== --- trunk/doc/help.txt 2009-07-23 08:00:39 UTC (rev 5092) +++ trunk/doc/help.txt 2009-07-23 15:18:58 UTC (rev 5093) @@ -357,9 +357,15 @@ your system administrator whether you should trust this certificate. +.gpgsm.crl-problem +# This tex is displayed by the audit log for problems with +# the CRL or OCSP checking. +Depending on your configuration a problem retrieving the CRL or +performing an OCSP check occurred. There are a great variety of +reasons why this did not work. Check the manual for possible +solutions. - # Local variables: # mode: default-generic # coding: utf-8 Modified: trunk/g10/keygen.c =================================================================== --- trunk/g10/keygen.c 2009-07-23 08:00:39 UTC (rev 5092) +++ trunk/g10/keygen.c 2009-07-23 15:18:58 UTC (rev 5093) @@ -1759,7 +1759,7 @@ } -/* Ask for the key size. ALGO is the algorithjm. If PRIMARY_KEYSIZE +/* Ask for the key size. ALGO is the algorithm. If PRIMARY_KEYSIZE is not 0, the function asks for the size of the encryption subkey. */ static unsigned Modified: trunk/sm/certchain.c =================================================================== --- trunk/sm/certchain.c 2009-07-23 08:00:39 UTC (rev 5092) +++ trunk/sm/certchain.c 2009-07-23 15:18:58 UTC (rev 5093) @@ -889,11 +889,17 @@ gpg_error_t err; if (opt.no_crl_check && !ctrl->use_ocsp) - return 0; + { + audit_log_ok (ctrl->audit, AUDIT_CRL_CHECK, + gpg_error (GPG_ERR_NOT_ENABLED)); + return 0; + } err = gpgsm_dirmngr_isvalid (ctrl, subject_cert, issuer_cert, force_ocsp? 2 : !!ctrl->use_ocsp); + audit_log_ok (ctrl->audit, AUDIT_CRL_CHECK, err); + if (err) { if (!lm) From cvs at cvs.gnupg.org Thu Jul 23 20:28:55 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Thu, 23 Jul 2009 20:28:55 +0200 Subject: [svn] GnuPG - r5094 - in trunk: doc g10 Message-ID: Author: dshaw Date: 2009-07-23 20:28:54 +0200 (Thu, 23 Jul 2009) New Revision: 5094 Modified: trunk/doc/ChangeLog trunk/doc/gpg.texi trunk/g10/ChangeLog trunk/g10/keyserver.c Log: Try a DNS-SD lookup to find a domain-specific LDAP server before resorting to keys.{domain}. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-07-23 15:18:58 UTC (rev 5093) +++ trunk/doc/ChangeLog 2009-07-23 18:28:54 UTC (rev 5094) @@ -1,3 +1,8 @@ +2009-07-23 David Shaw + + * gpg.texi (GPG Configuration Options): LDAP uses DNS-SD to locate + a server before falling back to keys.{domain}. + 2009-07-23 Werner Koch * help.txt (gpgsm.crl-problem): New. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-07-23 15:18:58 UTC (rev 5093) +++ trunk/g10/ChangeLog 2009-07-23 18:28:54 UTC (rev 5094) @@ -1,3 +1,8 @@ +2009-07-23 David Shaw + + * keyserver.c (keyserver_import_ldap): Try a DNS-SD lookup to find + a domain-specific LDAP server before resorting to keys.{domain}. + 2009-07-22 Werner Koch * card-util.c (generate_card_keys): Ask for off-card keys only if Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2009-07-23 15:18:58 UTC (rev 5093) +++ trunk/doc/gpg.texi 2009-07-23 18:28:54 UTC (rev 5094) @@ -1376,8 +1376,9 @@ Locate a key using DNS PKA. @item ldap -Locate a key using the PGP Universal method of checking - at samp{ldap://keys.(thedomain)}. +Using DNS Service Discovery, check the domain in question for any LDAP +keyservers to use. If this fails, attempt to locate the key using the +PGP Universal method of checking @samp{ldap://keys.(thedomain)}. @item keyserver Locate a key using whatever keyserver is defined using the Modified: trunk/g10/keyserver.c =================================================================== --- trunk/g10/keyserver.c 2009-07-23 15:18:58 UTC (rev 5093) +++ trunk/g10/keyserver.c 2009-07-23 18:28:54 UTC (rev 5094) @@ -42,6 +42,9 @@ #include "util.h" #include "dns-cert.h" #include "pka.h" +#ifdef USE_DNS_SRV +#include "srv.h" +#endif #ifdef HAVE_W32_SYSTEM /* It seems Vista doesn't grok X_OK and so fails access() tests. @@ -2125,18 +2128,20 @@ return rc; } -/* Use the PGP Universal trick of asking ldap://keys.(maildomain) for - the key. */ +/* Import a key by name using LDAP */ int keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len) { char *domain; struct keyserver_spec *keyserver; strlist_t list=NULL; - int rc; + int rc,hostlen=1; +#ifdef USE_DNS_SRV + struct srventry *srvlist=NULL; + int srvcount,i; + char srvname[MAXDNAME]; +#endif - append_to_strlist(&list,name); - /* Parse out the domain */ domain=strrchr(name,'@'); if(!domain) @@ -2145,16 +2150,48 @@ domain++; keyserver=xmalloc_clear(sizeof(struct keyserver_spec)); + keyserver->scheme=xstrdup("ldap"); + keyserver->host=xmalloc(1); + keyserver->host[0]='\0'; - keyserver->scheme=xstrdup("ldap"); - keyserver->host=xmalloc(5+strlen(domain)+1); - strcpy(keyserver->host,"keys."); +#ifdef USE_DNS_SRV + snprintf(srvname,MAXDNAME,"_pgpkey-ldap._tcp.%s",domain); + + srvcount=getsrv(srvname,&srvlist); + + for(i=0;ihost=xrealloc(keyserver->host,hostlen); + + strcat(keyserver->host,srvlist[i].target); + + if(srvlist[i].port!=389) + { + char port[7]; + + hostlen+=6; /* a colon, plus 5 digits (unsigned 16-bit value) */ + keyserver->host=xrealloc(keyserver->host,hostlen); + + snprintf(port,7,":%u",srvlist[i].port); + strcat(keyserver->host,port); + } + + strcat(keyserver->host," "); + } + + free(srvlist); +#endif + + /* If all else fails, do the PGP Universal trick of + ldap://keys.(domain) */ + + hostlen+=5+strlen(domain); + keyserver->host=xrealloc(keyserver->host,hostlen); + strcat(keyserver->host,"keys."); strcat(keyserver->host,domain); - keyserver->uri=xmalloc(strlen(keyserver->scheme)+ - 3+strlen(keyserver->host)+1); - strcpy(keyserver->uri,keyserver->scheme); - strcat(keyserver->uri,"://"); - strcat(keyserver->uri,keyserver->host); + + append_to_strlist(&list,name); rc=keyserver_work(KS_GETNAME,list,NULL,0,fpr,fpr_len,keyserver); From cvs at cvs.gnupg.org Thu Jul 23 20:56:57 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Thu, 23 Jul 2009 20:56:57 +0200 Subject: [svn] GnuPG - r5095 - trunk/common Message-ID: Author: dshaw Date: 2009-07-23 20:56:56 +0200 (Thu, 23 Jul 2009) New Revision: 5095 Modified: trunk/common/ChangeLog trunk/common/srv.c Log: * srv.c (getsrv): Fix type-punning warning. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-07-23 18:28:54 UTC (rev 5094) +++ trunk/common/ChangeLog 2009-07-23 18:56:56 UTC (rev 5095) @@ -1,3 +1,7 @@ +2009-07-23 David Shaw + + * srv.c (getsrv): Fix type-punning warning. + 2009-07-23 Werner Koch * util.h (GPG_ERR_NOT_ENABLED): New. Modified: trunk/common/srv.c =================================================================== --- trunk/common/srv.c 2009-07-23 18:28:54 UTC (rev 5094) +++ trunk/common/srv.c 2009-07-23 18:56:56 UTC (rev 5095) @@ -59,6 +59,7 @@ int r,srvcount=0; unsigned char *pt,*emsg; u16 count,dlen; + HEADER *header=(HEADER *)answer; *list=NULL; @@ -66,8 +67,7 @@ if(r2048) return -1; - if((((HEADER *)answer)->rcode)==NOERROR && - (count=ntohs(((HEADER *)answer)->ancount))) + if(header->rcode==NOERROR && (count=ntohs(header->ancount))) { int i,rc; From cvs at cvs.gnupg.org Thu Jul 23 21:05:19 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Thu, 23 Jul 2009 21:05:19 +0200 Subject: [svn] GnuPG - r5096 - branches/STABLE-BRANCH-1-4/util Message-ID: Author: dshaw Date: 2009-07-23 21:05:19 +0200 (Thu, 23 Jul 2009) New Revision: 5096 Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog branches/STABLE-BRANCH-1-4/util/srv.c Log: * srv.c (getsrv): Fix type-punning warning. (main): Allow testing any SRV. Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-07-23 18:56:56 UTC (rev 5095) +++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-07-23 19:05:19 UTC (rev 5096) @@ -1,3 +1,8 @@ +2009-07-23 David Shaw + + * srv.c (getsrv): Fix type-punning warning. + (main): Allow testing any SRV. + 2009-07-21 Werner Koch * ttyio.c (tty_printf): Replace vasprintf by xtryasprintf. Modified: branches/STABLE-BRANCH-1-4/util/srv.c =================================================================== --- branches/STABLE-BRANCH-1-4/util/srv.c 2009-07-23 18:56:56 UTC (rev 5095) +++ branches/STABLE-BRANCH-1-4/util/srv.c 2009-07-23 19:05:19 UTC (rev 5096) @@ -58,6 +58,7 @@ int r,srvcount=0; unsigned char *pt,*emsg; u16 count,dlen; + HEADER *header=(HEADER *)answer; *list=NULL; @@ -65,8 +66,7 @@ if(r2048) return -1; - if((((HEADER *)answer)->rcode)==NOERROR && - (count=ntohs(((HEADER *)answer)->ancount))) + if(header->rcode==NOERROR && (count=ntohs(header->ancount))) { int i,rc; @@ -234,7 +234,14 @@ struct srventry *srv; int rc,i; - rc=getsrv("_hkp._tcp.wwwkeys.pgp.net",&srv); + if(argc!=2) + { + fprintf(stderr,"%s {srv}\n",argv[0]); + fprintf(stderr," Try %s _hkp._tcp.wwwkeys.pgp.net\n",argv[0]); + return 1; + } + + rc=getsrv(argv[1],&srv); printf("Count=%d\n\n",rc); for(i=0;i Author: dshaw Date: 2009-07-23 21:50:25 +0200 (Thu, 23 Jul 2009) New Revision: 5097 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/keyserver.c Log: * keyserver.c (keyserver_import_ldap): Try a DNS-SD lookup to find a domain-specific LDAP server before resorting to keys.{domain}. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-23 19:05:19 UTC (rev 5096) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-23 19:50:25 UTC (rev 5097) @@ -1,3 +1,8 @@ +2009-07-23 David Shaw + + * keyserver.c (keyserver_import_ldap): Try a DNS-SD lookup to find + a domain-specific LDAP server before resorting to keys.{domain}. + 2009-07-23 Werner Koch * trustdb.c (how_to_fix_the_trustdb): New. Modified: branches/STABLE-BRANCH-1-4/g10/keyserver.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keyserver.c 2009-07-23 19:05:19 UTC (rev 5096) +++ branches/STABLE-BRANCH-1-4/g10/keyserver.c 2009-07-23 19:50:25 UTC (rev 5097) @@ -38,6 +38,9 @@ #include "trustdb.h" #include "keyserver-internal.h" #include "util.h" +#ifdef USE_DNS_SRV +#include "srv.h" +#endif #ifdef HAVE_W32_SYSTEM /* It seems Vista doesn't grok X_OK and so fails access() tests. @@ -2093,18 +2096,20 @@ return rc; } -/* Use the PGP Universal trick of asking ldap://keys.(maildomain) for - the key. */ +/* Import a key by name using LDAP */ int keyserver_import_ldap(const char *name,unsigned char **fpr,size_t *fpr_len) { char *domain; struct keyserver_spec *keyserver; STRLIST list=NULL; - int rc; + int rc,hostlen=1; +#ifdef USE_DNS_SRV + struct srventry *srvlist=NULL; + int srvcount,i; + char srvname[MAXDNAME]; +#endif - append_to_strlist(&list,name); - /* Parse out the domain */ domain=strrchr(name,'@'); if(!domain) @@ -2113,16 +2118,48 @@ domain++; keyserver=xmalloc_clear(sizeof(struct keyserver_spec)); + keyserver->scheme=xstrdup("ldap"); + keyserver->host=xmalloc(1); + keyserver->host[0]='\0'; - keyserver->scheme=xstrdup("ldap"); - keyserver->host=xmalloc(5+strlen(domain)+1); - strcpy(keyserver->host,"keys."); +#ifdef USE_DNS_SRV + snprintf(srvname,MAXDNAME,"_pgpkey-ldap._tcp.%s",domain); + + srvcount=getsrv(srvname,&srvlist); + + for(i=0;ihost=xrealloc(keyserver->host,hostlen); + + strcat(keyserver->host,srvlist[i].target); + + if(srvlist[i].port!=389) + { + char port[7]; + + hostlen+=6; /* a colon, plus 5 digits (unsigned 16-bit value) */ + keyserver->host=xrealloc(keyserver->host,hostlen); + + snprintf(port,7,":%u",srvlist[i].port); + strcat(keyserver->host,port); + } + + strcat(keyserver->host," "); + } + + free(srvlist); +#endif + + /* If all else fails, do the PGP Universal trick of + ldap://keys.(domain) */ + + hostlen+=5+strlen(domain); + keyserver->host=xrealloc(keyserver->host,hostlen); + strcat(keyserver->host,"keys."); strcat(keyserver->host,domain); - keyserver->uri=xmalloc(strlen(keyserver->scheme)+ - 3+strlen(keyserver->host)+1); - strcpy(keyserver->uri,keyserver->scheme); - strcat(keyserver->uri,"://"); - strcat(keyserver->uri,keyserver->host); + + append_to_strlist(&list,name); rc=keyserver_work(KS_GETNAME,list,NULL,0,fpr,fpr_len,keyserver); From cvs at cvs.gnupg.org Fri Jul 24 13:01:18 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 24 Jul 2009 13:01:18 +0200 Subject: [svn] GnuPG - r5098 - trunk/scd Message-ID: Author: wk Date: 2009-07-24 13:01:17 +0200 (Fri, 24 Jul 2009) New Revision: 5098 Modified: trunk/scd/ChangeLog trunk/scd/ccid-driver.c Log: Workaround for SCR3320 Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-07-23 19:50:25 UTC (rev 5097) +++ trunk/scd/ChangeLog 2009-07-24 11:01:17 UTC (rev 5098) @@ -1,3 +1,7 @@ +2009-07-24 Werner Koch + + * ccid-driver.c (parse_ccid_descriptor): Enable hack for SCR 3320. + 2009-07-21 Werner Koch * ccid-driver.c [HAVE_PTH]: Include pth.h. Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2009-07-23 19:50:25 UTC (rev 5097) +++ trunk/scd/ccid-driver.c 2009-07-24 11:01:17 UTC (rev 5098) @@ -944,6 +944,11 @@ 0x5111 - SCR 331-DI 0x5115 - SCR 335 0xe003 - SPR 532 + The + 0x5117 - SCR 3320 USB ID-000 reader + seems to be very slow but enabling this workaround boosts the + performance to a a more or less acceptable level (tested by David). + */ if (handle->id_vendor == VENDOR_SCM && handle->max_ifsd > 48 @@ -951,6 +956,7 @@ ||(handle->id_product == 0x5111 && handle->bcd_device < 0x0620) ||(handle->id_product == 0x5115 && handle->bcd_device < 0x0514) ||(handle->id_product == 0xe003 && handle->bcd_device < 0x0504) + ||(handle->id_product == 0x5117 && handle->bcd_device < 0x0522) )) { DEBUGOUT ("enabling workaround for buggy SCM readers\n"); From cvs at cvs.gnupg.org Wed Jul 29 12:07:07 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 29 Jul 2009 12:07:07 +0200 Subject: [svn] GnuPG - r5099 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2009-07-29 12:06:56 +0200 (Wed, 29 Jul 2009) New Revision: 5099 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/keygen.c Log: Update key generation menu to match gnupg 2.0. Changes default preferences and key algorithms. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-24 11:01:17 UTC (rev 5098) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-29 10:06:56 UTC (rev 5099) @@ -1,14 +1,30 @@ -2009-07-23 David Shaw +2009-07-29 Werner Koch - * keyserver.c (keyserver_import_ldap): Try a DNS-SD lookup to find - a domain-specific LDAP server before resorting to keys.{domain}. + * keygen.c (keygen_set_std_prefs): Remove RMD-160 from the list. + Change order to SHA-256, SHA-1, SHA-384, SHA-512, SHA-224. + (gen_dsa): Use a 256 bit Q for 2048 bit P. Round to FIPS allowed + values in non-expert mode. + (ask_algo): Add arg R_SUBKEY_ALGO. Change return value semantics. + Change presented order of algorithms. Make RSA+RSA the default. + (generate_keypair, generate_subkeypair): Adjust for change. 2009-07-23 Werner Koch + * keygen.c (generate_keypair): Allow Elgamal > 3072 in BOTH mode. + Reported by Jeroen Schot. Fixes bug#1091. + (ask_keysize): Add new arg PRIMARY_KEYSIZE. Set DSA default to + 2048. Print a different prompt for a subkey. + (gen_dsa): Remove check for dsa2 option. + * trustdb.c (how_to_fix_the_trustdb): New. * tdbio.c (tdbio_invalid): Print hints on how to fix the trustdb. * gpg.c (main) : Print hints. +2009-07-23 David Shaw + + * keyserver.c (keyserver_import_ldap): Try a DNS-SD lookup to find + a domain-specific LDAP server before resorting to keys.{domain}. + 2009-07-22 Werner Koch * cardglue.h (struct agent_card_info_s): Add field EXTCAP. Modified: branches/STABLE-BRANCH-1-4/g10/keygen.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keygen.c 2009-07-24 11:01:17 UTC (rev 5098) +++ branches/STABLE-BRANCH-1-4/g10/keygen.c 2009-07-29 10:06:56 UTC (rev 5099) @@ -298,7 +298,7 @@ byte sym[MAX_PREFS], hash[MAX_PREFS], zip[MAX_PREFS]; int nsym=0, nhash=0, nzip=0, val, rc=0; int mdc=1, modify=0; /* mdc defaults on, modify defaults off. */ - char dummy_string[45+1]; /* Enough for 15 items. */ + char dummy_string[20*4+1]; /* Enough for 20 items. */ if (!string || !ascii_strcasecmp (string, "default")) { @@ -342,15 +342,30 @@ if(!check_cipher_algo(CIPHER_ALGO_IDEA)) strcat(dummy_string,"S1 "); - /* SHA-1 */ - strcat(dummy_string,"H2 "); - if(!check_digest_algo(DIGEST_ALGO_SHA256)) - strcat(dummy_string,"H8 "); + /* The default hash algo order is: + SHA-256, SHA-1, SHA-384, SHA-512, SHA-224. + Ordering SHA-1 before SHA-384 might be viewed as a bit + strange; it is done because we expect that soon enough + SHA-3 will be available and at that point there should + be no more need for SHA-384 etc. Anyway this order is + just a default and can easily be changed by a config + option. */ + if (!check_digest_algo (DIGEST_ALGO_SHA256)) + strcat (dummy_string, "H8 "); - /* RIPEMD160 */ - strcat(dummy_string,"H3 "); + strcat (dummy_string,"H2 ");/* SHA-1 */ + if (!check_digest_algo (DIGEST_ALGO_SHA384)) + strcat (dummy_string, "H9 "); + + if (!check_digest_algo (DIGEST_ALGO_SHA512)) + strcat (dummy_string, "H10 "); + + if (!check_digest_algo (DIGEST_ALGO_SHA224)) + strcat (dummy_string, "H11 "); + + /* ZLIB */ strcat(dummy_string,"Z2 "); @@ -503,7 +518,8 @@ /* Return a fake user ID containing the preferences. Caller must free. */ -PKT_user_id *keygen_get_std_prefs(void) +PKT_user_id * +keygen_get_std_prefs (void) { int i,j=0; PKT_user_id *uid=xmalloc_clear(sizeof(PKT_user_id)); @@ -631,6 +647,8 @@ int keygen_upd_std_prefs( PKT_signature *sig, void *opaque ) { + (void)opaque; + if (!prefs_initialized) keygen_set_std_prefs (NULL, 0); @@ -1111,7 +1129,7 @@ MPI *factors; unsigned int qbits; - if( nbits < 512 || (!opt.flags.dsa2 && nbits > 1024)) + if( nbits < 512) { nbits = 1024; log_info(_("keysize invalid; using %u bits\n"), nbits ); @@ -1128,6 +1146,14 @@ log_info(_("keysize rounded up to %u bits\n"), nbits ); } + /* To comply with FIPS rules we round up to the next value unless + in expert mode. */ + if (!opt.expert && nbits > 1024 && (nbits % 1024)) + { + nbits = ((nbits + 1023) / 1024) * 1024; + log_info (_("keysize rounded up to %u bits\n"), nbits ); + } + /* Figure out a q size based on the key size. FIPS 180-3 says: @@ -1139,11 +1165,11 @@ 2048/256 is an odd pair since there is also a 2048/224 and 3072/256. Matching sizes is not a very exact science. - We'll do 256 qbits for nbits over 2048, 224 for nbits over 1024 + We'll do 256 qbits for nbits over 2047, 224 for nbits over 1024 but less than 2048, and 160 for 1024 (DSA1). */ - if(nbits>2048) + if(nbits>2047) qbits=256; else if(nbits>1024) qbits=224; @@ -1446,101 +1472,139 @@ } -/**************** - * Returns: 0 to create both a DSA and a Elgamal key. - * and only if key flags are to be written the desired usage. - */ +/* Ask for an algorithm. The function returns the algorithm id to + create. If ADDMODE is false the function won't show an option to + create the primary and subkey combined and won't set R_USAGE + either. If a combined algorithm has been selected, the subkey + algorithm is stored at R_SUBKEY_ALGO. */ static int -ask_algo (int addmode, unsigned int *r_usage) +ask_algo (int addmode, int *r_subkey_algo, unsigned int *r_usage) { - char *answer; - int algo; + char *answer; + int algo; + int dummy_algo; + + if (!r_subkey_algo) + r_subkey_algo = &dummy_algo; + + tty_printf(_("Please select what kind of key you want:\n")); + if (!addmode) + tty_printf (_(" (%d) RSA and RSA (default)\n"), 1 ); + if ( !addmode ) + tty_printf (_(" (%d) DSA and Elgamal\n"), 2 ); - *r_usage = 0; - tty_printf(_("Please select what kind of key you want:\n")); - if( !addmode ) - tty_printf(_(" (%d) DSA and Elgamal (default)\n"), 1 ); - tty_printf( _(" (%d) DSA (sign only)\n"), 2 ); - if (opt.expert) - tty_printf( _(" (%d) DSA (set your own capabilities)\n"), 3 ); - if( addmode ) - tty_printf(_(" (%d) Elgamal (encrypt only)\n"), 4 ); - tty_printf( _(" (%d) RSA (sign only)\n"), 5 ); - if (addmode) - tty_printf(_(" (%d) RSA (encrypt only)\n"), 6 ); - if (opt.expert) - tty_printf( _(" (%d) RSA (set your own capabilities)\n"), 7 ); + tty_printf( _(" (%d) DSA (sign only)\n"), 3 ); + tty_printf( _(" (%d) RSA (sign only)\n"), 4 ); - for(;;) { - answer = cpr_get("keygen.algo",_("Your selection? ")); - cpr_kill_prompt(); - algo = *answer? atoi(answer): 1; - xfree(answer); - if( algo == 1 && !addmode ) { - algo = 0; /* create both keys */ - break; + if (addmode) + { + tty_printf (_(" (%d) Elgamal (encrypt only)\n"), 5 ); + tty_printf (_(" (%d) RSA (encrypt only)\n"), 6 ); + } + if (opt.expert) + { + tty_printf (_(" (%d) DSA (set your own capabilities)\n"), 7 ); + tty_printf (_(" (%d) RSA (set your own capabilities)\n"), 8 ); + } + + for (;;) + { + *r_usage = 0; + *r_subkey_algo = 0; + answer = cpr_get ("keygen.algo", _("Your selection? ")); + cpr_kill_prompt (); + algo = *answer? atoi(answer): 1; + xfree (answer); + if ( algo == 1 && !addmode ) + { + algo = PUBKEY_ALGO_RSA; + *r_subkey_algo = PUBKEY_ALGO_RSA; + break; } - else if( algo == 7 && opt.expert ) { - algo = PUBKEY_ALGO_RSA; - *r_usage=ask_key_flags(algo,addmode); - break; + else if (algo == 2 && !addmode) + { + algo = PUBKEY_ALGO_DSA; + *r_subkey_algo = PUBKEY_ALGO_ELGAMAL_E; + break; } - else if( algo == 6 && addmode ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_ENC; - break; + else if (algo == 3) + { + algo = PUBKEY_ALGO_DSA; + *r_usage = PUBKEY_USAGE_SIG; + break; } - else if( algo == 5 ) { - algo = PUBKEY_ALGO_RSA; - *r_usage = PUBKEY_USAGE_SIG; - break; + else if (algo == 4) + { + algo = PUBKEY_ALGO_RSA; + *r_usage = PUBKEY_USAGE_SIG; + break; } - else if( algo == 4 && addmode ) { - algo = PUBKEY_ALGO_ELGAMAL_E; - *r_usage = PUBKEY_USAGE_ENC; - break; + else if (algo == 5 && addmode) + { + algo = PUBKEY_ALGO_ELGAMAL_E; + *r_usage = PUBKEY_USAGE_ENC; + break; } - else if( algo == 3 && opt.expert ) { - algo = PUBKEY_ALGO_DSA; - *r_usage=ask_key_flags(algo,addmode); - break; + else if (algo == 6 && addmode) + { + algo = PUBKEY_ALGO_RSA; + *r_usage = PUBKEY_USAGE_ENC; + break; } - else if( algo == 2 ) { - algo = PUBKEY_ALGO_DSA; - *r_usage = PUBKEY_USAGE_SIG; - break; + else if (algo == 7 && opt.expert) + { + algo = PUBKEY_ALGO_DSA; + *r_usage = ask_key_flags (algo, addmode); + break; } - else - tty_printf(_("Invalid selection.\n")); + else if (algo == 8 && opt.expert) + { + algo = PUBKEY_ALGO_RSA; + *r_usage = ask_key_flags (algo, addmode); + break; + } + else + tty_printf (_("Invalid selection.\n")); } - - return algo; + + return algo; } -static unsigned -ask_keysize( int algo ) +/* Ask for the key size. ALGO is the algorithm. If PRIMARY_KEYSIZE + is not 0, the function asks for the size of the encryption + subkey. */ +static unsigned int +ask_keysize (int algo, unsigned int primary_keysize) { - unsigned nbits,min,def=2048,max=4096; + unsigned nbits, min, def=2048, max=4096; + int for_subkey = !!primary_keysize; + int autocomp = 0; if(opt.expert) min=512; else min=1024; + if (primary_keysize && !opt.expert) + { + /* Deduce the subkey size from the primary key size. */ + if (algo == PUBKEY_ALGO_DSA && primary_keysize > 3072) + nbits = 3072; /* For performance reasons we don't support more + than 3072 bit DSA. However we won't see this + case anyway because DSA can't be used as an + encryption subkey ;-). */ + else + nbits = primary_keysize; + autocomp = 1; + goto leave; + } + switch(algo) { case PUBKEY_ALGO_DSA: - if(opt.flags.dsa2) - { - def=1024; - max=3072; - } - else - { - tty_printf(_("DSA keypair will have %u bits.\n"),1024); - return 1024; - } + def=2048; + max=3072; break; case PUBKEY_ALGO_RSA: @@ -1555,13 +1619,12 @@ { char *prompt,*answer; -#define PROMPTSTRING _("What keysize do you want? (%u) ") + if (for_subkey) + prompt = xasprintf (_("What keysize do you want " + "for the subkey? (%u) "), def); + else + prompt = xasprintf (_("What keysize do you want? (%u) "), def); - prompt=xmalloc(strlen(PROMPTSTRING)+20); - sprintf(prompt,PROMPTSTRING,def); - -#undef PROMPTSTRING - answer = cpr_get("keygen.size",prompt); cpr_kill_prompt(); nbits = *answer? atoi(answer): def; @@ -1577,15 +1640,18 @@ tty_printf(_("Requested keysize is %u bits\n"), nbits ); + leave: if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) { nbits = ((nbits + 63) / 64) * 64; - tty_printf(_("rounded up to %u bits\n"), nbits ); + if (!autocomp) + tty_printf (_("rounded up to %u bits\n"), nbits); } else if( (nbits % 32) ) { nbits = ((nbits + 31) / 32) * 32; - tty_printf(_("rounded up to %u bits\n"), nbits ); + if (!autocomp) + tty_printf (_("rounded up to %u bits\n"), nbits); } return nbits; @@ -2748,16 +2814,19 @@ } else { - algo = ask_algo( 0, &use ); - if( !algo ) - { /* default: DSA with ElG subkey of the specified size */ + int subkey_algo; + + algo = ask_algo (0, &subkey_algo, &use ); + if (subkey_algo) + { + /* Create primary and subkey at once. */ both = 1; r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYTYPE; - sprintf( r->u.value, "%d", PUBKEY_ALGO_DSA ); + sprintf (r->u.value, "%d", algo); r->next = para; para = r; - nbits = ask_keysize( PUBKEY_ALGO_DSA ); + nbits = ask_keysize (algo, 0); r = xmalloc_clear( sizeof *r + 20 ); r->key = pKEYLENGTH; sprintf( r->u.value, "%u", nbits); @@ -2769,10 +2838,9 @@ r->next = para; para = r; - algo = PUBKEY_ALGO_ELGAMAL_E; r = xmalloc_clear( sizeof *r + 20 ); r->key = pSUBKEYTYPE; - sprintf( r->u.value, "%d", algo ); + sprintf( r->u.value, "%d", subkey_algo ); r->next = para; para = r; r = xmalloc_clear( sizeof *r + 20 ); @@ -2800,10 +2868,10 @@ r->next = para; para = r; } - + nbits = 0; } - nbits = ask_keysize( algo ); + nbits = ask_keysize (both? subkey_algo : algo, nbits); r = xmalloc_clear( sizeof *r + 20 ); r->key = both? pSUBKEYLENGTH : pKEYLENGTH; sprintf( r->u.value, "%u", nbits); @@ -3357,9 +3425,9 @@ if( rc ) goto leave; - algo = ask_algo( 1, &use ); + algo = ask_algo (1, NULL, &use); assert(algo); - nbits = ask_keysize( algo ); + nbits = ask_keysize (algo, 0); expire = ask_expire_interval(timestamp,0,NULL); if( !cpr_enabled() && !cpr_get_answer_is_yes("keygen.sub.okay", _("Really create? (y/N) "))) From cvs at cvs.gnupg.org Wed Jul 29 18:05:50 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 29 Jul 2009 18:05:50 +0200 Subject: [svn] GnuPG - r5100 - trunk/sm Message-ID: Author: marcus Date: 2009-07-29 18:05:49 +0200 (Wed, 29 Jul 2009) New Revision: 5100 Modified: trunk/sm/ChangeLog trunk/sm/keylist.c Log: 2009-07-29 Marcus Brinkmann * keylist.c (print_capabilities): Print a trailing colon. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-07-29 10:06:56 UTC (rev 5099) +++ trunk/sm/ChangeLog 2009-07-29 16:05:49 UTC (rev 5100) @@ -1,3 +1,7 @@ +2009-07-29 Marcus Brinkmann + + * keylist.c (print_capabilities): Print a trailing colon. + 2009-07-23 Werner Koch * certchain.c (is_cert_still_valid): Emit AUDIT_CRL_CHECK. Modified: trunk/sm/keylist.c =================================================================== --- trunk/sm/keylist.c 2009-07-29 10:06:56 UTC (rev 5099) +++ trunk/sm/keylist.c 2009-07-29 16:05:49 UTC (rev 5100) @@ -286,6 +286,8 @@ es_putc ('S', fp); if ((use & KSBA_KEYUSAGE_KEY_CERT_SIGN)) es_putc ('C', fp); + + es_putc (':', fp); } From cvs at cvs.gnupg.org Wed Jul 29 18:19:54 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 29 Jul 2009 18:19:54 +0200 Subject: [svn] GnuPG - r5101 - trunk/scd Message-ID: Author: marcus Date: 2009-07-29 18:19:48 +0200 (Wed, 29 Jul 2009) New Revision: 5101 Modified: trunk/scd/ChangeLog trunk/scd/ccid-driver.c Log: 2009-07-29 Marcus Brinkmann * ccid-driver.c (print_pr_data): Fix 64 bit compat problem. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-07-29 16:05:49 UTC (rev 5100) +++ trunk/scd/ChangeLog 2009-07-29 16:19:48 UTC (rev 5101) @@ -1,3 +1,7 @@ +2009-07-29 Marcus Brinkmann + + * ccid-driver.c (print_pr_data): Fix 64 bit compat problem. + 2009-07-24 Werner Koch * ccid-driver.c (parse_ccid_descriptor): Enable hack for SCR 3320. Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2009-07-29 16:05:49 UTC (rev 5100) +++ trunk/scd/ccid-driver.c 2009-07-29 16:19:48 UTC (rev 5101) @@ -413,7 +413,7 @@ { if (any) DEBUGOUT_LF (); - DEBUGOUT_1 (" [%04d] ", off); + DEBUGOUT_1 (" [%04lu] ", (unsigned long) off); } DEBUGOUT_CONT_1 (" %02X", data[off]); any = 1; From cvs at cvs.gnupg.org Thu Jul 30 18:45:06 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 30 Jul 2009 18:45:06 +0200 Subject: [svn] GnuPG - r5102 - in trunk: g10 sm Message-ID: Author: wk Date: 2009-07-30 18:45:06 +0200 (Thu, 30 Jul 2009) New Revision: 5102 Modified: trunk/g10/ChangeLog trunk/g10/passphrase.c trunk/sm/ChangeLog trunk/sm/call-agent.c Log: Comment changes. Changed --learn-card. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-07-29 16:19:48 UTC (rev 5101) +++ trunk/g10/ChangeLog 2009-07-30 16:45:06 UTC (rev 5102) @@ -54,7 +54,7 @@ * keygen.c (keygen_set_std_prefs): Remove RMD-160 from the list. Change order to SHA-256, SHA-1, SHA-384, SHA-512, SHA-224. - (gen_dsa): Use a 256 bit Q for 2048 bit P. Runt to FIPS allowed + (gen_dsa): Use a 256 bit Q for 2048 bit P. Round to FIPS allowed values in non-expert mode. 2009-07-07 Werner Koch Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-07-29 16:19:48 UTC (rev 5101) +++ trunk/sm/ChangeLog 2009-07-30 16:45:06 UTC (rev 5102) @@ -1,3 +1,7 @@ +2009-07-30 Werner Koch + + * call-agent.c (learn_cb): Do not store as ephemeral. + 2009-07-29 Marcus Brinkmann * keylist.c (print_capabilities): Print a trailing colon. Modified: trunk/g10/passphrase.c =================================================================== --- trunk/g10/passphrase.c 2009-07-29 16:19:48 UTC (rev 5101) +++ trunk/g10/passphrase.c 2009-07-30 16:45:06 UTC (rev 5102) @@ -88,6 +88,10 @@ count = len2; } + /* Fixme: To avoid DoS attacks by sending an sym-encrypted + packet with a very high S2K count, we should either cap + the iteration count or CPU seconds based timeout. */ + /* A little bit complicated because we need a ulong for count. */ while ( count > len2 ) /* maybe iterated+salted */ { Modified: trunk/sm/call-agent.c =================================================================== --- trunk/sm/call-agent.c 2009-07-29 16:19:48 UTC (rev 5101) +++ trunk/sm/call-agent.c 2009-07-30 16:45:06 UTC (rev 5102) @@ -875,13 +875,11 @@ return 0; } + /* We do not store a certifciate with missing issuers as ephemeral + because we can assume that the --learn-card command has been used + on purpose. */ rc = gpgsm_basic_cert_check (parm->ctrl, cert); - if (gpg_err_code (rc) == GPG_ERR_MISSING_CERT) - { /* For later use we store it in the ephemeral database. */ - log_info ("issuer certificate missing - storing as ephemeral\n"); - keydb_store_cert (cert, 1, NULL); - } - else if (rc) + if (rc && gpg_err_code (rc) != GPG_ERR_MISSING_CERT) log_error ("invalid certificate: %s\n", gpg_strerror (rc)); else { From cvs at cvs.gnupg.org Fri Jul 31 15:10:43 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 31 Jul 2009 15:10:43 +0200 Subject: [svn] dirmngr - r320 - in trunk: . doc po src Message-ID: Author: wk Date: 2009-07-31 15:10:43 +0200 (Fri, 31 Jul 2009) New Revision: 320 Modified: trunk/NEWS trunk/doc/dirmngr.texi trunk/po/de.po trunk/po/dirmngr.pot trunk/src/ChangeLog trunk/src/crlfetch.c trunk/src/dirmngr-client.c trunk/src/estream-printf.c trunk/src/estream.c trunk/src/estream.h trunk/src/http.c trunk/src/http.h trunk/src/server.c Log: Streamlined the http code. Allow to debug HTTP header lines. Extend dirmngr-client. [The diff below has been truncated] Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-07-20 19:06:44 UTC (rev 319) +++ trunk/src/ChangeLog 2009-07-31 13:10:43 UTC (rev 320) @@ -1,3 +1,22 @@ +2009-07-31 Werner Koch + + * server.c (cmd_loadcrl): Add option --url. + * dirmngr-client.c (do_loadcrl): Make use of --url. + + * crlfetch.c (crl_fetch): Remove HTTP_FLAG_NO_SHUTDOWN. Add + flag HTTP_FLAG_LOG_RESP with active DBG_LOOKUP. + + * http.c: Require estream. Remove P_ES macro. + (write_server): Remove. + (my_read_line): Remove. Replace all callers by es_read_line. + (send_request): Use es_asprintf. Always store the cookie. + (http_wait_response): Remove the need to dup the socket. USe new + shutdown flag. + * http.h (HTTP_FLAG_NO_SHUTDOWN): Rename to HTTP_FLAG_SHUTDOWN. + + * estream.c, estream.h, estream-printf.c, estream-printf.h: Update + from current libestream. This is provide es_asprintf. + 2009-07-20 Werner Koch * dirmngr.c (pid_suffix_callback): New. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-07-20 19:06:44 UTC (rev 319) +++ trunk/NEWS 2009-07-31 13:10:43 UTC (rev 320) @@ -1,7 +1,11 @@ Noteworthy changes in version 1.0.4 ------------------------------------------------ + * Fixed a resource problem with LDAP CRLs. + * Made "dirmngr-client --url --load-crl URL" work. + + Noteworthy changes in version 1.0.3 (2009-06-17) ------------------------------------------------ Modified: trunk/doc/dirmngr.texi =================================================================== --- trunk/doc/dirmngr.texi 2009-07-20 19:06:44 UTC (rev 319) +++ trunk/doc/dirmngr.texi 2009-07-31 13:10:43 UTC (rev 320) @@ -281,7 +281,8 @@ @opindex fetch-crl This command requires an URL as additional argument, and it will make dirmngr try to retrieve an import the CRL from that @var{url} into -it's cache. This is mainly useful for debugging purposes. +it's cache. This is mainly useful for debugging purposes. The + at command{dirmngr-client} provides the same feature for a running dirmngr. @item --shutdown @opindex shutdown @@ -999,7 +1000,9 @@ @item --load-crl @opindex load-crl This command expects a list of filenames with DER encoded CRL files. -All CRL will be validated and then loaded into dirmngr's cache. +With the option @option{--url} URLs are expected in palce of filenames +and they are loaded directly from the given location. All CRLs will be +validated and then loaded into dirmngr's cache. @item --lookup @opindex lookup @@ -1011,7 +1014,7 @@ @item --url @itemx -u @opindex url -Modify the @command{lookup} command to take an URL and not a pattern. +Modify the @command{lookup} and @command{load-crl} commands to take an URL. @item --local @itemx -l Modified: trunk/po/de.po [not shown] Modified: trunk/po/dirmngr.pot =================================================================== --- trunk/po/dirmngr.pot 2009-07-20 19:06:44 UTC (rev 319) +++ trunk/po/dirmngr.pot 2009-07-31 13:10:43 UTC (rev 320) @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: gpa-dev at gnupg.org\n" -"POT-Creation-Date: 2009-06-17 15:10+0200\n" +"POT-Creation-Date: 2009-07-31 13:57+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -16,7 +16,7 @@ "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: jnlib/logging.c:628 +#: jnlib/logging.c:642 #, c-format msgid "you found a bug ... (%s:%d)\n" msgstr "" @@ -51,7 +51,7 @@ msgid "can't access directory `%s': %s\n" msgstr "" -#: src/certcache.c:390 src/crlcache.c:2367 src/dirmngr.c:1433 +#: src/certcache.c:390 src/crlcache.c:2367 src/dirmngr.c:1458 #, c-format msgid "can't open `%s': %s\n" msgstr "" @@ -245,7 +245,7 @@ msgstr "" #: src/crlcache.c:649 src/crlcache.c:654 src/crlcache.c:908 src/crlcache.c:914 -#: src/dirmngr.c:1379 +#: src/dirmngr.c:1404 #, c-format msgid "error reading `%s': %s\n" msgstr "" @@ -606,7 +606,7 @@ msgid "End CRL dump\n" msgstr "" -#: src/crlcache.c:2376 src/crlfetch.c:213 src/ldap.c:656 +#: src/crlcache.c:2376 src/crlfetch.c:213 src/ldap.c:685 #, c-format msgid "error initializing reader object: %s\n" msgstr "" @@ -822,211 +822,211 @@ #. TRANSLATORS: @EMAIL@ will get replaced by the actual bug #. reporting address. This is so that we can change the #. reporting address without breaking the translations. -#: src/dirmngr.c:266 src/dirmngr-client.c:149 src/dirmngr_ldap.c:148 +#: src/dirmngr.c:273 src/dirmngr-client.c:149 src/dirmngr_ldap.c:148 msgid "Please report bugs to <@EMAIL@>.\n" msgstr "" -#: src/dirmngr.c:269 +#: src/dirmngr.c:276 msgid "Usage: dirmngr [options] (-h for help)" msgstr "" -#: src/dirmngr.c:271 +#: src/dirmngr.c:278 msgid "" "Syntax: dirmngr [options] [command [args]]\n" "LDAP and OCSP access for GnuPG\n" msgstr "" -#: src/dirmngr.c:346 +#: src/dirmngr.c:353 #, c-format msgid "invalid debug-level `%s' given\n" msgstr "" -#: src/dirmngr.c:347 +#: src/dirmngr.c:354 #, c-format msgid "valid debug levels are: %s\n" msgstr "" -#: src/dirmngr.c:385 +#: src/dirmngr.c:392 msgid "usage: dirmngr [options] " msgstr "" -#: src/dirmngr.c:410 +#: src/dirmngr.c:417 #, c-format msgid "error spawning ldap wrapper reaper thread: %s\n" msgstr "" -#: src/dirmngr.c:622 src/dirmngr.c:632 +#: src/dirmngr.c:638 src/dirmngr.c:648 #, c-format msgid "%s is too old (need %s, have %s)\n" msgstr "" -#: src/dirmngr.c:735 +#: src/dirmngr.c:760 #, c-format msgid "NOTE: no default option file `%s'\n" msgstr "" -#: src/dirmngr.c:740 src/dirmngr.c:1539 +#: src/dirmngr.c:765 src/dirmngr.c:1564 #, c-format msgid "option file `%s': %s\n" msgstr "" -#: src/dirmngr.c:748 +#: src/dirmngr.c:773 #, c-format msgid "reading options from `%s'\n" msgstr "" -#: src/dirmngr.c:850 +#: src/dirmngr.c:875 #, c-format msgid "WARNING: running with faked system time %s\n" msgstr "" -#: src/dirmngr.c:933 +#: src/dirmngr.c:958 msgid "colons are not allowed in the socket name\n" msgstr "" -#: src/dirmngr.c:939 +#: src/dirmngr.c:964 msgid "name of socket too long\n" msgstr "" -#: src/dirmngr.c:946 +#: src/dirmngr.c:971 #, c-format msgid "can't create socket: %s\n" msgstr "" -#: src/dirmngr.c:965 +#: src/dirmngr.c:990 msgid "error getting nonce for the socket\n" msgstr "" -#: src/dirmngr.c:968 +#: src/dirmngr.c:993 #, c-format msgid "error binding socket to `%s': %s\n" msgstr "" -#: src/dirmngr.c:977 +#: src/dirmngr.c:1002 #, c-format msgid "listen() failed: %s\n" msgstr "" -#: src/dirmngr.c:983 +#: src/dirmngr.c:1008 #, c-format msgid "listening on socket `%s'\n" msgstr "" -#: src/dirmngr.c:994 +#: src/dirmngr.c:1019 #, c-format msgid "fork failed: %s\n" msgstr "" -#: src/dirmngr.c:1012 +#: src/dirmngr.c:1037 msgid "out of core\n" msgstr "" -#: src/dirmngr.c:1051 +#: src/dirmngr.c:1076 #, c-format msgid "setsid() failed: %s\n" msgstr "" -#: src/dirmngr.c:1061 +#: src/dirmngr.c:1086 #, c-format msgid "chdir to / failed: %s\n" msgstr "" -#: src/dirmngr.c:1131 +#: src/dirmngr.c:1156 src/server.c:1102 #, c-format msgid "fetching CRL from `%s' failed: %s\n" msgstr "" -#: src/dirmngr.c:1137 +#: src/dirmngr.c:1162 src/server.c:1108 #, c-format msgid "processing CRL from `%s' failed: %s\n" msgstr "" -#: src/dirmngr.c:1341 +#: src/dirmngr.c:1366 #, c-format msgid "error opening `%s': %s\n" msgstr "" -#: src/dirmngr.c:1356 +#: src/dirmngr.c:1381 #, c-format msgid "%s:%u: line too long - skipped\n" msgstr "" -#: src/dirmngr.c:1411 src/dirmngr.c:1495 +#: src/dirmngr.c:1436 src/dirmngr.c:1520 #, c-format msgid "%s:%u: invalid fingerprint detected\n" msgstr "" -#: src/dirmngr.c:1447 src/dirmngr.c:1473 +#: src/dirmngr.c:1472 src/dirmngr.c:1498 #, c-format msgid "%s:%u: read error: %s\n" msgstr "" -#: src/dirmngr.c:1502 +#: src/dirmngr.c:1527 #, c-format msgid "%s:%u: garbage at end of line ignored\n" msgstr "" -#: src/dirmngr.c:1572 +#: src/dirmngr.c:1597 msgid "SIGHUP received - re-reading configuration and flushing caches\n" msgstr "" -#: src/dirmngr.c:1586 +#: src/dirmngr.c:1611 msgid "SIGUSR2 received - no action defined\n" msgstr "" -#: src/dirmngr.c:1591 src/dirmngr.c:1628 +#: src/dirmngr.c:1616 src/dirmngr.c:1653 msgid "SIGTERM received - shutting down ...\n" msgstr "" -#: src/dirmngr.c:1593 +#: src/dirmngr.c:1618 #, c-format msgid "SIGTERM received - still %d active connections\n" msgstr "" -#: src/dirmngr.c:1598 src/dirmngr.c:1631 +#: src/dirmngr.c:1623 src/dirmngr.c:1656 msgid "shutdown forced\n" msgstr "" -#: src/dirmngr.c:1606 +#: src/dirmngr.c:1631 msgid "SIGINT received - immediate shutdown\n" msgstr "" -#: src/dirmngr.c:1613 +#: src/dirmngr.c:1638 #, c-format msgid "signal %d received - no action defined\n" msgstr "" -#: src/dirmngr.c:1647 +#: src/dirmngr.c:1672 #, c-format msgid "error reading nonce on fd %d: %s\n" msgstr "" -#: src/dirmngr.c:1668 +#: src/dirmngr.c:1697 #, c-format msgid "handler for fd %d started\n" msgstr "" -#: src/dirmngr.c:1673 +#: src/dirmngr.c:1702 #, c-format msgid "handler for fd %d terminated\n" msgstr "" -#: src/dirmngr.c:1752 +#: src/dirmngr.c:1785 #, c-format msgid "accept failed: %s - waiting 1s\n" msgstr "" -#: src/dirmngr.c:1778 +#: src/dirmngr.c:1811 #, c-format msgid "error spawning connection handler: %s\n" msgstr "" -#: src/http.c:1643 +#: src/http.c:1471 #, c-format msgid "error creating socket: %s\n" msgstr "" -#: src/http.c:1687 +#: src/http.c:1515 msgid "host not found" msgstr "" @@ -1050,57 +1050,57 @@ msgid "error printing log line: %s\n" msgstr "" -#: src/ldap.c:269 +#: src/ldap.c:270 #, c-format msgid "pth_event failed: %s\n" msgstr "" -#: src/ldap.c:289 +#: src/ldap.c:290 #, c-format msgid "pth_wait failed: %s\n" msgstr "" -#: src/ldap.c:319 +#: src/ldap.c:320 #, c-format msgid "error reading log from ldap wrapper %d: %s\n" msgstr "" -#: src/ldap.c:349 +#: src/ldap.c:352 #, c-format msgid "ldap wrapper %d ready: timeout\n" msgstr "" -#: src/ldap.c:350 +#: src/ldap.c:353 #, c-format msgid "ldap wrapper %d ready" msgstr "" -#: src/ldap.c:357 +#: src/ldap.c:361 #, c-format msgid "waiting for ldap wrapper %d failed: %s\n" msgstr "" -#: src/ldap.c:368 +#: src/ldap.c:373 #, c-format msgid "ldap wrapper %d stalled - killing\n" msgstr "" -#: src/ldap.c:433 src/ldap.c:454 +#: src/ldap.c:462 src/ldap.c:483 #, c-format msgid "reading from ldap wrapper %d failed: %s\n" msgstr "" -#: src/ldap.c:623 +#: src/ldap.c:652 #, c-format msgid "error allocating memory: %s\n" msgstr "" -#: src/ldap.c:1189 +#: src/ldap.c:1218 #, c-format msgid "start_cert_fetch: invalid pattern `%s'\n" msgstr "" -#: src/ldap.c:1395 +#: src/ldap.c:1424 msgid "ldap_search hit the size limit of the server\n" msgstr "" @@ -1305,12 +1305,12 @@ msgstr "" #: src/server.c:575 src/server.c:689 src/server.c:774 src/server.c:1069 -#: src/server.c:1097 src/server.c:1123 src/server.c:1176 src/server.c:1245 +#: src/server.c:1129 src/server.c:1155 src/server.c:1208 src/server.c:1277 #, c-format msgid "command %s failed: %s\n" msgstr "" -#: src/server.c:660 src/server.c:748 src/server.c:1156 src/server.c:1209 +#: src/server.c:660 src/server.c:748 src/server.c:1188 src/server.c:1241 #, c-format msgid "assuan_inquire failed: %s\n" msgstr "" @@ -1340,31 +1340,31 @@ msgid "max_replies %d exceeded\n" msgstr "" -#: src/server.c:1119 +#: src/server.c:1151 msgid "no data stream" msgstr "" -#: src/server.c:1311 +#: src/server.c:1343 #, c-format msgid "can't allocate control structure: %s\n" msgstr "" -#: src/server.c:1334 +#: src/server.c:1366 #, c-format msgid "failed to initialize the server: %s\n" msgstr "" -#: src/server.c:1342 +#: src/server.c:1374 #, c-format msgid "failed to the register commands with Assuan: %s\n" msgstr "" -#: src/server.c:1385 +#: src/server.c:1417 #, c-format msgid "Assuan accept problem: %s\n" msgstr "" -#: src/server.c:1405 +#: src/server.c:1437 #, c-format msgid "Assuan processing failed: %s\n" msgstr "" @@ -1563,7 +1563,7 @@ "not valid and other error codes for general failures\n" msgstr "" -#: src/dirmngr-client.c:285 src/dirmngr-client.c:997 +#: src/dirmngr-client.c:285 src/dirmngr-client.c:1005 #, c-format msgid "error reading certificate from stdin: %s\n" msgstr "" @@ -1596,15 +1596,15 @@ msgid "validation of certificate failed: %s\n" msgstr "" -#: src/dirmngr-client.c:404 src/dirmngr-client.c:1008 +#: src/dirmngr-client.c:404 src/dirmngr-client.c:1016 msgid "certificate is valid\n" msgstr "" -#: src/dirmngr-client.c:410 src/dirmngr-client.c:1016 +#: src/dirmngr-client.c:410 src/dirmngr-client.c:1024 msgid "certificate has been revoked\n" msgstr "" -#: src/dirmngr-client.c:415 src/dirmngr-client.c:1018 +#: src/dirmngr-client.c:415 src/dirmngr-client.c:1026 #, c-format msgid "certificate check failed: %s\n" msgstr "" @@ -1650,11 +1650,11 @@ msgid "unsupported inquiry `%s'\n" msgstr "" -#: src/dirmngr-client.c:899 +#: src/dirmngr-client.c:906 msgid "absolute file name expected\n" msgstr "" -#: src/dirmngr-client.c:941 +#: src/dirmngr-client.c:949 #, c-format msgid "looking up `%s'\n" msgstr "" Modified: trunk/src/crlfetch.c =================================================================== --- trunk/src/crlfetch.c 2009-07-20 19:06:44 UTC (rev 319) +++ trunk/src/crlfetch.c 2009-07-31 13:10:43 UTC (rev 320) @@ -187,8 +187,8 @@ else err = http_open_document (&hd, url, NULL, (opt.honor_http_proxy? HTTP_FLAG_TRY_PROXY:0) - |HTTP_FLAG_NO_SHUTDOWN - |HTTP_FLAG_NEED_HEADER, + |HTTP_FLAG_NEED_HEADER + |(DBG_LOOKUP? HTTP_FLAG_LOG_RESP:0), opt.http_proxy, NULL); switch ( err? 99999 : http_get_status_code (hd) ) Modified: trunk/src/dirmngr-client.c =================================================================== --- trunk/src/dirmngr-client.c 2009-07-20 19:06:44 UTC (rev 319) +++ trunk/src/dirmngr-client.c 2009-07-31 13:10:43 UTC (rev 320) @@ -883,38 +883,46 @@ const char *s; char *fname, *line, *p; -#ifdef HAVE_CANONICALIZE_FILE_NAME - fname = canonicalize_file_name (filename); - if (!fname) + if (opt.url) { - log_error ("error canonicalizing `%s': %s\n", - filename, strerror (errno)); - return gpg_error (GPG_ERR_GENERAL); - } -#else - fname = xstrdup (filename); -#endif - if (*fname != '/') - { - log_error (_("absolute file name expected\n")); - return gpg_error (GPG_ERR_GENERAL); + line = xmalloc (8+6+ strlen (filename) + 1); + strcpy (stpcpy (line, "LOADCRL --url "), filename?filename:""); } - - line = xmalloc (8+ strlen (fname) * 3 + 1); - p = stpcpy (line, "LOADCRL "); - for (s = fname; *s; s++) + else { - if (*s < ' ' || *s == '+') +#ifdef HAVE_CANONICALIZE_FILE_NAME + fname = canonicalize_file_name (filename); + if (!fname) { - sprintf (p, "%%%02X", *s); - p += 3; + log_error ("error canonicalizing `%s': %s\n", + filename, strerror (errno)); + return gpg_error (GPG_ERR_GENERAL); + } +#else + fname = xstrdup (filename); +#endif + if (*fname != '/') + { + log_error (_("absolute file name expected\n")); + return gpg_error (GPG_ERR_GENERAL); } - else if (*s == ' ') - *p++ = '+'; - else - *p++ = *s; + + line = xmalloc (8+ strlen (fname) * 3 + 1); + p = stpcpy (line, "LOADCRL "); + for (s = fname; *s; s++) + { + if (*s < ' ' || *s == '+') + { + sprintf (p, "%%%02X", *s); + p += 3; + } + else if (*s == ' ') + *p++ = '+'; + else + *p++ = *s; + } + *p = 0; } - *p = 0; err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, Modified: trunk/src/estream-printf.c =================================================================== --- trunk/src/estream-printf.c 2009-07-20 19:06:44 UTC (rev 319) +++ trunk/src/estream-printf.c 2009-07-31 13:10:43 UTC (rev 320) @@ -1,5 +1,5 @@ /* estream-printf.c - Versatile C-99 compliant printf formatting - * Copyright (C) 2007, 2008 g10 Code GmbH + * Copyright (C) 2007, 2008, 2009 g10 Code GmbH * * This file is part of Libestream. * @@ -34,6 +34,7 @@ Missing stuff: wchar and wint_t thousands_sep in pr_float. + */ #ifdef HAVE_CONFIG_H @@ -54,22 +55,21 @@ #ifdef HAVE_LANGINFO_THOUSANDS_SEP #include #endif -#ifdef TEST -# include -#else -# ifdef _ESTREAM_PRINTF_EXTRA_INCLUDE -# include _ESTREAM_PRINTF_EXTRA_INCLUDE -# endif +#ifdef _ESTREAM_PRINTF_EXTRA_INCLUDE +# include _ESTREAM_PRINTF_EXTRA_INCLUDE #endif #include "estream-printf.h" +/* #define DEBUG 1 */ + + /* Allow redefinition of asprintf used malloc functions. */ -#if defined(_ESTREAM_PRINTF_MALLOC) && !defined(TEST) +#if defined(_ESTREAM_PRINTF_MALLOC) #define my_printf_malloc(a) _ESTREAM_PRINTF_MALLOC((a)) #else #define my_printf_malloc(a) malloc((a)) #endif -#if defined(_ESTREAM_PRINTF_FREE) && !defined(TEST) +#if defined(_ESTREAM_PRINTF_FREE) #define my_printf_free(a) _ESTREAM_PRINTF_FREE((a)) #else #define my_printf_free(a) free((a)) @@ -257,9 +257,7 @@ typedef struct valueitem_s *valueitem_t; -#ifdef TEST -static int verbose; - +#ifdef DEBUG static void dump_argspecs (argspec_t arg, size_t argcount) { @@ -281,7 +279,7 @@ arg->width_pos, arg->precision_pos); } -#endif /*TEST*/ +#endif /*DEBUG*/ /* Set the vt field for ARG. */ @@ -995,7 +993,7 @@ int use_dbl = 0; #endif double afloat; - char numbuf[200]; + char numbuf[350]; char formatstr[20]; char *p, *pend; size_t n; @@ -1482,8 +1480,7 @@ if (max_pos < 0 || max_pos >= strlen (format)) goto leave_einval; -#ifdef TEST - if (verbose > 1) +#ifdef DEBUG dump_argspecs (argspecs, argspecs_len); #endif @@ -1787,324 +1784,3 @@ } -#ifdef TEST - -static int -one_test (const char *format, ...) -{ -#ifdef _WIN32 - { - static int show; - - if (!show) - { - /* We do not have a system vasprintf. */ - printf ("one-test: disabled under W32\n"); - show = 1; - } - } -#else - int rc1, rc2; - va_list arg_ptr; - char *buf1, *buf2; - - if (verbose) - printf ("format: ->%s<-\n", format); - - va_start (arg_ptr, format); - rc1 = vasprintf (&buf1, format, arg_ptr); - va_end (arg_ptr); - if (rc1 == -1) - { - printf (" sys: errno=%d (%s)\n", errno, strerror (errno)); - buf1 = NULL; - } - else if (verbose) - printf (" sys: ->%s<-\n", buf1); - - va_start (arg_ptr, format); - rc2 = estream_vasprintf (&buf2, format, arg_ptr); - va_end (arg_ptr); - if (rc2 == -1) - printf (" our: errno=%d (%s)\n", errno, strerror (errno)); - else if (verbose) - printf (" our: ->%s<-\n", buf2); - - if (rc1 != -1 && rc2 != -1 && strcmp (buf1, buf2)) - printf ("error: output does not match\n" - "format: ->%s<-\n sys: ->%s<-\n our: ->%s<-\n", - format, buf1, buf2); - else if ( rc1 != rc2 ) - printf ("error: return codes are different: sys_rc=%d our_rc=%d\n", - rc1, rc2); - - free (buf2); - free (buf1); -#endif - return 0; -} - - -static void -run_tests (void) -{ - /*one_test ("%d %% %'d", 17, 19681977);*/ - - one_test ("%d %% %d", 17, 768114563); - one_test ("%d %% %d", 17, -768114563); - - one_test ("%d", 17); - one_test ("%4d", 17); - one_test ("%40d", 17); - one_test ("%-d", 17); - one_test ("%-4d", 17); - one_test ("%-140d", 17); - one_test ("%d", -17); - one_test ("%4d", -17); - one_test ("%40d", -17); - one_test ("%-d", -17); - one_test ("%-4d", -17); - one_test ("%-40d", -17); - - one_test ("%+4d", 17); - one_test ("%+4d", -17); - one_test ("%-+4d", 17); - one_test ("%-+4d", -17); - one_test ("% 4d", 17); - one_test ("% 4d", -17); - one_test ("%- +4d", 17); - one_test ("%- +4d", -17); - - one_test ("%.4d", 17); - one_test ("%.0d", 17); - one_test ("%.0d", 0); - one_test ("%.4d", -17); - one_test ("%.0d", -17); - one_test ("%6.4d", 17); - one_test ("%6.4d", -17); - one_test ("%6.0d", 0); - one_test ("%4.6d", 17); - one_test ("%4.6d", -17); - - one_test ("% 4.6d", 17); - one_test ("% 6.0d", 0); - - one_test ("%.4d", 17); - one_test ("%04d", 17); - one_test ("%.4d", -17); - one_test ("%04d", -17); - one_test ("%0.d", 0); - - one_test ("%*d", 7, 42); - one_test ("%*d", -7, 42); - one_test ("%.*d", 7, 42); - one_test ("%.*d", -7, 42); - one_test ("%*.*d", 10, 7, 42); - one_test ("%*.*d", 10, -7, 42); - one_test ("%*.*d", -10, 7, 42); - one_test ("%*.*d", -10, -7, 42); - - one_test ("%*x", 7, 42); - one_test ("%*x", -7, 42); - one_test ("%.*x", 7, 42); - one_test ("%.*x", -7, 42); - one_test ("%*.*x", 10, 7, 42); - one_test ("%*.*x", 10, -7, 42); - one_test ("%*.*x", -10, 7, 42); - one_test ("%*.*x", -10, -7, 42); - one_test ("%#*x", 7, 42); - one_test ("%#*x", -7, 42); - one_test ("%#.*x", 7, 42); - one_test ("%#.*x", -7, 42); - one_test ("%#*.*x", 10, 7, 42); - one_test ("%#*.*x", 10, -7, 42); - one_test ("%#*.*x", -10, 7, 42); - one_test ("%#*.*x", -10, -7, 42); - - one_test ("%*X", 7, 42); - one_test ("%*X", -7, 42); - one_test ("%.*X", 7, 42); - one_test ("%.*X", -7, 42); - one_test ("%*.*X", 10, 7, 42); - one_test ("%*.*X", 10, -7, 42); - one_test ("%*.*X", -10, 7, 42); - one_test ("%*.*X", -10, -7, 42); - one_test ("%#*X", 7, 42); - one_test ("%#*X", -7, 42); - one_test ("%#.*X", 7, 42); - one_test ("%#.*X", -7, 42); - one_test ("%#*.*X", 10, 7, 42); - one_test ("%#*.*X", 10, -7, 42); - one_test ("%#*.*X", -10, 7, 42); - one_test ("%#*.*X", -10, -7, 42); - - one_test ("%*o", 7, 42); - one_test ("%*o", -7, 42); - one_test ("%.*o", 7, 42); - one_test ("%.*o", -7, 42); - one_test ("%*.*o", 10, 7, 42); - one_test ("%*.*o", 10, -7, 42); - one_test ("%*.*o", -10, 7, 42); - one_test ("%*.*o", -10, -7, 42); - one_test ("%#*o", 7, 42); - one_test ("%#*o", -7, 42); - one_test ("%#.*o", 7, 42); - one_test ("%#.*o", -7, 42); - one_test ("%#*.*o", 10, 7, 42); - one_test ("%#*.*o", 10, -7, 42); - one_test ("%#*.*o", -10, 7, 42); - one_test ("%#*.*o", -10, -7, 42); - - one_test ("%s", "the quick brown fox jumps over the lazy dogs back"); - one_test ("%.0s", "the quick brown fox jumps over the lazy dogs back"); - one_test ("%.10s", "the quick brown fox jumps over the lazy dogs back"); - one_test ("%.48s", "the quick brown fox jumps over the lazy dogs back"); - one_test ("%.49s", "the quick brown fox jumps over the lazy dogs back"); - one_test ("%.50s", "the quick brown fox jumps over the lazy dogs back"); - one_test ("%.51s", "the quick brown fox jumps over the lazy dogs back"); - one_test ("%48s", "the quick brown fox jumps over the lazy dogs back"); - one_test ("%49s", "the quick brown fox jumps over the lazy dogs back"); - one_test ("%50s", "the quick brown fox jumps over the lazy dogs back"); - one_test ("%51s", "the quick brown fox jumps over the lazy dogs back"); - one_test ("%-51s", "the quick brown fox jumps over the lazy dogs back"); - - one_test ("/%s=", "CN"); - - one_test ("%f", 3.1415926535); - one_test ("%f", -3.1415926535); - one_test ("%.10f", 3.1415926535); - one_test ("%.2f", 3.1415926535); - one_test ("%.1f", 3.1415926535); - one_test ("%.0f", 3.1415926535); - one_test ("%.20f", 3.1415926535); - one_test ("%10.10f", 3.1415926535); - one_test ("%10.2f", 3.1415926535); - one_test ("%10.1f", 3.1415926535); - one_test ("%10.0f", 3.1415926535); - one_test ("%30.20f", 3.1415926535); - one_test ("%10.10f", -3.1415926535); - one_test ("%10.2f", -3.1415926535); - one_test ("%10.1f", -3.1415926535); - one_test ("%10.0f", -3.1415926535); - one_test ("%30.20f", -3.1415926535); - - one_test ("%-10f", 3.1415926535); - one_test ("%-10.10f", 3.1415926535); - one_test ("%-10.2f", 3.1415926535); - one_test ("%-10.1f", 3.1415926535); - one_test ("%-10.0f", 3.1415926535); - one_test ("%-30.20f", 3.1415926535); - one_test ("%-10f", -3.1415926535); - one_test ("%-10.10f", -3.1415926535); - one_test ("%-10.2f", -3.1415926535); - one_test ("%-10.1f", -3.1415926535); - one_test ("%-10.0f", -3.1415926535); - one_test ("%-30.20f", -3.1415926535); - - one_test ("%#.0f", 3.1415926535); - one_test ("%#10.0f", 3.1415926535); - one_test ("%#10.0f", -3.1415926535); - one_test ("%-#10.0f", 3.1415926535); - one_test ("%-#10.0f", -3.1415926535); - - one_test ("%e", 3.1415926535); - one_test ("%g", 3.1415926535); - - one_test ("%a", 1); - one_test ("%a", -1); - one_test ("%a", 3.1415926535); - -#ifdef HAVE_LONG_DOUBLE - one_test ("%La", 1); - one_test ("%La", -1); - one_test ("%La", 3.1415926535); -#endif - -#ifdef __GLIBC__ - /* "%m" is a glibc extension so this _test_ will only work on such a - system. */ - errno = ENOENT; - one_test ("%m"); - errno = ENOENT; - one_test ("%d=%m", 17); - errno = ENOENT; - one_test ("%2$d:%m:%1$d", 42, 17); -#endif /*__GLIBC__*/ - -} - -static void -check_snprintf (void) -{ - char buffer[20]; - int rc, rc2; - size_t tmplen, blen, blen2; - - rc = estream_snprintf (buffer, 0, "%*s", 18, ""); - if (rc != 18) - printf ("rc=%d\n", rc ); - rc = estream_snprintf (buffer, sizeof buffer, "%*s", 18, ""); - if (rc != 18) - printf ("rc=%d, strlen(buffer)=%d\n", rc, (int)strlen (buffer)); - rc = estream_snprintf (buffer, sizeof buffer, "%*s", 19, ""); - if (rc != 19) - printf ("rc=%d, strlen(buffer)=%d\n", rc, (int)strlen (buffer)); - rc = estream_snprintf (buffer, sizeof buffer, "%*s", 20, ""); - if (rc != 20) - printf ("rc=%d, strlen(buffer)=%d\n", rc, (int)strlen (buffer)); - rc = estream_snprintf (buffer, sizeof buffer, "%*s", 21, ""); - if (rc != 21) - printf ("rc=%d, strlen(buffer)=%d\n", rc, (int)strlen (buffer)); - - for (tmplen = 0; tmplen <= sizeof buffer; tmplen++) - { - rc = estream_snprintf (buffer, tmplen, "%04d%02d%02dT%02d%02d%02d", - 1998, 9, 7, 16, 56, 05); - blen = strlen (buffer); - rc2 = snprintf (buffer, tmplen, "%04d%02d%02dT%02d%02d%02d", - 1998, 9, 7, 16, 56, 05); - blen2 = strlen (buffer); - if (rc != rc2 || blen != blen2) - printf ("snprintf test with len %u gives %d instead of %d (%d,%d)\n", - (unsigned int)tmplen, rc, rc2, blen, blen2); - } -} - - - -int -main (int argc, char **argv) -{ - int rc; - - if (argc) {argc--; argv++; } - - setlocale (LC_NUMERIC, ""); - - while (argc && !strcmp (*argv, "--verbose")) - { - verbose++; - argc--; - argv++; - } - - if (!argc) - { - run_tests (); - check_snprintf () ; - } - else - { - rc = estream_vfprintf (stdout, argv[0], NULL); - fflush (stdout); - fprintf (stderr, "[estream_vfprintf returns: %d]\n", rc); - } - - return 0; -} -#endif /*TEST*/ -/* -Local Variables: -compile-command: "cc -Wall -O3 -g -I.. -DHAVE_CONFIG_H -DTEST -o estream-printf estream-printf.c" -End: -*/ Modified: trunk/src/estream.c =================================================================== --- trunk/src/estream.c 2009-07-20 19:06:44 UTC (rev 319) +++ trunk/src/estream.c 2009-07-31 13:10:43 UTC (rev 320) @@ -2892,6 +2892,45 @@ } +/* A variant of asprintf. The function returns the allocated buffer + or NULL on error; ERRNO is set in the error case. The caller + should use es_free to release the buffer. This function actually + belongs into estream-printf but we put it here as a convenience + and because es_free is required anyway. */ +char * +es_asprintf (const char *ES__RESTRICT format, ...) +{ + int rc; + va_list ap; + char *buf; + + va_start (ap, format); + rc = estream_vasprintf (&buf, format, ap); + va_end (ap); + if (rc < 0) + return NULL; + return buf; +} + + +/* A variant of vasprintf. The function returns the allocated buffer + or NULL on error; ERRNO is set in the error case. The caller + should use es_free to release the buffer. This function actually + belongs into estream-printf but we put it here as a convenience + and because es_free is required anyway. */ +char * +es_vasprintf (const char *ES__RESTRICT format, va_list ap) +{ + int rc; + char *buf; + + rc = estream_vasprintf (&buf, format, ap); + if (rc < 0) + return NULL; + return buf; +} + + static int tmpfd (void) { Modified: trunk/src/estream.h =================================================================== --- trunk/src/estream.h 2009-07-20 19:06:44 UTC (rev 319) +++ trunk/src/estream.h 2009-07-31 13:10:43 UTC (rev 320) @@ -292,6 +292,12 @@ int es_vfprintf (estream_t ES__RESTRICT stream, const char *ES__RESTRICT format, va_list ap) _ESTREAM_GCC_A_PRINTF(2,0); + +char *es_asprintf (const char *ES__RESTRICT format, ...) + _ESTREAM_GCC_A_PRINTF(1,2); +char *es_vasprintf (const char *ES__RESTRICT format, va_list ap) + _ESTREAM_GCC_A_PRINTF(1,0); + int es_setvbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf, int mode, size_t size); void es_setbuf (estream_t ES__RESTRICT stream, char *ES__RESTRICT buf); Modified: trunk/src/http.c =================================================================== --- trunk/src/http.c 2009-07-20 19:06:44 UTC (rev 319) +++ trunk/src/http.c 2009-07-31 13:10:43 UTC (rev 320) @@ -1,6 +1,6 @@ /* http.c - HTTP protocol handler * Copyright (C) 1999, 2001, 2002, 2003, 2004, - * 2006 Free Software Foundation, Inc. + * 2006, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -23,11 +23,13 @@ /* Simple HTTP client implementation. We try to keep the code as self-contained as possible. There are some contraints however: + - estream is required. We now require estream because it provides a + very useful and portable asprintf implementation and the fopencookie + function. - stpcpy is required - fixme: list other requirements. - - With HTTP_USE_ESTREAM defined, all I/O is done through estream. - With HTTP_USE_GNUTLS support for https is provided (this also requires estream). - With HTTP_NO_WSASTARTUP the socket initialization is not done @@ -114,18 +116,9 @@ "01234567890@" \ "!\"#$%&'()*+,-./:;<=>?[\\]^_{|}~" -/* Define a prefix to map stream functions to the estream library. */ -#ifdef HTTP_USE_ESTREAM -#define P_ES(a) es_ ## a -#else -#define P_ES(a) a -#endif #ifndef HTTP_USE_GNUTLS typedef void * gnutls_session_t; #endif -#if defined(HTTP_USE_GNUTLS) && !defined(HTTP_USE_ESTREAM) -#error Use of GNUTLS also requires support for Estream -#endif static gpg_error_t do_parse_uri (parsed_uri_t uri, int only_local_part); static int remove_escapes (char *string); @@ -139,11 +132,7 @@ static int connect_server (const char *server, unsigned short port, unsigned int flags, const char *srvtag); -#ifndef HTTP_USE_ESTREAM -static gpg_error_t write_server (int sock, const char *data, size_t length); -#endif -#ifdef HTTP_USE_ESTREAM static ssize_t cookie_read (void *cookie, void *buffer, size_t size); static ssize_t cookie_write (void *cookie, const void *buffer, size_t size); static int cookie_close (void *cookie); @@ -160,11 +149,10 @@ { int fd; /* File descriptor or -1 if already closed. */ gnutls_session_t tls_session; /* TLS session context or NULL if not used. */ - int keep_socket; /* Flag to communicate with teh close handler. */ + int keep_socket; /* Flag to communicate with the close handler. */ }; typedef struct cookie_s *cookie_t; -#endif /*HTTP_USE_ESTREAM*/ #ifdef HTTP_USE_GNUTLS static gpg_error_t (*tls_callback) (http_t, gnutls_session_t, int); @@ -187,14 +175,10 @@ unsigned int status_code; int sock; int in_data; -#ifdef HTTP_USE_ESTREAM estream_t fp_read; estream_t fp_write; void *write_cookie; -#else /*!HTTP_USE_ESTREAM*/ - FILE *fp_read; - FILE *fp_write; -#endif /*!HTTP_USE_ESTREAM*/ + void *read_cookie; void *tls_context; int is_http_0_9; parsed_uri_t uri; @@ -351,9 +335,9 @@ if (!hd->fp_read && !hd->fp_write && hd->sock != -1) sock_close (hd->sock); if (hd->fp_read) - P_ES(fclose) (hd->fp_read); + es_fclose (hd->fp_read); if (hd->fp_write) - P_ES(fclose) (hd->fp_write); + es_fclose (hd->fp_write); http_release_parsed_uri (hd->uri); xfree (hd); } @@ -368,17 +352,12 @@ { if (!hd->in_data) { -#ifdef HTTP_USE_ESTREAM es_fputs ("\r\n", hd->fp_write); es_fflush (hd->fp_write); -#else - fflush (hd->fp_write); - write_server (hd->sock, "\r\n", 2); -#endif hd->in_data = 1; } else - P_ES(fflush) (hd->fp_write); + es_fflush (hd->fp_write); } @@ -386,69 +365,45 @@ http_wait_response (http_t hd) { gpg_error_t err; + cookie_t cookie; /* Make sure that we are in the data. */ http_start_data (hd); - /* We dup the socket, to cope with the fact that fclose closes the - underlying socket. In TLS mode we don't do that because we can't - close the socket gnutls is working on; instead we make sure that - the fclose won't close the socket in this case. */ -#ifdef HTTP_USE_ESTREAM - if (hd->write_cookie) - { - /* The write cookie is only set in the TLS case. */ - cookie_t cookie = hd->write_cookie; - cookie->keep_socket = 1; - } - else -#endif /*HTTP_USE_ESTREAM*/ - { -#ifndef HAVE_W32_SYSTEM - hd->sock = dup (hd->sock); -#else - if (!DuplicateHandle (GetCurrentProcess(), hd->sock, - GetCurrentProcess(), &hd->sock, 0, - TRUE, DUPLICATE_SAME_ACCESS )) - return gpg_error_from_syserror (); -#endif - if (hd->sock == -1) - return gpg_error_from_syserror (); - } - P_ES(fclose) (hd->fp_write); + cookie = hd->write_cookie; + if (!cookie) + return gpg_error (GPG_ERR_INTERNAL); + + /* Close the write stream but keep the socket open. */ + cookie->keep_socket = 1; + es_fclose (hd->fp_write); hd->fp_write = NULL; -#ifdef HTTP_USE_ESTREAM hd->write_cookie = NULL; -#endif - if (!(hd->flags & HTTP_FLAG_NO_SHUTDOWN)) + /* Shutdown one end of the socket is desired. As per HTTP/1.0 this + is not required but some very old servers (e.g. the original pksd + key server didn't worked without it. */ + if ((hd->flags & HTTP_FLAG_SHUTDOWN)) shutdown (hd->sock, 1); hd->in_data = 0; -#ifdef HTTP_USE_ESTREAM - { - cookie_t cookie; - - cookie = xtrycalloc (1, sizeof *cookie); - if (!cookie) + /* Create a new cookie and a stream for reading. */ + cookie = xtrycalloc (1, sizeof *cookie); + if (!cookie) + return gpg_error_from_syserror (); + cookie->fd = hd->sock; + if (hd->uri->use_tls) + cookie->tls_session = hd->tls_context; + + hd->read_cookie = cookie; + hd->fp_read = es_fopencookie (cookie, "r", cookie_functions); + if (!hd->fp_read) + { + xfree (cookie); + hd->read_cookie = NULL; return gpg_error_from_syserror (); - cookie->fd = hd->sock; - if (hd->uri->use_tls) - cookie->tls_session = hd->tls_context; + } - hd->fp_read = es_fopencookie (cookie, "r", cookie_functions); - if (!hd->fp_read) - { - xfree (cookie); - return gpg_error_from_syserror (); - } - } -#else /*!HTTP_USE_ESTREAM*/ - hd->fp_read = fdopen (hd->sock, "r"); - if (!hd->fp_read) - return gpg_error_from_syserror (); -#endif /*!HTTP_USE_ESTREAM*/ - err = parse_response (hd); return err; } @@ -486,9 +441,9 @@ if (!hd->fp_read && !hd->fp_write && hd->sock != -1) sock_close (hd->sock); if (hd->fp_read && !keep_read_stream) - P_ES(fclose) (hd->fp_read); + es_fclose (hd->fp_read); if (hd->fp_write) - P_ES(fclose) (hd->fp_write); + es_fclose (hd->fp_write); http_release_parsed_uri (hd->uri); while (hd->headers) { @@ -502,29 +457,18 @@ } -#ifdef HTTP_USE_ESTREAM estream_t http_get_read_ptr (http_t hd) { return hd?hd->fp_read:NULL; } + estream_t http_get_write_ptr (http_t hd) { return hd?hd->fp_write:NULL; } -#else /*!HTTP_USE_ESTREAM*/ -FILE * -http_get_read_ptr (http_t hd) -{ - return hd?hd->fp_read:NULL; -} -FILE * -http_get_write_ptr (http_t hd) -{ - return hd?hd->fp_write:NULL; -} -#endif /*!HTTP_USE_ESTREAM*/ + unsigned int http_get_status_code (http_t hd) { @@ -840,7 +784,9 @@ char *proxy_authstr = NULL; char *authstr = NULL; int save_errno; + cookie_t cookie; + tls_session = hd->tls_context; if (hd->uri->use_tls && !tls_session) { @@ -973,29 +919,16 @@ if (!p) return gpg_error_from_syserror (); - request = xtrymalloc (2 * strlen (server) - + strlen (p) - + (authstr?strlen(authstr):0) - + (proxy_authstr?strlen(proxy_authstr):0) - + 100); - if (!request) - { - err = gpg_error_from_syserror (); - xfree (p); - xfree (authstr); - xfree (proxy_authstr); - return err; - } - if (http_proxy && *http_proxy) { - sprintf (request, "%s http://%s:%hu%s%s HTTP/1.0\r\n%s%s", - hd->req_type == HTTP_REQ_GET ? "GET" : - hd->req_type == HTTP_REQ_HEAD ? "HEAD" : - hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", - server, port, *p == '/' ? "" : "/", p, - authstr ? authstr : "", - proxy_authstr ? proxy_authstr : ""); + request = es_asprintf + ("%s http://%s:%hu%s%s HTTP/1.0\r\n%s%s", + hd->req_type == HTTP_REQ_GET ? "GET" : + hd->req_type == HTTP_REQ_HEAD ? "HEAD" : + hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", + server, port, *p == '/' ? "" : "/", p, + authstr ? authstr : "", + proxy_authstr ? proxy_authstr : ""); } else { @@ -1004,65 +937,51 @@ if (port == 80) *portstr = 0; else - sprintf (portstr, ":%u", port); + snprintf (portstr, sizeof portstr, ":%u", port); - sprintf (request, "%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s", - hd->req_type == HTTP_REQ_GET ? "GET" : - hd->req_type == HTTP_REQ_HEAD ? "HEAD" : - hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", - *p == '/' ? "" : "/", p, server, portstr, - authstr? authstr:""); + request = es_asprintf + ("%s %s%s HTTP/1.0\r\nHost: %s%s\r\n%s", + hd->req_type == HTTP_REQ_GET ? "GET" : + hd->req_type == HTTP_REQ_HEAD ? "HEAD" : + hd->req_type == HTTP_REQ_POST ? "POST" : "OOPS", + *p == '/' ? "" : "/", p, server, portstr, + authstr? authstr:""); } xfree (p); + if (!request) + { + err = gpg_error_from_syserror (); + xfree (authstr); + xfree (proxy_authstr); + return err; + } - -#ifdef HTTP_USE_ESTREAM /* First setup estream so that we can write even the first line using estream. This is also required for the sake of gnutls. */ - { - cookie_t cookie; - - cookie = xtrycalloc (1, sizeof *cookie); - if (!cookie) - { - err = gpg_error_from_syserror (); - goto leave; - } - cookie->fd = hd->sock; - if (hd->uri->use_tls) - { - cookie->tls_session = tls_session; - hd->write_cookie = cookie; - } - - hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); - if (!hd->fp_write) - { - xfree (cookie); - err = gpg_error_from_syserror (); - } - else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) + cookie = xtrycalloc (1, sizeof *cookie); + if (!cookie) + { err = gpg_error_from_syserror (); - else - err = 0; - } - - leave: - -#else /*!HTTP_USE_ESTREAM*/ - /* We send out the start of the request through our own send - function and only then assign a stdio stream. This allows for - better error reporting that through standard stdio means. */ - err = write_server (hd->sock, request, strlen (request)); - if (!err) + goto leave; + } + cookie->fd = hd->sock; + hd->write_cookie = cookie; + if (hd->uri->use_tls) + cookie->tls_session = tls_session; + hd->fp_write = es_fopencookie (cookie, "w", cookie_functions); + if (!hd->fp_write) { - hd->fp_write = fdopen (hd->sock, "w"); - if (!hd->fp_write) - err = gpg_error_from_syserror (); + xfree (cookie); + hd->write_cookie = NULL; + err = gpg_error_from_syserror (); } -#endif /*!HTTP_USE_ESTREAM*/ + else if (es_fputs (request, hd->fp_write) || es_fflush (hd->fp_write)) + err = gpg_error_from_syserror (); + else From cvs at cvs.gnupg.org Fri Jul 31 15:36:49 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 31 Jul 2009 15:36:49 +0200 Subject: [svn] dirmngr - r321 - in trunk: doc po src Message-ID: Author: wk Date: 2009-07-31 15:36:49 +0200 (Fri, 31 Jul 2009) New Revision: 321 Modified: trunk/doc/dirmngr.texi trunk/po/de.po trunk/po/dirmngr.pot trunk/src/dirmngr-client.c trunk/src/http.c Log: Escape spaces in URLs Modified: trunk/doc/dirmngr.texi =================================================================== --- trunk/doc/dirmngr.texi 2009-07-31 13:10:43 UTC (rev 320) +++ trunk/doc/dirmngr.texi 2009-07-31 13:36:49 UTC (rev 321) @@ -1000,7 +1000,7 @@ @item --load-crl @opindex load-crl This command expects a list of filenames with DER encoded CRL files. -With the option @option{--url} URLs are expected in palce of filenames +With the option @option{--url} URLs are expected in place of filenames and they are loaded directly from the given location. All CRLs will be validated and then loaded into dirmngr's cache. Modified: trunk/po/de.po [not shown] Modified: trunk/po/dirmngr.pot =================================================================== --- trunk/po/dirmngr.pot 2009-07-31 13:10:43 UTC (rev 320) +++ trunk/po/dirmngr.pot 2009-07-31 13:36:49 UTC (rev 321) @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: gpa-dev at gnupg.org\n" -"POT-Creation-Date: 2009-07-31 13:57+0200\n" +"POT-Creation-Date: 2009-07-31 14:26+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1563,7 +1563,7 @@ "not valid and other error codes for general failures\n" msgstr "" -#: src/dirmngr-client.c:285 src/dirmngr-client.c:1005 +#: src/dirmngr-client.c:285 src/dirmngr-client.c:1004 #, c-format msgid "error reading certificate from stdin: %s\n" msgstr "" @@ -1596,15 +1596,15 @@ msgid "validation of certificate failed: %s\n" msgstr "" -#: src/dirmngr-client.c:404 src/dirmngr-client.c:1016 +#: src/dirmngr-client.c:404 src/dirmngr-client.c:1015 msgid "certificate is valid\n" msgstr "" -#: src/dirmngr-client.c:410 src/dirmngr-client.c:1024 +#: src/dirmngr-client.c:410 src/dirmngr-client.c:1023 msgid "certificate has been revoked\n" msgstr "" -#: src/dirmngr-client.c:415 src/dirmngr-client.c:1026 +#: src/dirmngr-client.c:415 src/dirmngr-client.c:1025 #, c-format msgid "certificate check failed: %s\n" msgstr "" @@ -1650,11 +1650,11 @@ msgid "unsupported inquiry `%s'\n" msgstr "" -#: src/dirmngr-client.c:906 +#: src/dirmngr-client.c:903 msgid "absolute file name expected\n" msgstr "" -#: src/dirmngr-client.c:949 +#: src/dirmngr-client.c:948 #, c-format msgid "looking up `%s'\n" msgstr "" Modified: trunk/src/dirmngr-client.c =================================================================== --- trunk/src/dirmngr-client.c 2009-07-31 13:10:43 UTC (rev 320) +++ trunk/src/dirmngr-client.c 2009-07-31 13:36:49 UTC (rev 321) @@ -884,10 +884,7 @@ char *fname, *line, *p; if (opt.url) - { - line = xmalloc (8+6+ strlen (filename) + 1); - strcpy (stpcpy (line, "LOADCRL --url "), filename?filename:""); - } + fname = xstrdup (filename); else { #ifdef HAVE_CANONICALIZE_FILE_NAME @@ -906,23 +903,25 @@ log_error (_("absolute file name expected\n")); return gpg_error (GPG_ERR_GENERAL); } - - line = xmalloc (8+ strlen (fname) * 3 + 1); - p = stpcpy (line, "LOADCRL "); - for (s = fname; *s; s++) + } + + line = xmalloc (8 + 6 + strlen (fname) * 3 + 1); + p = stpcpy (line, "LOADCRL "); + if (opt.url) + p = stpcpy (p, "--url "); + for (s = fname; *s; s++) + { + if (*s < ' ' || *s == '+') { - if (*s < ' ' || *s == '+') - { - sprintf (p, "%%%02X", *s); - p += 3; - } - else if (*s == ' ') - *p++ = '+'; - else - *p++ = *s; + sprintf (p, "%%%02X", *s); + p += 3; } - *p = 0; - } + else if (*s == ' ') + *p++ = '+'; + else + *p++ = *s; + } + *p = 0; err = assuan_transact (ctx, line, NULL, NULL, NULL, NULL, Modified: trunk/src/http.c =================================================================== --- trunk/src/http.c 2009-07-31 13:10:43 UTC (rev 320) +++ trunk/src/http.c 2009-07-31 13:36:49 UTC (rev 321) @@ -1770,7 +1770,7 @@ uri = NULL; rc = http_open_document (&hd, *argv, NULL, - HTTP_FLAG_NO_SHUTDOWN | HTTP_FLAG_NEED_HEADER, + HTTP_FLAG_NEED_HEADER, NULL, tls_session); if (rc) { @@ -1805,7 +1805,7 @@ #endif /*TEST*/ /* -Saved Local Variables: +Local Variables: compile-command: "gcc -I.. -I../gl -DTEST -DHAVE_CONFIG_H -Wall -O2 -g -o http-test http.c -L. -lcommon -L../jnlib -ljnlib -lgcrypt -lpth -lgnutls" End: */ From cvs at cvs.gnupg.org Fri Jul 31 16:34:55 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Fri, 31 Jul 2009 16:34:55 +0200 Subject: [svn] GnuPG - r5103 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: dshaw Date: 2009-07-31 16:34:55 +0200 (Fri, 31 Jul 2009) New Revision: 5103 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/gpg.c Log: * gpg.c (main): --pgp6 includes --disable-mdc. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-30 16:45:06 UTC (rev 5102) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-07-31 14:34:55 UTC (rev 5103) @@ -1,3 +1,7 @@ +2009-07-31 David Shaw + + * gpg.c (main): --pgp6 includes --disable-mdc. + 2009-07-29 Werner Koch * keygen.c (keygen_set_std_prefs): Remove RMD-160 from the list. Modified: branches/STABLE-BRANCH-1-4/g10/gpg.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/gpg.c 2009-07-30 16:45:06 UTC (rev 5102) +++ branches/STABLE-BRANCH-1-4/g10/gpg.c 2009-07-31 14:34:55 UTC (rev 5103) @@ -3058,6 +3058,7 @@ } else if(PGP6) { + opt.disable_mdc=1; opt.escape_from=1; opt.force_v3_sigs=1; opt.ask_sig_expire=0; From cvs at cvs.gnupg.org Fri Jul 31 16:36:22 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Fri, 31 Jul 2009 16:36:22 +0200 Subject: [svn] GnuPG - r5104 - trunk/doc Message-ID: Author: dshaw Date: 2009-07-31 16:36:22 +0200 (Fri, 31 Jul 2009) New Revision: 5104 Modified: trunk/doc/ChangeLog trunk/doc/gpg.texi Log: * gpg.texi (OpenPGP Options): Don't mention --no-sk-comment (doesn't exist any longer). Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-07-31 14:34:55 UTC (rev 5103) +++ trunk/doc/ChangeLog 2009-07-31 14:36:22 UTC (rev 5104) @@ -1,3 +1,8 @@ +2009-07-31 David Shaw + + * gpg.texi (OpenPGP Options): Don't mention + --no-sk-comment (doesn't exist any longer). + 2009-07-23 David Shaw * gpg.texi (GPG Configuration Options): LDAP uses DNS-SD to locate Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2009-07-31 14:34:55 UTC (rev 5103) +++ trunk/doc/gpg.texi 2009-07-31 14:36:22 UTC (rev 5104) @@ -2062,9 +2062,9 @@ available, but the MIT release is a good common baseline. This option implies @option{--rfc1991 --disable-mdc ---no-force-v4-certs --no-sk-comment --escape-from-lines ---force-v3-sigs --cipher-algo IDEA --digest-algo MD5 --compress-algo -ZIP}. It also disables @option{--textmode} when encrypting. +--no-force-v4-certs --escape-from-lines --force-v3-sigs --cipher-algo +IDEA --digest-algo MD5 --compress-algo ZIP}. It also disables + at option{--textmode} when encrypting. @item --pgp6 @opindex pgp6 @@ -2075,8 +2075,8 @@ --throw-keyids, and making signatures with signing subkeys as PGP 6 does not understand signatures made by signing subkeys. -This option implies @option{--disable-mdc --no-sk-comment ---escape-from-lines --force-v3-sigs}. +This option implies @option{--disable-mdc --escape-from-lines +--force-v3-sigs}. @item --pgp7 @opindex pgp7 From cvs at cvs.gnupg.org Fri Jul 31 16:37:00 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Fri, 31 Jul 2009 16:37:00 +0200 Subject: [svn] GnuPG - r5105 - trunk/g10 Message-ID: Author: dshaw Date: 2009-07-31 16:36:59 +0200 (Fri, 31 Jul 2009) New Revision: 5105 Modified: trunk/g10/ChangeLog trunk/g10/gpg.c Log: * gpg.c (main): --pgp6 includes --disable-mdc. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-07-31 14:36:22 UTC (rev 5104) +++ trunk/g10/ChangeLog 2009-07-31 14:36:59 UTC (rev 5105) @@ -1,3 +1,7 @@ +2009-07-31 David Shaw + + * gpg.c (main): --pgp6 includes --disable-mdc. + 2009-07-23 David Shaw * keyserver.c (keyserver_import_ldap): Try a DNS-SD lookup to find Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2009-07-31 14:36:22 UTC (rev 5104) +++ trunk/g10/gpg.c 2009-07-31 14:36:59 UTC (rev 5105) @@ -3112,6 +3112,7 @@ } else if(PGP6) { + opt.disable_mdc=1; opt.escape_from=1; opt.force_v3_sigs=1; opt.ask_sig_expire=0;