From cvs at cvs.gnupg.org Mon Feb 2 11:57:44 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 02 Feb 2009 11:57:44 +0100 Subject: [svn] gcry - r1387 - trunk/src Message-ID: Author: wk Date: 2009-02-02 11:57:44 +0100 (Mon, 02 Feb 2009) New Revision: 1387 Modified: trunk/src/ChangeLog trunk/src/ath.h Log: fix for bug#993. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-01-26 09:58:18 UTC (rev 1386) +++ trunk/src/ChangeLog 2009-02-02 10:57:44 UTC (rev 1387) @@ -1,3 +1,7 @@ +2009-02-02 Werner Koch + + * ath.h: Include sys/time.h. Fixes bug#993. + 2009-01-22 Werner Koch * fips.c (_gcry_initialize_fips_mode): Remove superfluous const @@ -2100,7 +2104,7 @@ Copyright (C) 1998,1999,2000,2001,2002,2003 - 2004, 2005, 2008 Free Software Foundation, Inc. + 2004, 2005, 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/src/ath.h =================================================================== --- trunk/src/ath.h 2009-01-26 09:58:18 UTC (rev 1386) +++ trunk/src/ath.h 2009-02-02 10:57:44 UTC (rev 1387) @@ -29,6 +29,8 @@ #endif #include +#include /* Required by Interix. */ + #include From cvs at cvs.gnupg.org Mon Feb 2 11:58:10 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 02 Feb 2009 11:58:10 +0100 Subject: [svn] gcry - r1388 - branches/LIBGCRYPT-1-4-BRANCH/src Message-ID: Author: wk Date: 2009-02-02 11:58:10 +0100 (Mon, 02 Feb 2009) New Revision: 1388 Modified: branches/LIBGCRYPT-1-4-BRANCH/src/ChangeLog branches/LIBGCRYPT-1-4-BRANCH/src/ath.h Log: Fix for bug#993. Modified: branches/LIBGCRYPT-1-4-BRANCH/src/ChangeLog =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/src/ChangeLog 2009-02-02 10:57:44 UTC (rev 1387) +++ branches/LIBGCRYPT-1-4-BRANCH/src/ChangeLog 2009-02-02 10:58:10 UTC (rev 1388) @@ -1,3 +1,7 @@ +2009-02-02 Werner Koch + + * ath.h: Include sys/time.h. Fixes bug#993. + 2009-01-22 Werner Koch * fips.c (_gcry_initialize_fips_mode): Remove superfluous const Modified: branches/LIBGCRYPT-1-4-BRANCH/src/ath.h =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/src/ath.h 2009-02-02 10:57:44 UTC (rev 1387) +++ branches/LIBGCRYPT-1-4-BRANCH/src/ath.h 2009-02-02 10:58:10 UTC (rev 1388) @@ -29,6 +29,8 @@ #endif #include +#include /* Required by Interix. */ + #include From cvs at cvs.gnupg.org Tue Feb 3 11:56:02 2009 From: cvs at cvs.gnupg.org (cvs user werner) Date: Tue, 03 Feb 2009 11:56:02 +0100 Subject: misc-scripts (sks-stats.sh) Message-ID: Date: Tuesday, February 3, 2009 @ 11:56:02 Author: werner Path: /cvs/wk/misc-scripts Modified: sks-stats.sh Add failed hosts support + From cvs at cvs.gnupg.org Tue Feb 3 12:00:58 2009 From: cvs at cvs.gnupg.org (cvs user werner) Date: Tue, 03 Feb 2009 12:00:58 +0100 Subject: misc-scripts (sks-stats.sh) Message-ID: Date: Tuesday, February 3, 2009 @ 12:00:58 Author: werner Path: /cvs/wk/misc-scripts Modified: sks-stats.sh First fix From cvs at cvs.gnupg.org Tue Feb 3 13:51:41 2009 From: cvs at cvs.gnupg.org (cvs user werner) Date: Tue, 03 Feb 2009 13:51:41 +0100 Subject: misc-scripts (sks-stats.sh) Message-ID: Date: Tuesday, February 3, 2009 @ 13:51:41 Author: werner Path: /cvs/wk/misc-scripts Modified: sks-stats.sh Split it up into two tables and allow a hosts file From cvs at cvs.gnupg.org Tue Feb 3 20:40:29 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Tue, 03 Feb 2009 20:40:29 +0100 Subject: [svn] GnuPG - r4924 - branches/STABLE-BRANCH-1-4/keyserver Message-ID: Author: dshaw Date: 2009-02-03 20:40:28 +0100 (Tue, 03 Feb 2009) New Revision: 4924 Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c Log: * gpgkeys_hkp.c (send_key, get_key, get_name, search_key, main): Add support for SSLized HKP. Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-01-28 14:18:40 UTC (rev 4923) +++ branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-02-03 19:40:28 UTC (rev 4924) @@ -1,3 +1,8 @@ +2009-02-03 David Shaw + + * gpgkeys_hkp.c (send_key, get_key, get_name, search_key, main): + Add support for SSLized HKP. + 2008-11-18 David Shaw * curl-shim.h, gpgkeys_curl.c, gpgkeys_hkp.c (main): Always show Modified: branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-01-28 14:18:40 UTC (rev 4923) +++ branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-02-03 19:40:28 UTC (rev 4924) @@ -1,6 +1,6 @@ /* gpgkeys_hkp.c - talk to an HKP keyserver - * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, - * 2008 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + * 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -54,6 +54,7 @@ static CURL *curl; static struct ks_options *opt; static char errorbuffer[CURL_ERROR_SIZE]; +static char *proto,*port; static size_t curl_mrindex_writer(const void *ptr,size_t size,size_t nmemb,void *stream) @@ -186,13 +187,10 @@ strcpy(key,"keytext="); strcat(key,encoded_key); - strcpy(request,"http://"); + strcpy(request,proto); strcat(request,opt->host); strcat(request,":"); - if(opt->port) - strcat(request,opt->port); - else - strcat(request,"11371"); + strcat(request,port); strcat(request,opt->path); /* request is MAX_URL+15 bytes long - MAX_URL covers the whole URL, including any supplied path. The 15 covers /pks/add. */ @@ -253,13 +251,10 @@ return KEYSERVER_NOT_SUPPORTED; } - strcpy(request,"http://"); + strcpy(request,proto); strcat(request,opt->host); strcat(request,":"); - if(opt->port) - strcat(request,opt->port); - else - strcat(request,"11371"); + strcat(request,port); strcat(request,opt->path); /* request is MAX_URL+55 bytes long - MAX_URL covers the whole URL, including any supplied path. The 60 overcovers this /pks/... etc @@ -334,13 +329,10 @@ fprintf(output,"NAME %s BEGIN\n",getkey); - strcpy(request,"http://"); + strcpy(request,proto); strcat(request,opt->host); strcat(request,":"); - if(opt->port) - strcat(request,opt->port); - else - strcat(request,"11371"); + strcat(request,port); strcat(request,opt->path); append_path(request,"/pks/lookup?op=get&options=mr&search="); strcat(request,searchkey_encoded); @@ -420,13 +412,10 @@ fprintf(output,"SEARCH %s BEGIN\n",searchkey); - strcpy(request,"http://"); + strcpy(request,proto); strcat(request,opt->host); strcat(request,":"); - if(opt->port) - strcat(request,opt->port); - else - strcat(request,"11371"); + strcat(request,port); strcat(request,opt->path); append_path(request,"/pks/lookup?op=index&options=mr&search="); @@ -633,6 +622,28 @@ } } + + if(!opt->scheme) + { + fprintf(console,"gpgkeys: no scheme supplied!\n"); + ret=KEYSERVER_SCHEME_NOT_FOUND; + goto fail; + } + + if(ascii_strcasecmp(opt->scheme,"hkps")==0) + { + proto="https://"; + port="11372"; + } + else + { + proto="http://"; + port="11371"; + } + + if(opt->port) + port=opt->port; + if(!opt->host) { fprintf(console,"gpgkeys: no keyserver host provided\n"); @@ -666,6 +677,9 @@ curl_easy_setopt(curl,CURLOPT_VERBOSE,1L); } + curl_easy_setopt(curl,CURLOPT_SSL_VERIFYPEER,(long)opt->flags.check_cert); + curl_easy_setopt(curl,CURLOPT_CAINFO,opt->ca_cert_file); + if(proxy) curl_easy_setopt(curl,CURLOPT_PROXY,proxy); From cvs at cvs.gnupg.org Tue Feb 3 20:49:18 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Tue, 03 Feb 2009 20:49:18 +0100 Subject: [svn] GnuPG - r4925 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: dshaw Date: 2009-02-03 20:49:17 +0100 (Tue, 03 Feb 2009) New Revision: 4925 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/keyserver.c Log: * keyserver.c (keyserver_typemap): gpgkeys_hkp handles hkps as well. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-02-03 19:40:28 UTC (rev 4924) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-02-03 19:49:17 UTC (rev 4925) @@ -1,3 +1,8 @@ +2009-02-03 David Shaw + + * keyserver.c (keyserver_typemap): gpgkeys_hkp handles hkps as + well. + 2008-12-21 David Shaw * gpg.c (main): Properly handle UTF8 usernames with --sign-key and Modified: branches/STABLE-BRANCH-1-4/g10/keyserver.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keyserver.c 2009-02-03 19:40:28 UTC (rev 4924) +++ branches/STABLE-BRANCH-1-4/g10/keyserver.c 2009-02-03 19:49:17 UTC (rev 4925) @@ -1,6 +1,6 @@ /* keyserver.c - generic keyserver code - * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, - * 2007 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, + * 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -927,6 +927,8 @@ { if(strcmp(type,"ldaps")==0) return "ldap"; + else if(strcmp(type,"hkps")==0) + return "hkp"; else return type; } From cvs at cvs.gnupg.org Wed Feb 4 10:51:44 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 04 Feb 2009 10:51:44 +0100 Subject: [svn] gpgme - r1354 - in trunk: . src tests tests/gpg Message-ID: Author: wk Date: 2009-02-04 10:51:43 +0100 (Wed, 04 Feb 2009) New Revision: 1354 Modified: trunk/NEWS trunk/src/ChangeLog trunk/src/gpgme.h.in trunk/src/key.c trunk/src/keylist.c trunk/tests/ChangeLog trunk/tests/gpg/t-keylist.c Log: Provide inforation about smartcards. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-01-26 10:21:10 UTC (rev 1353) +++ trunk/src/ChangeLog 2009-02-04 09:51:43 UTC (rev 1354) @@ -1,3 +1,11 @@ +2009-02-03 Werner Koch + + * gpgme.h.in (struct _gpgme_subkey): Add fields IS_CARDKEY and + CARD_NUMBER.. + * key.c (gpgme_key_unref): Release field CARD_NUMBER. + * keylist.c (keylist_colon_handler): Factor common code out to ... + (parse_sec_field15): New. Set card number. + 2009-01-26 Werner Koch * opassuan.c, dirinfo.c, engine-assuan.c: New. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-01-26 10:21:10 UTC (rev 1353) +++ trunk/tests/ChangeLog 2009-02-04 09:51:43 UTC (rev 1354) @@ -1,3 +1,8 @@ +2009-02-03 Werner Koch + + * gpg/t-keylist.c (main): Check that new fields is_cardkey and + card_number are not set. + 2009-01-26 Werner Koch * opassuan/: New. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-26 10:21:10 UTC (rev 1353) +++ trunk/NEWS 2009-02-04 09:51:43 UTC (rev 1354) @@ -11,6 +11,7 @@ gpgme_op_assuan_transact_start NEW. gpgme_op_assuan_transact NEW. gpgme_op_assuan_result NEW. + gpgme_subkey_t EXTENDED: New fields is_cardkey, card_number. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Modified: trunk/src/gpgme.h.in =================================================================== --- trunk/src/gpgme.h.in 2009-01-26 10:21:10 UTC (rev 1353) +++ trunk/src/gpgme.h.in 2009-02-04 09:51:43 UTC (rev 1354) @@ -519,8 +519,11 @@ /* True if subkey is qualified for signatures according to German law. */ unsigned int is_qualified : 1; + /* True if the secret key is stored on a smart card. */ + unsigned int is_cardkey : 1; + /* Internal to GPGME, do not use. */ - unsigned int _unused : 22; + unsigned int _unused : 21; /* Public key algorithm supported by this subkey. */ gpgme_pubkey_algo_t pubkey_algo; @@ -542,6 +545,9 @@ /* The expiration timestamp, 0 if the subkey does not expire. */ long int expires; + + /* The serial number of a smart card holding this key or NULL. */ + char *card_number; }; typedef struct _gpgme_subkey *gpgme_subkey_t; Modified: trunk/src/key.c =================================================================== --- trunk/src/key.c 2009-01-26 10:21:10 UTC (rev 1353) +++ trunk/src/key.c 2009-02-04 09:51:43 UTC (rev 1354) @@ -327,6 +327,8 @@ gpgme_subkey_t next = subkey->next; if (subkey->fpr) free (subkey->fpr); + if (subkey->card_number) + free (subkey->card_number); free (subkey); subkey = next; } Modified: trunk/src/keylist.c =================================================================== --- trunk/src/keylist.c 2009-01-26 10:21:10 UTC (rev 1353) +++ trunk/src/keylist.c 2009-02-04 09:51:43 UTC (rev 1354) @@ -1,7 +1,7 @@ /* keylist.c - Listing keys. Copyright (C) 2000 Werner Koch (dd9jn) Copyright (C) 2001, 2002, 2003, 2004, 2006, 2007, - 2008 g10 Code GmbH + 2008, 2009 g10 Code GmbH This file is part of GPGME. @@ -351,6 +351,38 @@ } +/* Parse field 15 of a secret key or subkey. This fields holds a + reference to smartcards. FIELD is the content of the field and we + are allowed to modify it. */ +static gpg_error_t +parse_sec_field15 (gpgme_subkey_t subkey, char *field) +{ + if (!*field) + ; /* Empty. */ + else if (*field == '#') + { + /* This is a stub for an offline key. We reset the SECRET flag + of the subkey here. Note that the secret flag of the entire + key will be true even then. */ + subkey->secret = 0; + } + else if (strchr ("01234567890ABCDEFabcdef", *field)) + { + /* Fields starts with a hex digit; thus it is a serial number. */ + subkey->is_cardkey = 1; + subkey->card_number = strdup (field); + if (!subkey->card_number) + return gpg_error_from_syserror (); + } + else + { + /* RFU. */ + } + + return 0; +} + + /* We have read an entire key into tmp_key and should now finish it. It is assumed that this releases tmp_key. */ static void @@ -533,12 +565,13 @@ if (fields >= 12) set_mainkey_capability (key, field[11]); - /* Field 15 carries special flags of a secret key. We reset the - SECRET flag of a subkey here if the key is actually only a - stub. The SECRET flag of the key will be true even then. */ + /* Field 15 carries special flags of a secret key. */ if (fields >= 15 && key->secret) - if (*field[14] == '#') - subkey->secret = 0; + { + err = parse_sec_field15 (subkey, field[14]); + if (err) + return err; + } break; case RT_SUB: @@ -596,8 +629,11 @@ /* Field 15 carries special flags of a secret key. */ if (fields >= 15 && key->secret) - if (*field[14] == '#') - subkey->secret = 0; + { + err = parse_sec_field15 (subkey, field[14]); + if (err) + return err; + } break; case RT_UID: Modified: trunk/tests/gpg/t-keylist.c =================================================================== --- trunk/tests/gpg/t-keylist.c 2009-01-26 10:21:10 UTC (rev 1353) +++ trunk/tests/gpg/t-keylist.c 2009-02-04 09:51:43 UTC (rev 1354) @@ -270,6 +270,16 @@ fprintf (stderr, "Primary key unexpectedly secret\n"); exit (1); } + if (key->subkeys->is_cardkey) + { + fprintf (stderr, "Public key marked as card key\n"); + exit (1); + } + if (key->subkeys->card_number) + { + fprintf (stderr, "Public key with card number set\n"); + exit (1); + } if (key->subkeys->pubkey_algo != GPGME_PK_DSA) { fprintf (stderr, "Primary key has unexpected public key algo: %s\n", @@ -342,6 +352,16 @@ fprintf (stderr, "Secondary key unexpectedly secret\n"); exit (1); } + if (key->subkeys->next->is_cardkey) + { + fprintf (stderr, "Secondary public key marked as card key\n"); + exit (1); + } + if (key->subkeys->next->card_number) + { + fprintf (stderr, "Secondary public key with card number set\n"); + exit (1); + } if (key->subkeys->next->pubkey_algo != GPGME_PK_ELG_E) { fprintf (stderr, "Secondary key has unexpected public key algo: %s\n", From cvs at cvs.gnupg.org Wed Feb 4 17:42:25 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 04 Feb 2009 17:42:25 +0100 Subject: [svn] gpgme - r1355 - tags Message-ID: Author: wk Date: 2009-02-04 17:42:25 +0100 (Wed, 04 Feb 2009) New Revision: 1355 Added: tags/gpgme-1.1.8/ Log: Add tag for the last release. From cvs at cvs.gnupg.org Wed Feb 4 17:48:26 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 04 Feb 2009 17:48:26 +0100 Subject: [svn] gpgme - r1356 - trunk/src Message-ID: Author: wk Date: 2009-02-04 17:48:25 +0100 (Wed, 04 Feb 2009) New Revision: 1356 Modified: trunk/src/ChangeLog trunk/src/w32-glib-io.c trunk/src/w32-qt-io.cpp Log: Fix spawn prototype for w32 glib and qt versions. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-02-04 16:42:25 UTC (rev 1355) +++ trunk/src/ChangeLog 2009-02-04 16:48:25 UTC (rev 1356) @@ -1,3 +1,9 @@ +2009-02-04 Werner Koch + + * w32-glib-io.c (_gpgme_io_spawn): Make ARGV argument const to + match prototype. + * w32-qt-io.cpp (_gpgme_io_spawn): Ditto. + 2009-02-03 Werner Koch * gpgme.h.in (struct _gpgme_subkey): Add fields IS_CARDKEY and Modified: trunk/src/w32-glib-io.c =================================================================== --- trunk/src/w32-glib-io.c 2009-02-04 16:42:25 UTC (rev 1355) +++ trunk/src/w32-glib-io.c 2009-02-04 16:48:25 UTC (rev 1356) @@ -448,7 +448,7 @@ int -_gpgme_io_spawn (const char *path, char **argv, +_gpgme_io_spawn (const char *path, char * const argv[], struct spawn_fd_item_s *fd_list, pid_t *r_pid) { SECURITY_ATTRIBUTES sec_attr; Modified: trunk/src/w32-qt-io.cpp =================================================================== --- trunk/src/w32-qt-io.cpp 2009-02-04 16:42:25 UTC (rev 1355) +++ trunk/src/w32-qt-io.cpp 2009-02-04 16:48:25 UTC (rev 1356) @@ -397,7 +397,7 @@ int -_gpgme_io_spawn (const char *path, char **argv, +_gpgme_io_spawn (const char *path, char * const argv[], struct spawn_fd_item_s *fd_list, pid_t *r_pid) { SECURITY_ATTRIBUTES sec_attr; From cvs at cvs.gnupg.org Mon Feb 9 11:25:41 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 09 Feb 2009 11:25:41 +0100 Subject: [svn] GnuPG - r4926 - in trunk: . scd sm Message-ID: Author: wk Date: 2009-02-09 11:25:41 +0100 (Mon, 09 Feb 2009) New Revision: 4926 Modified: trunk/NEWS trunk/scd/atr.c trunk/scd/command.c trunk/sm/ChangeLog Log: Change default gpgsm cipher back to 3DES. Typo fixes. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-02-03 19:49:17 UTC (rev 4925) +++ trunk/sm/ChangeLog 2009-02-09 10:25:41 UTC (rev 4926) @@ -1,3 +1,7 @@ +2009-02-09 Werner Koch + + * gpgsm.c (main): Change default cipher back to 3DES. + 2009-01-12 Werner Koch * keylist.c (print_utf8_extn_raw): Cast printf precision argument. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-02-03 19:49:17 UTC (rev 4925) +++ trunk/NEWS 2009-02-09 10:25:41 UTC (rev 4926) @@ -1,9 +1,15 @@ Noteworthy changes in version 2.0.11 (unreleased) ------------------------------------------------- - * [scdaemon] --allow-admin is now the default. + * The SCDAEMON option --allow-admin is now used by default. + * SCDAEMON is now aware of the Geldkarte. + * [gpgsm] The default cipher algorith is now again 3DES. This is due + to interoperability problems with Outlook 2003 which still can't + cope with AES. + + Noteworthy changes in version 2.0.10 (2009-01-12) ------------------------------------------------- Modified: trunk/scd/atr.c =================================================================== --- trunk/scd/atr.c 2009-02-03 19:49:17 UTC (rev 4925) +++ trunk/scd/atr.c 2009-02-09 10:25:41 UTC (rev 4926) @@ -278,7 +278,7 @@ /* Note: This code has not yet been tested! It shall return -1 on - error or the nu,ber of hiostroical bytes and store them at + error or the number of historical bytes and store them at HISTORICAL. */ int atr_get_historical (int slot, unsigned char historical[]) Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2009-02-03 19:49:17 UTC (rev 4925) +++ trunk/scd/command.c 2009-02-09 10:25:41 UTC (rev 4926) @@ -469,7 +469,7 @@ /* SERIALNO [APPTYPE] Return the serial number of the card using a status reponse. This - functon should be used to check for the presence of a card. + function should be used to check for the presence of a card. If APPTYPE is given, an application of that type is selected and an error is returned if the application is not supported or available. From cvs at cvs.gnupg.org Mon Feb 9 12:09:58 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 09 Feb 2009 12:09:58 +0100 Subject: [svn] GnuPG - r4927 - in trunk: g10 sm Message-ID: Author: wk Date: 2009-02-09 12:09:57 +0100 (Mon, 09 Feb 2009) New Revision: 4927 Modified: trunk/g10/ChangeLog trunk/g10/keyedit.c trunk/g10/keylist.c trunk/sm/gpgsm.c Log: Fix bug#998. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-02-09 10:25:41 UTC (rev 4926) +++ trunk/g10/ChangeLog 2009-02-09 11:09:57 UTC (rev 4927) @@ -1,3 +1,9 @@ +2009-02-09 Werner Koch + + * keylist.c (print_capabilities): Take care of cert-only keys. + Fixes bug#998. + * keyedit.c (show_key_with_all_names_colon): Print the capabilities. + 2009-01-26 Werner Koch * card-util.c (card_status): Detect a Geldkarte. Modified: trunk/g10/keyedit.c =================================================================== --- trunk/g10/keyedit.c 2009-02-09 10:25:41 UTC (rev 4926) +++ trunk/g10/keyedit.c 2009-02-09 11:09:57 UTC (rev 4927) @@ -2522,6 +2522,17 @@ && !(opt.fast_list_mode || opt.no_expensive_trust_checks )) putchar(get_ownertrust_info (pk)); putchar(':'); + putchar (':'); + putchar (':'); + /* Print capabilities. */ + if ( (pk->pubkey_usage & PUBKEY_USAGE_ENC) ) + putchar ('e'); + if ( (pk->pubkey_usage & PUBKEY_USAGE_SIG) ) + putchar ('s'); + if ( (pk->pubkey_usage & PUBKEY_USAGE_CERT) ) + putchar ('c'); + if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) ) + putchar ('a'); putchar('\n'); print_fingerprint (pk, NULL, 0); Modified: trunk/g10/keylist.c =================================================================== --- trunk/g10/keylist.c 2009-02-09 10:25:41 UTC (rev 4926) +++ trunk/g10/keylist.c 2009-02-09 11:09:57 UTC (rev 4927) @@ -594,6 +594,7 @@ if(pk || (sk && sk->protect.s2k.mode!=1001)) { unsigned int use = pk? pk->pubkey_usage : sk->pubkey_usage; + int c_printed = 0; if ( use & PUBKEY_USAGE_ENC ) putchar ('e'); @@ -602,9 +603,19 @@ { putchar ('s'); if( pk? pk->is_primary : sk->is_primary ) - putchar ('c'); + { + putchar ('c'); + /* The PUBKEY_USAGE_CERT flag was introduced later and + we used to always print 'c' for a primary key. To + avoid any regression here we better track whether we + printed 'c' already. */ + c_printed = 1; + } } + if ( (use & PUBKEY_USAGE_CERT) && !c_printed ) + putchar ('c'); + if ( (use & PUBKEY_USAGE_AUTH) ) putchar ('a'); } @@ -630,6 +641,8 @@ if(pk->is_primary) cert = 1; } + if ( pk->pubkey_usage & PUBKEY_USAGE_CERT ) + cert = 1; if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) ) auth = 1; } @@ -647,6 +660,8 @@ if(sk->is_primary) cert = 1; } + if ( (sk->pubkey_usage & PUBKEY_USAGE_CERT) ) + cert = 1; if ( (sk->pubkey_usage & PUBKEY_USAGE_AUTH) ) auth = 1; } Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2009-02-09 10:25:41 UTC (rev 4926) +++ trunk/sm/gpgsm.c 2009-02-09 11:09:57 UTC (rev 4927) @@ -893,7 +893,7 @@ /* Note: If you change this default cipher algorithm , please remember to update the Gpgconflist entry as well. */ - opt.def_cipher_algoid = "AES"; /*des-EDE3-CBC*/ + opt.def_cipher_algoid = "3DES"; /*des-EDE3-CBC*/ opt.homedir = default_homedir (); @@ -1607,7 +1607,7 @@ #ifndef HAVE_W32_SYSTEM printf ("prefer-system-dirmngr:%lu:\n", GC_OPT_FLAG_NONE); #endif - printf ("cipher-algo:%lu:\"AES:\n", GC_OPT_FLAG_DEFAULT); + printf ("cipher-algo:%lu:\"3DES:\n", GC_OPT_FLAG_DEFAULT); printf ("p12-charset:%lu:\n", GC_OPT_FLAG_DEFAULT); printf ("default-key:%lu:\n", GC_OPT_FLAG_DEFAULT); printf ("encrypt-to:%lu:\n", GC_OPT_FLAG_DEFAULT); From cvs at cvs.gnupg.org Mon Feb 9 12:14:43 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 09 Feb 2009 12:14:43 +0100 Subject: [svn] GnuPG - r4928 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2009-02-09 12:14:42 +0100 (Mon, 09 Feb 2009) New Revision: 4928 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/keylist.c Log: Fix bug 998. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-02-09 11:09:57 UTC (rev 4927) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-02-09 11:14:42 UTC (rev 4928) @@ -1,3 +1,8 @@ +2009-02-09 Werner Koch + + * keylist.c (print_capabilities): Take care of cert-only keys. + Fixes bug#998. + 2009-02-03 David Shaw * keyserver.c (keyserver_typemap): gpgkeys_hkp handles hkps as Modified: branches/STABLE-BRANCH-1-4/g10/keylist.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keylist.c 2009-02-09 11:09:57 UTC (rev 4927) +++ branches/STABLE-BRANCH-1-4/g10/keylist.c 2009-02-09 11:14:42 UTC (rev 4928) @@ -547,7 +547,8 @@ if(pk || (sk && sk->protect.s2k.mode!=1001)) { unsigned int use = pk? pk->pubkey_usage : sk->pubkey_usage; - + int c_printed = 0; + if ( use & PUBKEY_USAGE_ENC ) putchar ('e'); @@ -555,9 +556,19 @@ { putchar ('s'); if( pk? pk->is_primary : sk->is_primary ) - putchar ('c'); + { + putchar ('c'); + /* The PUBKEY_USAGE_CERT flag was introduced later and + we used to always print 'c' for a primary key. To + avoid any regression here we better track whether we + printed 'c' already. */ + c_printed = 1; + } } + if ( (use & PUBKEY_USAGE_CERT) && !c_printed ) + putchar ('c'); + if ( (use & PUBKEY_USAGE_AUTH) ) putchar ('a'); } @@ -583,6 +594,8 @@ if(pk->is_primary) cert = 1; } + if ( pk->pubkey_usage & PUBKEY_USAGE_CERT ) + cert = 1; if ( (pk->pubkey_usage & PUBKEY_USAGE_AUTH) ) auth = 1; } @@ -600,6 +613,8 @@ if(sk->is_primary) cert = 1; } + if ( (sk->pubkey_usage & PUBKEY_USAGE_CERT) ) + cert = 1; if ( (sk->pubkey_usage & PUBKEY_USAGE_AUTH) ) auth = 1; } From cvs at cvs.gnupg.org Wed Feb 11 12:53:54 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 11 Feb 2009 12:53:54 +0100 Subject: [svn] gcry - r1389 - trunk/tests Message-ID: Author: wk Date: 2009-02-11 12:53:54 +0100 (Wed, 11 Feb 2009) New Revision: 1389 Added: trunk/tests/rsacvt.c Modified: trunk/tests/ChangeLog trunk/tests/Makefile.am Log: Add a new helper tool Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-02-02 10:58:10 UTC (rev 1388) +++ trunk/tests/ChangeLog 2009-02-11 11:53:54 UTC (rev 1389) @@ -1,3 +1,7 @@ +2009-02-11 Werner Koch + + * rsacvt.c: New. + 2009-01-22 Werner Koch * cavs_tests.sh: Pass option -D to driver if required. Modified: trunk/tests/Makefile.am =================================================================== --- trunk/tests/Makefile.am 2009-02-02 10:58:10 UTC (rev 1388) +++ trunk/tests/Makefile.am 2009-02-11 11:53:54 UTC (rev 1389) @@ -39,6 +39,6 @@ LDADD = ../src/libgcrypt.la $(DL_LIBS) EXTRA_PROGRAMS = testapi pkbench -noinst_PROGRAMS = $(TESTS) fipsdrv +noinst_PROGRAMS = $(TESTS) fipsdrv rsacvt EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl Added: trunk/tests/rsacvt.c =================================================================== --- trunk/tests/rsacvt.c (rev 0) +++ trunk/tests/rsacvt.c 2009-02-11 11:53:54 UTC (rev 1389) @@ -0,0 +1,407 @@ +/* rsacvt.c - A debug tool to convert RSA formats. + Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of Libgcrypt. + + Libgcrypt 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. + + Libgcrypt 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 . + */ + +/* Input data format: + +======= +# A hash denotes a comment line +e861b700e17e8afe68[...]f1 +f7a7ca5367c661f8e6[...]61 +10001 + +# After an empty line another input block may follow. +7861b700e17e8afe68[...]f3 +e7a7ca5367c661f8e6[...]71 +3 +========= + +*/ + + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include +#include +#include +#ifdef HAVE_W32_SYSTEM +# include /* We need setmode(). */ +#else +# include +#endif +#include +#include + +#ifdef _GCRYPT_IN_LIBGCRYPT +# include "../src/gcrypt.h" +#else +# include +# define PACKAGE_BUGREPORT "devnull at example.org" +# define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]" +#endif + + +#define PGM "rsacvt" + +#define my_isascii(c) (!((c) & 0x80)) +#define digitp(p) (*(p) >= '0' && *(p) <= '9') +#define hexdigitp(a) (digitp (a) \ + || (*(a) >= 'A' && *(a) <= 'F') \ + || (*(a) >= 'a' && *(a) <= 'f')) +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) +#define DIM(v) (sizeof(v)/sizeof((v)[0])) +#define DIMof(type,member) DIM(((type *)0)->member) + + +/* Verbose mode flag. */ +static int verbose; + +/* Prefix output with labels. */ +static int with_labels; + +/* Do not suppress leading zeroes. */ +static int keep_lz; + + +/* Print a error message and exit the process with an error code. */ +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + fputs (PGM ": ", stderr); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + +static char * +read_textline (FILE *fp) +{ + char line[4096]; + char *p; + int any = 0; + + /* Read line but skip over initial empty lines. */ + do + { + do + { + if (!fgets (line, sizeof line, fp)) + { + if (feof (fp)) + return NULL; + die ("error reading input line: %s\n", strerror (errno)); + } + p = strchr (line, '\n'); + if (p) + *p = 0; + p = line + (*line? (strlen (line)-1):0); + for ( ;p > line; p--) + if (my_isascii (*p) && isspace (*p)) + *p = 0; + } + while (!any && !*line); + any = 1; + } + while (*line == '#'); /* Always skip comment lines. */ + if (verbose > 1) + fprintf (stderr, PGM ": received line: %s\n", line); + return gcry_xstrdup (line); +} + + +static gcry_mpi_t +read_hexmpi_line (FILE *fp, int *got_eof) +{ + gpg_error_t err; + gcry_mpi_t a; + char *line; + + *got_eof = 0; + line = read_textline (fp); + if (!line) + { + *got_eof = 1; + return NULL; + } + err = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, line, 0, NULL); + gcry_free (line); + if (err) + a = NULL; + return a; +} + + +static int +skip_to_empty_line (FILE *fp) +{ + char line[256]; + char *p; + + do + { + if (!fgets (line, sizeof line, fp)) + { + if (feof (fp)) + return -1; + die ("error reading input line: %s\n", strerror (errno)); + } + p = strchr (line, '\n'); + if (p) + *p =0; + } + while (*line); + return 0; +} + + +/* Print an MPI on a line. */ +static void +print_mpi_line (const char *label, gcry_mpi_t a) +{ + unsigned char *buf, *p; + gcry_error_t err; + int writerr = 0; + + if (with_labels && label) + printf ("%s = ", label); + + err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a); + if (err) + die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); + + p = buf; + if (!keep_lz && p[0] == '0' && p[1] == '0' && p[2]) + p += 2; + + printf ("%s\n", p); + if (ferror (stdout)) + writerr++; + if (!writerr && fflush (stdout) == EOF) + writerr++; + if (writerr) + die ("writing output failed: %s\n", strerror (errno)); + gcry_free (buf); +} + + +/* Compute and print missing RSA parameters. */ +static void +compute_missing (gcry_mpi_t rsa_p, gcry_mpi_t rsa_q, gcry_mpi_t rsa_e) +{ + gcry_mpi_t rsa_n, rsa_d, rsa_pm1, rsa_qm1, rsa_u; + gcry_mpi_t phi, tmp_g, tmp_f; + + rsa_n = gcry_mpi_new (0); + rsa_d = gcry_mpi_new (0); + rsa_pm1 = gcry_mpi_new (0); + rsa_qm1 = gcry_mpi_new (0); + rsa_u = gcry_mpi_new (0); + + phi = gcry_mpi_new (0); + tmp_f = gcry_mpi_new (0); + tmp_g = gcry_mpi_new (0); + + /* Check that p < q; if not swap p and q. */ + if (gcry_mpi_cmp (rsa_p, rsa_q) > 0) + { + fprintf (stderr, PGM ": swapping p and q\n"); + gcry_mpi_swap (rsa_p, rsa_q); + } + + gcry_mpi_mul (rsa_n, rsa_p, rsa_q); + + + /* Compute the Euler totient: phi = (p-1)(q-1) */ + gcry_mpi_sub_ui (rsa_pm1, rsa_p, 1); + gcry_mpi_sub_ui (rsa_qm1, rsa_q, 1); + gcry_mpi_mul (phi, rsa_pm1, rsa_qm1); + + if (!gcry_mpi_gcd (tmp_g, rsa_e, phi)) + die ("parameter 'e' does match 'p' and 'q'\n"); + + /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */ + gcry_mpi_gcd (tmp_g, rsa_pm1, rsa_qm1); + gcry_mpi_div (tmp_f, NULL, phi, tmp_g, -1); + + /* Compute the secret key: d = e^{-1} mod lcm(p-1,q-1) */ + gcry_mpi_invm (rsa_d, rsa_e, tmp_f); + + /* Compute the CRT helpers: d mod (p-1), d mod (q-1) */ + gcry_mpi_mod (rsa_pm1, rsa_d, rsa_pm1); + gcry_mpi_mod (rsa_qm1, rsa_d, rsa_pm1); + + /* Compute the CRT value: u = p^{-1} mod q */ + gcry_mpi_invm (rsa_u, rsa_p, rsa_q); + + gcry_mpi_release (phi); + gcry_mpi_release (tmp_f); + gcry_mpi_release (tmp_g); + + /* Print everything. */ + print_mpi_line ("n", rsa_n); + print_mpi_line ("e", rsa_e); + print_mpi_line ("d", rsa_d); + print_mpi_line ("p", rsa_p); + print_mpi_line ("q", rsa_q); + print_mpi_line ("dmp1", rsa_pm1); + print_mpi_line ("dmq1", rsa_qm1); + print_mpi_line ("u", rsa_u); + + gcry_mpi_release (rsa_n); + gcry_mpi_release (rsa_d); + gcry_mpi_release (rsa_pm1); + gcry_mpi_release (rsa_qm1); + gcry_mpi_release (rsa_u); +} + + + +static void +usage (int show_help) +{ + if (!show_help) + { + fputs ("usage: " PGM + " [OPTION] [FILE] (try --help for more information)\n", stderr); + exit (2); + } + fputs + ("Usage: " PGM " [OPTIONS] [FILE]\n" + "Take RSA parameters p, n, e and compute missing parameters.\n" + "OPTIONS:\n" + " --version Print version information\n" + " --verbose Print additional information\n" + " --labels Prefix output with labels\n" + " --keep-lz Keep all leading zeroes in the output\n" + " --help Print this text\n" + "With no FILE, or if FILE is -, read standard input.\n" + "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout); + exit (0); +} + + +int +main (int argc, char **argv) +{ + int last_argc = -1; + FILE *input; + gcry_mpi_t rsa_p, rsa_q, rsa_e; + int got_eof; + int any = 0; + + if (argc) + { argc--; argv++; } + + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + { + usage (1); + } + else if (!strcmp (*argv, "--version")) + { + fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout); + printf ("libgcrypt %s\n", gcry_check_version (NULL)); + exit (0); + } + else if (!strcmp (*argv, "--verbose")) + { + verbose++; + argc--; argv++; + } + else if (!strcmp (*argv, "--labels")) + { + with_labels = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--keep-lz")) + { + keep_lz = 1; + argc--; argv++; + } + } + + if (argc > 1) + usage (0); + +#if !defined (HAVE_W32_SYSTEM) && !defined (_WIN32) + signal (SIGPIPE, SIG_IGN); +#endif + + if (argc == 1 && strcmp (argv[0], "-")) + { + input = fopen (argv[0], "r"); + if (!input) + die ("can't open `%s': %s\n", argv[0], strerror (errno)); + } + else + input = stdin; + + gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); + if (!gcry_check_version ("1.4.0")) + die ("Libgcrypt is not sufficient enough\n"); + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + do + { + rsa_p = read_hexmpi_line (input, &got_eof); + if (!rsa_p && got_eof) + break; + if (!rsa_p) + die ("RSA parameter 'p' missing or not properly hex encoded\n"); + rsa_q = read_hexmpi_line (input, &got_eof); + if (!rsa_q) + die ("RSA parameter 'q' missing or not properly hex encoded\n"); + rsa_e = read_hexmpi_line (input, &got_eof); + if (!rsa_e) + die ("RSA parameter 'e' missing or not properly hex encoded\n"); + got_eof = skip_to_empty_line (input); + + if (any) + putchar ('\n'); + + compute_missing (rsa_p, rsa_q, rsa_e); + + gcry_mpi_release (rsa_p); + gcry_mpi_release (rsa_q); + gcry_mpi_release (rsa_e); + + any = 1; + } + while (!got_eof); + + return 0; +} + From cvs at cvs.gnupg.org Wed Feb 11 23:15:30 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 11 Feb 2009 23:15:30 +0100 Subject: [svn] GpgEX - r64 - trunk/src Message-ID: Author: marcus Date: 2009-02-11 23:15:29 +0100 (Wed, 11 Feb 2009) New Revision: 64 Modified: trunk/src/ChangeLog trunk/src/bitmaps.cc trunk/src/icons.rc Log: 2009-02-11 Marcus Brinkmann * bitmaps.cc (load_bitmap): Change minus to underscore. * icons.rc: Likewise in identifiers. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-01-28 10:27:15 UTC (rev 63) +++ trunk/src/ChangeLog 2009-02-11 22:15:29 UTC (rev 64) @@ -1,3 +1,8 @@ +2009-02-11 Marcus Brinkmann + + * bitmaps.cc (load_bitmap): Change minus to underscore. + * icons.rc: Likewise in identifiers. + 2008-09-01 Marcus Brinkmann * gpgex.cc (Initialize): Also pay attention to endings pem, p7m Modified: trunk/src/bitmaps.cc =================================================================== --- trunk/src/bitmaps.cc 2009-01-28 10:27:15 UTC (rev 63) +++ trunk/src/bitmaps.cc 2009-02-11 22:15:29 UTC (rev 64) @@ -78,7 +78,7 @@ HBITMAP bmap; std::ostringstream out; - out << name << "-" << this->size; + out << name << "_" << this->size; bmap = LoadBitmap (gpgex_server::instance, out.str().c_str()); if (bmap == NULL) (void) TRACE2 (DEBUG_INIT, "gpgex_bitmaps_t::load_bitmap", this, Modified: trunk/src/icons.rc =================================================================== --- trunk/src/icons.rc 2009-01-28 10:27:15 UTC (rev 63) +++ trunk/src/icons.rc 2009-02-11 22:15:29 UTC (rev 64) @@ -1,2 +1,2 @@ -Key-12 BITMAP "icon-key-12.bmp" -Key-16 BITMAP "icon-key-16.bmp" +Key_12 BITMAP "icon-key-12.bmp" +Key_16 BITMAP "icon-key-16.bmp" From cvs at cvs.gnupg.org Thu Feb 12 18:45:41 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 12 Feb 2009 18:45:41 +0100 Subject: [svn] GnuPG - r4929 - in trunk: . keyserver scd Message-ID: Author: wk Date: 2009-02-12 18:45:40 +0100 (Thu, 12 Feb 2009) New Revision: 4929 Modified: trunk/NEWS trunk/README.maint trunk/keyserver/Makefile.am trunk/scd/ChangeLog trunk/scd/command.c Log: New scd getinfo subcommand deny_admin Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-02-09 11:14:42 UTC (rev 4928) +++ trunk/scd/ChangeLog 2009-02-12 17:45:40 UTC (rev 4929) @@ -1,3 +1,7 @@ +2009-02-12 Werner Koch + + * command.c (cmd_getinfo): Add new subcommand "deny_admin". + 2009-01-28 Werner Koch * scdaemon.c (main): Make --allow-admin the default and make the Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-02-09 11:14:42 UTC (rev 4928) +++ trunk/NEWS 2009-02-12 17:45:40 UTC (rev 4929) @@ -5,9 +5,9 @@ * SCDAEMON is now aware of the Geldkarte. - * [gpgsm] The default cipher algorith is now again 3DES. This is due - to interoperability problems with Outlook 2003 which still can't - cope with AES. + * The default cipher algorithm in GPGSM is now again 3DES. This is + due to interoperability problems with Outlook 2003 which still + can't cope with AES. Noteworthy changes in version 2.0.10 (2009-01-12) Modified: trunk/README.maint =================================================================== --- trunk/README.maint 2009-02-09 11:14:42 UTC (rev 4928) +++ trunk/README.maint 2009-02-12 17:45:40 UTC (rev 4929) @@ -48,8 +48,9 @@ * Update the webpages - at least the file swdb.wml needs an update. * Add a new headline to NEWS. * Bump "my_version" up and set "my_issvn" back to "yes" in configure.ac - * Write an announcement. + * Write an announcement. Update https://savannah.gnu.org/projects/gnupg . + Modified: trunk/keyserver/Makefile.am =================================================================== --- trunk/keyserver/Makefile.am 2009-02-09 11:14:42 UTC (rev 4928) +++ trunk/keyserver/Makefile.am 2009-02-12 17:45:40 UTC (rev 4929) @@ -69,7 +69,7 @@ $(other_libs) else # Note that we need to include all other libs here as well because -# some compilers don't care about inline fucntions and insert +# some compilers don't care about inline functions and insert # references to symbols used in unused inline functions. gpg2keys_curl_CPPFLAGS = $(LIBCURL_CPPFLAGS) $(AM_CPPFLAGS) gpg2keys_curl_LDADD = $(common_libs) $(GPG_ERROR_LIBS) $(NETLIBS) $(DNSLIBS) \ Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2009-02-09 11:14:42 UTC (rev 4928) +++ trunk/scd/command.c 2009-02-12 17:45:40 UTC (rev 4929) @@ -1557,6 +1557,10 @@ reader_list - Return a list of detected card readers. Does currently only work with the internal CCID driver. + + deny_admin - Returns OK if admin commands are not allowed or + GPG_ERR_GENERAL if admin commands are allowed. + */ static int @@ -1622,6 +1626,8 @@ rc = gpg_error (GPG_ERR_NO_DATA); xfree (s); } + else if (!strcmp (line, "deny_admin")) + rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0; else rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); return rc; From cvs at cvs.gnupg.org Fri Feb 13 19:47:56 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 13 Feb 2009 19:47:56 +0100 Subject: [svn] gcry - r1390 - trunk/tests Message-ID: Author: wk Date: 2009-02-13 19:47:56 +0100 (Fri, 13 Feb 2009) New Revision: 1390 Modified: trunk/tests/ChangeLog trunk/tests/rsacvt.c Log: Add OpenPGP opeion and fix non openpgp calculation. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-02-11 11:53:54 UTC (rev 1389) +++ trunk/tests/ChangeLog 2009-02-13 18:47:56 UTC (rev 1390) @@ -1,3 +1,9 @@ +2009-02-13 Werner Koch + + * rsacvt.c (compute_missing): Fix dqm1 computation. Take care of + openpgp flag. + (main): Add option --openpgp. + 2009-02-11 Werner Koch * rsacvt.c: New. Modified: trunk/tests/rsacvt.c =================================================================== --- trunk/tests/rsacvt.c 2009-02-11 11:53:54 UTC (rev 1389) +++ trunk/tests/rsacvt.c 2009-02-13 18:47:56 UTC (rev 1390) @@ -83,7 +83,11 @@ /* Do not suppress leading zeroes. */ static int keep_lz; +/* Create parameters as specified by OpenPGP (rfc4880). That is we + don't store dmp1 and dmp1 but d and make sure that p is less than q. */ +static int openpgp_mode; + /* Print a error message and exit the process with an error code. */ static void die (const char *format, ...) @@ -227,7 +231,7 @@ tmp_g = gcry_mpi_new (0); /* Check that p < q; if not swap p and q. */ - if (gcry_mpi_cmp (rsa_p, rsa_q) > 0) + if (openpgp_mode && gcry_mpi_cmp (rsa_p, rsa_q) > 0) { fprintf (stderr, PGM ": swapping p and q\n"); gcry_mpi_swap (rsa_p, rsa_q); @@ -253,10 +257,14 @@ /* Compute the CRT helpers: d mod (p-1), d mod (q-1) */ gcry_mpi_mod (rsa_pm1, rsa_d, rsa_pm1); - gcry_mpi_mod (rsa_qm1, rsa_d, rsa_pm1); + gcry_mpi_mod (rsa_qm1, rsa_d, rsa_qm1); - /* Compute the CRT value: u = p^{-1} mod q */ - gcry_mpi_invm (rsa_u, rsa_p, rsa_q); + /* Compute the CRT value: OpenPGP: u = p^{-1} mod q + Standard: iqmp = q^{-1} mod p */ + if (openpgp_mode) + gcry_mpi_invm (rsa_u, rsa_p, rsa_q); + else + gcry_mpi_invm (rsa_u, rsa_q, rsa_p); gcry_mpi_release (phi); gcry_mpi_release (tmp_f); @@ -265,12 +273,18 @@ /* Print everything. */ print_mpi_line ("n", rsa_n); print_mpi_line ("e", rsa_e); - print_mpi_line ("d", rsa_d); + if (openpgp_mode) + print_mpi_line ("d", rsa_d); print_mpi_line ("p", rsa_p); print_mpi_line ("q", rsa_q); - print_mpi_line ("dmp1", rsa_pm1); - print_mpi_line ("dmq1", rsa_qm1); - print_mpi_line ("u", rsa_u); + if (openpgp_mode) + print_mpi_line ("u", rsa_u); + else + { + print_mpi_line ("dmp1", rsa_pm1); + print_mpi_line ("dmq1", rsa_qm1); + print_mpi_line ("iqmp", rsa_u); + } gcry_mpi_release (rsa_n); gcry_mpi_release (rsa_d); @@ -294,10 +308,11 @@ ("Usage: " PGM " [OPTIONS] [FILE]\n" "Take RSA parameters p, n, e and compute missing parameters.\n" "OPTIONS:\n" - " --version Print version information\n" - " --verbose Print additional information\n" + " --openpgp Compute as specified by RFC4880\n" " --labels Prefix output with labels\n" " --keep-lz Keep all leading zeroes in the output\n" + " --verbose Print additional information\n" + " --version Print version information\n" " --help Print this text\n" "With no FILE, or if FILE is -, read standard input.\n" "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout); @@ -350,6 +365,11 @@ keep_lz = 1; argc--; argv++; } + else if (!strcmp (*argv, "--openpgp")) + { + openpgp_mode = 1; + argc--; argv++; + } } if (argc > 1) From cvs at cvs.gnupg.org Mon Feb 16 22:05:37 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 16 Feb 2009 22:05:37 +0100 Subject: [svn] gcry - r1391 - in trunk: . cipher mpi src tests Message-ID: Author: wk Date: 2009-02-16 22:05:37 +0100 (Mon, 16 Feb 2009) New Revision: 1391 Modified: trunk/THANKS trunk/cipher/ChangeLog trunk/cipher/crc.c trunk/cipher/md4.c trunk/cipher/md5.c trunk/cipher/rmd160.c trunk/cipher/rsa.c trunk/cipher/sha1.c trunk/cipher/sha256.c trunk/cipher/tiger.c trunk/cipher/whirlpool.c trunk/mpi/ChangeLog trunk/mpi/mpicoder.c trunk/mpi/mpiutil.c trunk/src/ChangeLog trunk/src/ath.h trunk/src/mpi.h trunk/src/sexp.c trunk/tests/ChangeLog trunk/tests/fipsdrv.c Log: Portability fixes. Modified: trunk/cipher/ChangeLog =================================================================== --- trunk/cipher/ChangeLog 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/cipher/ChangeLog 2009-02-16 21:05:37 UTC (rev 1391) @@ -1,3 +1,11 @@ +2009-02-16 Werner Koch + + * rsa.c (generate_x931): Do not initialize TBL with automatic + variables. + * whirlpool.c, tiger.c, sha256.c, sha1.c, rmd160.c, md5.c + * md4.c, crc.c: Remove memory.h. This is garbage from gnupg. + Reported by Dan Fandrich. + 2009-01-22 Werner Koch * ecc.c (compute_keygrip): Remove superfluous const. Modified: trunk/mpi/ChangeLog =================================================================== --- trunk/mpi/ChangeLog 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/mpi/ChangeLog 2009-02-16 21:05:37 UTC (rev 1391) @@ -1,3 +1,7 @@ +2009-02-16 Werner Koch + + * mpiutil.c: Remove memory.h. + 2008-12-05 Werner Koch * mpicoder.c (mpi_read_from_buffer): Do not bail out if the mpi is Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/src/ChangeLog 2009-02-16 21:05:37 UTC (rev 1391) @@ -1,3 +1,13 @@ +2009-02-16 Werner Koch + + * ath.h [HAVE_SYS_SELECT_H]: Include for fd_set. + [!HAVE_SYS_SELECT_H]: Include . Move inclusion of + config.h to the top. The actual configure check was already + there. + + * sexp.c: Remove memory.h. + * mpi.h: Remove memory.h. Add string.h. + 2009-02-02 Werner Koch * ath.h: Include sys/time.h. Fixes bug#993. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/tests/ChangeLog 2009-02-16 21:05:37 UTC (rev 1391) @@ -1,3 +1,8 @@ +2009-02-16 Werner Koch + + * fipsdrv.c (print_buffer): Remove parens from initializer for + better portability. Reported by Dan Fandrich. + 2009-02-13 Werner Koch * rsacvt.c (compute_missing): Fix dqm1 computation. Take care of Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/THANKS 2009-02-16 21:05:37 UTC (rev 1391) @@ -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 +Dan Fandrich dan at coneharvesters com Daniel Eisenbud eisenbud at cs.swarthmore.edu Daniel Koening dan at mail.isis.de David Ellement ellement at sdd.hp.com @@ -148,7 +149,8 @@ nbecker at hns.com - Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2002, 2003, + 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/cipher/crc.c =================================================================== --- trunk/cipher/crc.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/cipher/crc.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -25,7 +25,6 @@ #include #include "g10lib.h" -#include "memory.h" #include "cipher.h" #include "bithelp.h" Modified: trunk/cipher/md4.c =================================================================== --- trunk/cipher/md4.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/cipher/md4.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -53,7 +53,6 @@ #include #include "g10lib.h" -#include "memory.h" #include "cipher.h" #include "bithelp.h" Modified: trunk/cipher/md5.c =================================================================== --- trunk/cipher/md5.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/cipher/md5.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -37,7 +37,6 @@ #include #include "g10lib.h" -#include "memory.h" #include "cipher.h" #include "bithelp.h" Modified: trunk/cipher/rmd160.c =================================================================== --- trunk/cipher/rmd160.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/cipher/rmd160.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -24,7 +24,6 @@ #include #include "g10lib.h" -#include "memory.h" #include "rmd.h" #include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */ Modified: trunk/cipher/rsa.c =================================================================== --- trunk/cipher/rsa.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/cipher/rsa.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -444,18 +444,28 @@ else { /* Parameters to derive the key are given. */ + /* Note that we explicitly need to setup the values of tbl + because some compilers (e.g. OpenWatcom, IRIX) don't allow + to initialize a structure with automatic variables. */ struct { const char *name; gcry_mpi_t *value; } tbl[] = { - { "Xp1", &xp1 }, - { "Xp2", &xp2 }, - { "Xp", &xp }, - { "Xq1", &xq1 }, - { "Xq2", &xq2 }, - { "Xq", &xq }, - { NULL, NULL } + { "Xp1" }, + { "Xp2" }, + { "Xp" }, + { "Xq1" }, + { "Xq2" }, + { "Xq" }, + { NULL } }; int idx; gcry_sexp_t oneparm; + tbl[0].value = &xp1; + tbl[1].value = &xp2; + tbl[2].value = &xp; + tbl[3].value = &xq1; + tbl[4].value = &xq2; + tbl[5].value = &xq; + for (idx=0; tbl[idx].name; idx++) { oneparm = gcry_sexp_find_token (deriveparms, tbl[idx].name, 0); Modified: trunk/cipher/sha1.c =================================================================== --- trunk/cipher/sha1.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/cipher/sha1.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -37,7 +37,6 @@ #endif #include "g10lib.h" -#include "memory.h" #include "bithelp.h" #include "cipher.h" #include "hash-common.h" Modified: trunk/cipher/sha256.c =================================================================== --- trunk/cipher/sha256.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/cipher/sha256.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -41,7 +41,6 @@ #include #include "g10lib.h" -#include "memory.h" #include "bithelp.h" #include "cipher.h" #include "hash-common.h" Modified: trunk/cipher/tiger.c =================================================================== --- trunk/cipher/tiger.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/cipher/tiger.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -24,7 +24,6 @@ #include #include "g10lib.h" -#include "memory.h" #include "cipher.h" #ifdef HAVE_U64_TYPEDEF Modified: trunk/cipher/whirlpool.c =================================================================== --- trunk/cipher/whirlpool.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/cipher/whirlpool.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -36,7 +36,6 @@ #include "types.h" #include "g10lib.h" -#include "memory.h" #include "cipher.h" #include "bithelp.h" Modified: trunk/mpi/mpicoder.c =================================================================== --- trunk/mpi/mpicoder.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/mpi/mpicoder.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -456,6 +456,10 @@ const unsigned char *s = buffer; size_t n; + /* This test is not strictly necessary and an assert (!len) + would be sufficient. We keep this test in case we later + allow the BUFLEN argument to act as a sanitiy check. Same + below. */ if (len && len < 4) return gcry_error (GPG_ERR_TOO_SHORT); Modified: trunk/mpi/mpiutil.c =================================================================== --- trunk/mpi/mpiutil.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/mpi/mpiutil.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -25,7 +25,6 @@ #include "g10lib.h" #include "mpi-internal.h" -#include "memory.h" #include "mod-source-info.h" Modified: trunk/src/ath.h =================================================================== --- trunk/src/ath.h 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/src/ath.h 2009-02-16 21:05:37 UTC (rev 1391) @@ -21,18 +21,22 @@ #ifndef ATH_H #define ATH_H +#include + #ifdef _WIN32 -#include -#else -#include -#include -#endif +# include +#else /* !_WIN32 */ +# ifdef HAVE_SYS_SELECT_H +# include +# else +# include +# endif +# include +# include +#endif /* !_WIN32 */ #include -#include /* Required by Interix. */ -#include - /* Define _ATH_EXT_SYM_PREFIX if you want to give all external symbols a prefix. */ Modified: trunk/src/mpi.h =================================================================== --- trunk/src/mpi.h 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/src/mpi.h 2009-02-16 21:05:37 UTC (rev 1391) @@ -30,8 +30,9 @@ #include #include +#include + #include "types.h" -#include "memory.h" #include "../mpi/mpi-asm-defs.h" #include "g10lib.h" Modified: trunk/src/sexp.c =================================================================== --- trunk/src/sexp.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/src/sexp.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -30,7 +30,6 @@ #define GCRYPT_NO_MPI_MACROS 1 #include "g10lib.h" -#include "memory.h" typedef struct gcry_sexp *NODE; typedef unsigned short DATALEN; Modified: trunk/tests/fipsdrv.c =================================================================== --- trunk/tests/fipsdrv.c 2009-02-13 18:47:56 UTC (rev 1390) +++ trunk/tests/fipsdrv.c 2009-02-16 21:05:37 UTC (rev 1391) @@ -797,9 +797,9 @@ if (base64_output) { static const unsigned char bintoasc[64+1] = - ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"); + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"; const unsigned char *p; unsigned char inbuf[4]; char outbuf[4]; From cvs at cvs.gnupg.org Thu Feb 19 17:18:41 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Thu, 19 Feb 2009 17:18:41 +0100 Subject: [svn] pinentry - r191 - trunk/qt4 Message-ID: Author: marcus Date: 2009-02-19 17:18:41 +0100 (Thu, 19 Feb 2009) New Revision: 191 Added: trunk/qt4/pinentrydialog.moc trunk/qt4/qsecurelineedit.cpp trunk/qt4/qsecurelineedit.h trunk/qt4/qsecurelineedit.moc trunk/qt4/qsecurelineedit_p.h trunk/qt4/secstring.cpp trunk/qt4/secstring.h Modified: trunk/qt4/Makefile.am trunk/qt4/main.cpp trunk/qt4/pinentrydialog.cpp trunk/qt4/pinentrydialog.h Log: 2009-02-19 Marcus Brinkmann * qt4/Makefile.am, qt4/main.cpp, qt4/pinentrydialog.cpp, qt4/pinentrydialog.h: Changes to use secure memory. * qt4/pinentrydialog.moc, qt4/qsecurelineedit.moc: New files. * qt4/qsecurelineedit.cpp, qt4/qsecurelineedit.h, qt4/qsecurelineedit_p.h, qt4/secstring.h, qt4/secstring.cpp: New files. Submitted by Marc Mutz . [The diff below has been truncated] Modified: trunk/qt4/Makefile.am =================================================================== --- trunk/qt4/Makefile.am 2008-12-08 16:45:52 UTC (rev 190) +++ trunk/qt4/Makefile.am 2009-02-19 16:18:41 UTC (rev 191) @@ -31,7 +31,7 @@ endif -AM_CPPFLAGS = -I$(top_srcdir)/assuan -I$(top_srcdir)/secmem \ +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/assuan -I$(top_srcdir)/secmem \ $(ncurses_include) -I$(top_srcdir)/pinentry AM_CXXFLAGS = $(QT4_CORE_CFLAGS) $(QT4_GUI_CFLAGS) pinentry_qt4_LDADD = $(QT4_CORE_LIBS) $(QT4_GUI_LIBS) $(libcurses) \ @@ -39,11 +39,4 @@ $(top_builddir)/secmem/libsecmem.a $(LIBCAP) pinentry_qt4_SOURCES = pinentrydialog.h pinentrydialog.cpp \ - main.cpp -nodist_pinentry_qt4_SOURCES = pinentrydialog.moc -BUILT_SOURCES = pinentrydialog.moc - -CLEANFILES = $(nodist_pinentry_qt4_SOURCES) - -%.moc: $(srcdir)/%.h - $(MOC) $< -o $@ + main.cpp secstring.h secstring.cpp qsecurelineedit.h qsecurelineedit.cpp Modified: trunk/qt4/main.cpp =================================================================== --- trunk/qt4/main.cpp 2008-12-08 16:45:52 UTC (rev 190) +++ trunk/qt4/main.cpp 2009-02-19 16:18:41 UTC (rev 191) @@ -1,12 +1,13 @@ /* main.cpp - A (not yet) secure Qt 4 dialog for PIN entry. - Copyright (C) 2002 Klar??lvdalens Datakonsult AB + Copyright (C) 2002, 2008 Klar?lvdalens Datakonsult AB (KDAB) Copyright (C) 2003 g10 Code GmbH Copyright 2007 Ingo Kl??cker Written by Steffen Hansen . Modified by Marcus Brinkmann . + Modified by Marc Mutz This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -24,25 +25,17 @@ */ -#include -#include +#include "pinentrydialog.h" +#include "pinentry.h" #include #include #include #include -// #include "secqstring.h" -#include "pinentrydialog.h" - -#include "pinentry.h" - -extern "C" -{ -#include "memory.h" -} - #include +#include +#include #ifdef FALLBACK_CURSES #include @@ -52,7 +45,7 @@ class ForeignWidget : public QWidget { public: - ForeignWidget( WId wid ) : QWidget( 0 ) + explicit ForeignWidget( WId wid ) : QWidget( 0 ) { QWidget::destroy(); create( wid, false, false ); @@ -82,9 +75,7 @@ pinentry.setPrompt (QString::fromUtf8 (pe->prompt)); pinentry.setDescription (QString::fromUtf8 (pe->description)); /* If we reuse the same dialog window. */ -#if 0 - pinentry.setText (SecQString::null); -#endif + pinentry.setPin (secqstring()); if (pe->ok) pinentry.setOkText (QString::fromUtf8 (pe->ok)); @@ -97,8 +88,8 @@ if (!ret) return -1; - QByteArray pinUtf8 = pinentry.text().toUtf8(); - char *pin = pinUtf8.data(); + const secstring pinUtf8 = toUtf8( pinentry.pin() ); + const char *pin = pinUtf8.data(); if (!pin) return -1; @@ -109,11 +100,9 @@ if (pe->pin) { strcpy (pe->pin, pin); - // ::secmem_free (pin); return len; } } - // ::secmem_free (pin); return -1; } else Modified: trunk/qt4/pinentrydialog.cpp =================================================================== --- trunk/qt4/pinentrydialog.cpp 2008-12-08 16:45:52 UTC (rev 190) +++ trunk/qt4/pinentrydialog.cpp 2009-02-19 16:18:41 UTC (rev 191) @@ -1,7 +1,7 @@ /* pinentrydialog.cpp - A (not yet) secure Qt 4 dialog for PIN entry. - Copyright (C) 2002 Klar??lvdalens Datakonsult AB + Copyright (C) 2002, 2008 Klar?lvdalens Datakonsult AB (KDAB) Copyright 2007 Ingo Kl??cker Written by Steffen Hansen . @@ -21,6 +21,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "pinentrydialog.h" + +#include "qsecurelineedit.h" + #include #include #include @@ -28,14 +32,6 @@ #include #include -#ifdef WITH_SECURE_QSTRING -#include "secqlineedit.h" -#else -#include -#endif - -#include "pinentrydialog.h" - PinEntryDialog::PinEntryDialog( QWidget* parent, const char* name, bool modal ) : QDialog( parent ), _grabbed( false ) { @@ -65,9 +61,8 @@ top->addLayout( l ); _prompt = new QLabel( this ); l->addWidget( _prompt ); - _edit = new SecQLineEdit( this ); + _edit = new QSecureLineEdit( this ); _edit->setMaxLength( 256 ); - _edit->setEchoMode( SecQLineEdit::Password ); l->addWidget( _edit ); l = new QHBoxLayout(); @@ -95,15 +90,15 @@ _edit->setFocus(); } -void PinEntryDialog::paintEvent( QPaintEvent* ev ) +void PinEntryDialog::showEvent( QShowEvent* ev ) { // Grab keyboard when widget is mapped to screen // It might be a little weird to do it here, but it works! + QDialog::showEvent( ev ); if( !_grabbed ) { _edit->grabKeyboard(); _grabbed = true; } - QDialog::paintEvent( ev ); } void PinEntryDialog::hideEvent( QHideEvent* ev ) @@ -145,14 +140,14 @@ return _error->text(); } -void PinEntryDialog::setText( const SecQString& txt ) +void PinEntryDialog::setPin( const secqstring & txt ) { - _edit->setText( txt ); + _edit->setText( txt ); } -SecQString PinEntryDialog::text() const +secqstring PinEntryDialog::pin() const { - return _edit->text(); + return _edit->text(); } void PinEntryDialog::setPrompt( const QString& txt ) Modified: trunk/qt4/pinentrydialog.h =================================================================== --- trunk/qt4/pinentrydialog.h 2008-12-08 16:45:52 UTC (rev 190) +++ trunk/qt4/pinentrydialog.h 2009-02-19 16:18:41 UTC (rev 191) @@ -1,7 +1,7 @@ /* pinentrydialog.h - A (not yet) secure Qt 4 dialog for PIN entry. - Copyright (C) 2002 Klar??lvdalens Datakonsult AB + Copyright (C) 2002, 2008 Klar?lvdalens Datakonsult AB (KDAB) Copyright 2007 Ingo Kl??cker Written by Steffen Hansen . @@ -26,28 +26,25 @@ #include +#include "secstring.h" + class QLabel; class QPushButton; -#ifdef WITH_SECURE_QSTRING -class SecQLineEdit; -class SecQString; -#else -class QLineEdit; +class QSecureLineEdit; class QString; -#define SecQLineEdit QLineEdit -#define SecQString QString -#endif + + class PinEntryDialog : public QDialog { Q_OBJECT Q_PROPERTY( QString description READ description WRITE setDescription ) Q_PROPERTY( QString error READ error WRITE setError ) - // Q_PROPERTY( SecQString text READ text WRITE setText ) + Q_PROPERTY( secqstring pin READ pin WRITE setPin ) Q_PROPERTY( QString prompt READ prompt WRITE setPrompt ) public: friend class PinEntryController; // TODO: remove when assuan lets me use Qt eventloop. - PinEntryDialog( QWidget* parent = 0, const char* name = 0, bool modal = false ); + explicit PinEntryDialog( QWidget* parent = 0, const char* name = 0, bool modal = false ); void setDescription( const QString& ); QString description() const; @@ -55,8 +52,8 @@ void setError( const QString& ); QString error() const; - void setText( const SecQString& ); - SecQString text() const; + void setPin( const secqstring & ); + secqstring pin() const; void setPrompt( const QString& ); QString prompt() const; @@ -69,16 +66,16 @@ void rejected(); protected: - virtual void keyPressEvent( QKeyEvent *e ); - virtual void hideEvent( QHideEvent* ); - virtual void paintEvent( QPaintEvent* ); + /* reimp */ void keyPressEvent( QKeyEvent *e ); + /* reimp */ void hideEvent( QHideEvent* ); + /* reimp */ void showEvent( QShowEvent* ); private: QLabel* _icon; QLabel* _desc; QLabel* _error; QLabel* _prompt; - SecQLineEdit* _edit; + QSecureLineEdit* _edit; QPushButton* _ok; QPushButton* _cancel; bool _grabbed; Added: trunk/qt4/pinentrydialog.moc =================================================================== --- trunk/qt4/pinentrydialog.moc (rev 0) +++ trunk/qt4/pinentrydialog.moc 2009-02-19 16:18:41 UTC (rev 191) @@ -0,0 +1,126 @@ +/**************************************************************************** +** Meta object code from reading C++ file 'pinentrydialog.h' +** +** Created: Mon Oct 20 09:30:12 2008 +** by: The Qt Meta Object Compiler version 59 (Qt 4.4.1) +** +** WARNING! All changes made in this file will be lost! +*****************************************************************************/ + +#include "pinentrydialog.h" +#if !defined(Q_MOC_OUTPUT_REVISION) +#error "The header file 'pinentrydialog.h' doesn't include ." +#elif Q_MOC_OUTPUT_REVISION != 59 +#error "This file was generated using the moc from 4.4.1. It" +#error "cannot be used with the include files from this version of Qt." +#error "(The moc has changed too much.)" +#endif + +QT_BEGIN_MOC_NAMESPACE +static const uint qt_meta_data_PinEntryDialog[] = { + + // content: + 1, // revision + 0, // classname + 0, 0, // classinfo + 2, 10, // methods + 4, 20, // properties + 0, 0, // enums/sets + + // signals: signature, parameters, type, tag, flags + 16, 15, 15, 15, 0x05, + 27, 15, 15, 15, 0x05, + + // properties: name, type, flags + 46, 38, 0x0a095103, + 58, 38, 0x0a095103, + 75, 64, 0x0009510b, + 79, 38, 0x0a095103, + + 0 // eod +}; + +static const char qt_meta_stringdata_PinEntryDialog[] = { + "PinEntryDialog\0\0accepted()\0rejected()\0" + "QString\0description\0error\0secqstring\0" + "pin\0prompt\0" +}; + +const QMetaObject PinEntryDialog::staticMetaObject = { + { &QDialog::staticMetaObject, qt_meta_stringdata_PinEntryDialog, + qt_meta_data_PinEntryDialog, 0 } +}; + +const QMetaObject *PinEntryDialog::metaObject() const +{ + return &staticMetaObject; +} + +void *PinEntryDialog::qt_metacast(const char *_clname) +{ + if (!_clname) return 0; + if (!strcmp(_clname, qt_meta_stringdata_PinEntryDialog)) + return static_cast(const_cast< PinEntryDialog*>(this)); + return QDialog::qt_metacast(_clname); +} + +int PinEntryDialog::qt_metacall(QMetaObject::Call _c, int _id, void **_a) +{ + _id = QDialog::qt_metacall(_c, _id, _a); + if (_id < 0) + return _id; + if (_c == QMetaObject::InvokeMetaMethod) { + switch (_id) { + case 0: accepted(); break; + case 1: rejected(); break; + } + _id -= 2; + } +#ifndef QT_NO_PROPERTIES + else if (_c == QMetaObject::ReadProperty) { + void *_v = _a[0]; + switch (_id) { + case 0: *reinterpret_cast< QString*>(_v) = description(); break; + case 1: *reinterpret_cast< QString*>(_v) = error(); break; + case 2: *reinterpret_cast< secqstring*>(_v) = pin(); break; + case 3: *reinterpret_cast< QString*>(_v) = prompt(); break; + } + _id -= 4; + } else if (_c == QMetaObject::WriteProperty) { + void *_v = _a[0]; + switch (_id) { + case 0: setDescription(*reinterpret_cast< QString*>(_v)); break; + case 1: setError(*reinterpret_cast< QString*>(_v)); break; + case 2: setPin(*reinterpret_cast< secqstring*>(_v)); break; + case 3: setPrompt(*reinterpret_cast< QString*>(_v)); break; + } + _id -= 4; + } else if (_c == QMetaObject::ResetProperty) { + _id -= 4; + } else if (_c == QMetaObject::QueryPropertyDesignable) { + _id -= 4; + } else if (_c == QMetaObject::QueryPropertyScriptable) { + _id -= 4; + } else if (_c == QMetaObject::QueryPropertyStored) { + _id -= 4; + } else if (_c == QMetaObject::QueryPropertyEditable) { + _id -= 4; + } else if (_c == QMetaObject::QueryPropertyUser) { + _id -= 4; + } +#endif // QT_NO_PROPERTIES + return _id; +} + +// SIGNAL 0 +void PinEntryDialog::accepted() +{ + QMetaObject::activate(this, &staticMetaObject, 0, 0); +} + +// SIGNAL 1 +void PinEntryDialog::rejected() +{ + QMetaObject::activate(this, &staticMetaObject, 1, 0); +} +QT_END_MOC_NAMESPACE Added: trunk/qt4/qsecurelineedit.cpp =================================================================== --- trunk/qt4/qsecurelineedit.cpp (rev 0) +++ trunk/qt4/qsecurelineedit.cpp 2009-02-19 16:18:41 UTC (rev 191) @@ -0,0 +1,3591 @@ +/* + qsecurelineedit.cpp - QLineEdit that uses secmem + + Copyright (C) 2008 Klar?lvdalens Datakonsult AB (KDAB) + + Written by Marc Mutz . + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +// the following code has been ported from QString to secqstring. +// The licence of the original code: + +/**************************************************************************** +** +** Copyright (C) 1992-2008 Trolltech ASA. All rights reserved. +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** Licensees holding a valid Qt License Agreement may use this file in +** accordance with the rights, responsibilities and obligations +** contained therein. Please consult your licensing agreement or +** contact sales at trolltech.com if any conditions of this licensing +** agreement are not clear to you. +** +** Further information about Qt licensing is available at: +** http://www.trolltech.com/products/qt/licensing.html or by +** contacting info at trolltech.com. +** +** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** +****************************************************************************/ + +#include "qlineedit.h" // added to pick up qt defines + +#ifndef QT_NO_LINEEDIT +#include "qaction.h" +#include "qapplication.h" +#include "qclipboard.h" +#include "qdrag.h" +#include "qdrawutil.h" +#include "qevent.h" +#include "qfontmetrics.h" +#include "qmenu.h" +#include "qpainter.h" +#include "qpixmap.h" +#include "qpointer.h" +#include "qstringlist.h" +#include "qstyle.h" +#include "qstyleoption.h" +#include "qtimer.h" +#include "qvalidator.h" +#include "qvariant.h" +#include "qvector.h" +#include "qwhatsthis.h" +#include "qdebug.h" +#include "qtextedit.h" +//#include +#ifndef QT_NO_ACCESSIBILITY +#include "qaccessible.h" +#endif +#ifndef QT_NO_IM +#include "qinputcontext.h" +#include "qlist.h" +#endif +#include "qabstractitemview.h" +#ifdef QT_NO_STYLE_STYLESHEET +#include "private/qstylesheetstyle_p.h" +#endif + +#ifndef QT_NO_SHORTCUT +#include "qkeysequence.h" +#define ACCEL_KEY(k) QLatin1String("\t") + QString(QKeySequence(k)) +#else +#define ACCEL_KEY(k) QString() +#endif + +#include + +// these go last so they don't contaminate other Qt headers +#include "qsecurelineedit_p.h" +#include "qsecurelineedit.h" + +#define verticalMargin 1 +#define horizontalMargin 2 + +QT_BEGIN_NAMESPACE + +#ifdef Q_WS_MAC +extern void qt_mac_secure_keyboard(bool); //qapplication_mac.cpp +#endif + +/*! + Initialize \a option with the values from this QSecureLineEdit. This method + is useful for subclasses when they need a QStyleOptionFrame or QStyleOptionFrameV2, but don't want + to fill in all the information themselves. This function will check the version + of the QStyleOptionFrame and fill in the additional values for a + QStyleOptionFrameV2. + + \sa QStyleOption::initFrom() +*/ +void QSecureLineEdit::initStyleOption(QStyleOptionFrame *option) const +{ + if (!option) + return; + + Q_D(const QSecureLineEdit); + option->initFrom(this); + option->rect = contentsRect(); + option->lineWidth = d->frame ? style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this) + : 0; + option->midLineWidth = 0; + option->state |= QStyle::State_Sunken; + if (d->readOnly) + option->state |= QStyle::State_ReadOnly; +#ifdef QT_KEYPAD_NAVIGATION + if (hasEditFocus()) + option->state |= QStyle::State_HasEditFocus; +#endif + if (QStyleOptionFrameV2 *optionV2 = qstyleoption_cast(option)) + optionV2->features = QStyleOptionFrameV2::None; +} + +/*! + \class QSecureLineEdit + \brief The QSecureLineEdit widget is a one-line text editor. + + \ingroup basicwidgets + \mainclass + + A line edit allows the user to enter and edit a single line of + plain text with a useful collection of editing functions, + including undo and redo, cut and paste, and drag and drop. + + By changing the echoMode() of a line edit, it can also be used as + a "write-only" field, for inputs such as passwords. + + The length of the text can be constrained to maxLength(). The text + can be arbitrarily constrained using a validator() or an + inputMask(), or both. + + A related class is QTextEdit which allows multi-line, rich text + editing. + + You can change the text with setText() or insert(). The text is + retrieved with text(); the displayed text (which may be different, + see \l{EchoMode}) is retrieved with displayText(). Text can be + selected with setSelection() or selectAll(), and the selection can + be cut(), copy()ied and paste()d. The text can be aligned with + setAlignment(). + + When the text changes the textChanged() signal is emitted; when + the text changes other than by calling setText() the textEdited() + signal is emitted; when the cursor is moved the + cursorPositionChanged() signal is emitted; and when the Return or + Enter key is pressed the returnPressed() signal is emitted. + + When editing is finished, either because the line edit lost focus + or Return/Enter is pressed the editingFinished() signal is + emitted. + + Note that if there is a validator set on the line edit, the + returnPressed()/editingFinished() signals will only be emitted if + the validator returns QValidator::Acceptable. + + By default, QSecureLineEdits have a frame as specified by the Windows + and Motif style guides; you can turn it off by calling + setFrame(false). + + The default key bindings are described below. The line edit also + provides a context menu (usually invoked by a right mouse click) + that presents some of these editing options. + \target desc + \table + \header \i Keypress \i Action + \row \i Left Arrow \i Moves the cursor one character to the left. + \row \i Shift+Left Arrow \i Moves and selects text one character to the left. + \row \i Right Arrow \i Moves the cursor one character to the right. + \row \i Shift+Right Arrow \i Moves and selects text one character to the right. + \row \i Home \i Moves the cursor to the beginning of the line. + \row \i End \i Moves the cursor to the end of the line. + \row \i Backspace \i Deletes the character to the left of the cursor. + \row \i Ctrl+Backspace \i Deletes the word to the left of the cursor. + \row \i Delete \i Deletes the character to the right of the cursor. + \row \i Ctrl+Delete \i Deletes the word to the right of the cursor. + \row \i Ctrl+A \i Select all. + \row \i Ctrl+C \i Copies the selected text to the clipboard. + \row \i Ctrl+Insert \i Copies the selected text to the clipboard. + \row \i Ctrl+K \i Deletes to the end of the line. + \row \i Ctrl+V \i Pastes the clipboard text into line edit. + \row \i Shift+Insert \i Pastes the clipboard text into line edit. + \row \i Ctrl+X \i Deletes the selected text and copies it to the clipboard. + \row \i Shift+Delete \i Deletes the selected text and copies it to the clipboard. + \row \i Ctrl+Z \i Undoes the last operation. + \row \i Ctrl+Y \i Redoes the last undone operation. + \endtable + + Any other key sequence that represents a valid character, will + cause the character to be inserted into the line edit. + + \table 100% + \row \o \inlineimage macintosh-lineedit.png Screenshot of a Macintosh style line edit + \o A line edit shown in the \l{Macintosh Style Widget Gallery}{Macintosh widget style}. + \row \o \inlineimage windows-lineedit.png Screenshot of a Windows XP style line edit + \o A line edit shown in the \l{Windows XP Style Widget Gallery}{Windows XP widget style}. + \row \o \inlineimage plastique-lineedit.png Screenshot of a Plastique style line edit + \o A line edit shown in the \l{Plastique Style Widget Gallery}{Plastique widget style}. + \endtable + + \sa QTextEdit, QLabel, QComboBox, {fowler}{GUI Design Handbook: Field, Entry}, {Line Edits Example} +*/ + + +/*! + \fn void QSecureLineEdit::textChanged(const QString &text) + + This signal is emitted whenever the text changes. The \a text + argument is the new text. + + Unlike textEdited(), this signal is also emitted when the text is + changed programmatically, for example, by calling setText(). +*/ + +/*! + \fn void QSecureLineEdit::textEdited(const QString &text) + + This signal is emitted whenever the text is edited. The \a text + argument is the next text. + + Unlike textChanged(), this signal is not emitted when the text is + changed programmatically, for example, by calling setText(). +*/ + +/*! + \fn void QSecureLineEdit::cursorPositionChanged(int old, int new) + + This signal is emitted whenever the cursor moves. The previous + position is given by \a old, and the new position by \a new. + + \sa setCursorPosition(), cursorPosition() +*/ + +/*! + \fn void QSecureLineEdit::selectionChanged() + + This signal is emitted whenever the selection changes. + + \sa hasSelectedText(), selectedText() +*/ + +/*! + Constructs a line edit with no text. + + The maximum text length is set to 32767 characters. + + The \a parent argument is sent to the QWidget constructor. + + \sa setText(), setMaxLength() +*/ +QSecureLineEdit::QSecureLineEdit(QWidget* parent) + : QWidget(parent,0), m_d(new QSecureLineEditPrivate(this)) +{ + Q_D(QSecureLineEdit); + d->init(secqstring()); +} + +/*! + Constructs a line edit containing the text \a contents. + + The cursor position is set to the end of the line and the maximum + text length to 32767 characters. + + The \a parent and argument is sent to the QWidget + constructor. + + \sa text(), setMaxLength() +*/ +QSecureLineEdit::QSecureLineEdit(const secqstring& contents, QWidget* parent) + : QWidget(parent, 0), m_d(new QSecureLineEditPrivate(this)) +{ + Q_D(QSecureLineEdit); + d->init(contents); +} + + +#ifdef QT3_SUPPORT +/*! + Constructs a line edit with no text. + + The maximum text length is set to 32767 characters. + + The \a parent and \a name arguments are sent to the QWidget constructor. + + \sa setText(), setMaxLength() +*/ +QSecureLineEdit::QSecureLineEdit(QWidget* parent, const char* name) + : QWidget(parent,0), m_d(new QSecureLineEditPrivate(this)) +{ + Q_D(QSecureLineEdit); + setObjectName(QString::fromAscii(name)); + d->init(secqstring()); +} + +/*! + Constructs a line edit containing the text \a contents. + + The cursor position is set to the end of the line and the maximum + text length to 32767 characters. + + The \a parent and \a name arguments are sent to the QWidget + constructor. + + \sa text(), setMaxLength() +*/ + +QSecureLineEdit::QSecureLineEdit(const secqstring& contents, QWidget* parent, const char* name) + : QWidget(parent, 0), m_d(new QSecureLineEditPrivate(this)) +{ + Q_D(QSecureLineEdit); + setObjectName(QString::fromAscii(name)); + d->init(contents); +} + +/*! + Constructs a line edit with an input \a inputMask and the text \a + contents. + + The cursor position is set to the end of the line and the maximum + text length is set to the length of the mask (the number of mask + characters and separators). + + The \a parent and \a name arguments are sent to the QWidget + constructor. + + \sa setMask() text() +*/ +QSecureLineEdit::QSecureLineEdit(const QString& contents, const QString &inputMask, QWidget* parent, const char* name) + : QWidget(parent, 0), m_d(new QSecureLineEditPrivate(this)) +{ + Q_D(QSecureLineEdit); + setObjectName(QString::fromAscii(name)); + d->parseInputMask(inputMask); + if (d->maskData) { + QString ms = d->maskString(0, contents); + d->init(ms + d->clearString(ms.length(), d->maxLength - ms.length())); + d->cursor = d->nextMaskBlank(ms.length()); + } else { + d->init(contents); + } +} +#endif + +/*! + Destroys the line edit. +*/ + +QSecureLineEdit::~QSecureLineEdit() +{ + delete m_d; +} + + +/*! + \property QSecureLineEdit::text + \brief the line edit's text + + Setting this property clears the selection, clears the undo/redo + history, moves the cursor to the end of the line and resets the + \l modified property to false. The text is not validated when + inserted with setText(). + + The text is truncated to maxLength() length. + + \sa insert(), clear() +*/ +secqstring QSecureLineEdit::text() const +{ + Q_D(const QSecureLineEdit); + secqstring res = d->text; + if (d->maskData) + res = d->stripString(d->text); + return res;//(res.isNull() ? QString::fromLatin1("") : res); +} + +void QSecureLineEdit::setText(const secqstring& text) +{ + Q_D(QSecureLineEdit); + d->setText(text, -1, false); +#ifdef QT_KEYPAD_NAVIGATION + d->origText = d->text; +#endif +} + + +/*! + \property QSecureLineEdit::displayText + \brief the displayed text + + If \l echoMode is \l Normal this returns the same as text(); if + \l EchoMode is \l Password or \l PasswordEchoOnEdit it returns a string of asterisks + text().length() characters long, e.g. "******"; if \l EchoMode is + \l NoEcho returns an empty string, "". + + \sa setEchoMode() text() EchoMode +*/ + +secqstring QSecureLineEdit::displayText() const +{ + Q_D(const QSecureLineEdit); + if (d->echoMode == NoEcho) + return secqstring(); + secqstring res = d->text; + + if (d->echoMode == Password || d->echoMode == PasswordEchoOnEdit) { + QStyleOptionFrameV2 opt; + initStyleOption(&opt); + return secqstring( res.size(), style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this) ); + //res.fill(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this)); + } + return res;//(res.isNull() ? QString::fromLatin1("") : res); +} + + +/*! + \property QSecureLineEdit::maxLength + \brief the maximum permitted length of the text + + If the text is too long, it is truncated at the limit. + + If truncation occurs any selected text will be unselected, the + cursor position is set to 0 and the first part of the string is + shown. + + If the line edit has an input mask, the mask defines the maximum + string length. + + \sa inputMask +*/ + +int QSecureLineEdit::maxLength() const +{ + Q_D(const QSecureLineEdit); + return d->maxLength; +} + +void QSecureLineEdit::setMaxLength(int maxLength) +{ + Q_D(QSecureLineEdit); + if (d->maskData) + return; + d->maxLength = maxLength; + setText(d->text); +} + + + +/*! + \property QSecureLineEdit::frame + \brief whether the line edit draws itself with a frame + + If enabled (the default) the line edit draws itself inside a + frame, otherwise the line edit draws itself without any frame. +*/ +bool QSecureLineEdit::hasFrame() const +{ + Q_D(const QSecureLineEdit); + return d->frame; +} + + +void QSecureLineEdit::setFrame(bool enable) +{ + Q_D(QSecureLineEdit); + d->frame = enable; + update(); + updateGeometry(); +} + + +/*! + \enum QSecureLineEdit::EchoMode + + This enum type describes how a line edit should display its + contents. + + \value Normal Display characters as they are entered. This is the + default. + \value NoEcho Do not display anything. This may be appropriate + for passwords where even the length of the + password should be kept secret. + \value Password Display asterisks instead of the characters + actually entered. + \value PasswordEchoOnEdit Display characters as they are entered + while editing otherwise display asterisks. + + \sa setEchoMode() echoMode() +*/ + + +/*! + \property QSecureLineEdit::echoMode + \brief the line edit's echo mode + + The initial setting is \l Normal, but QSecureLineEdit also supports \l + NoEcho, \l Password and \l PasswordEchoOnEdit modes. + + The widget's display and the ability to copy or drag the text is + affected by this setting. + + \sa EchoMode displayText() +*/ + +QSecureLineEdit::EchoMode QSecureLineEdit::echoMode() const +{ + Q_D(const QSecureLineEdit); + return (EchoMode) d->echoMode; +} + +void QSecureLineEdit::setEchoMode(EchoMode mode) +{ + Q_D(QSecureLineEdit); + if(mode == (EchoMode)d->echoMode) + return; + setAttribute(Qt::WA_InputMethodEnabled, mode == Normal || mode == PasswordEchoOnEdit); + d->echoMode = mode; + d->updateTextLayout(); + update(); +#ifdef Q_WS_MAC + if (hasFocus()) + qt_mac_secure_keyboard(d->echoMode == Password || d->echoMode == NoEcho); +#endif +} + + +#ifndef QT_NO_VALIDATOR +/*! + Returns a pointer to the current input validator, or 0 if no + validator has been set. + + \sa setValidator() +*/ + +const QValidator * QSecureLineEdit::validator() const +{ + Q_D(const QSecureLineEdit); + return d->validator; +} + +/*! + Sets this line edit to only accept input that the validator, \a v, + will accept. This allows you to place any arbitrary constraints on + the text which may be entered. + + If \a v == 0, setValidator() removes the current input validator. + The initial setting is to have no input validator (i.e. any input + is accepted up to maxLength()). + + \sa validator() QIntValidator QDoubleValidator QRegExpValidator +*/ + +void QSecureLineEdit::setValidator(const QValidator *v) +{ + Q_D(QSecureLineEdit); + d->validator = const_cast(v); +} +#endif // QT_NO_VALIDATOR + +#ifndef QT_NO_COMPLETER +/*! + \since 4.2 + + Sets this line edit to provide auto completions from the completer, \a c. + The completion mode is set using QCompleter::setCompletionMode(). + + To use a QCompleter with a QValidator or QSecureLineEdit::inputMask, you need to + ensure that the model provided to QCompleter contains valid entries. You can + use the QSortFilterProxyModel to ensure that the QCompleter's model contains + only valid entries. + + If \a c == 0, setCompleter() removes the current completer, effectively + disabling auto completion. + + \sa QCompleter +*/ +void QSecureLineEdit::setCompleter(QCompleter *c) +{ + Q_D(QSecureLineEdit); + if (c == d->completer) + return; + if (d->completer) { + disconnect(d->completer, 0, this, 0); + d->completer->setWidget(0); + if (d->completer->parent() == this) + delete d->completer; + } + d->completer = c; + if (!c) + return; + if (c->widget() == 0) + c->setWidget(this); + if (hasFocus()) { + QObject::connect(d->completer, SIGNAL(activated(QString)), + this, SLOT(setText(QString))); + QObject::connect(d->completer, SIGNAL(highlighted(QString)), + this, SLOT(_q_completionHighlighted(QString))); + } +} + +/*! + \since 4.2 + + Returns the current QCompleter that provides completions. +*/ +QCompleter *QSecureLineEdit::completer() const +{ + Q_D(const QSecureLineEdit); + return d->completer; +} + +// looks for an enabled item iterating forward(dir=1)/backward(dir=-1) from the +// current row based. dir=0 indicates a new completion prefix was set. +bool QSecureLineEditPrivate::advanceToEnabledItem(int dir) +{ + int start = completer->currentRow(); + if (start == -1) + return false; + int i = start + dir; + if (dir == 0) dir = 1; + do { + if (!completer->setCurrentRow(i)) { + if (!completer->wrapAround()) + break; + i = i > 0 ? 0 : completer->completionCount() - 1; + } else { + QModelIndex currentIndex = completer->currentIndex(); + if (completer->completionModel()->flags(currentIndex) & Qt::ItemIsEnabled) + return true; + i += dir; + } + } while (i != start); + + completer->setCurrentRow(start); // restore + return false; +} + +void QSecureLineEditPrivate::complete(int key) +{ + if (!completer || readOnly || echoMode != QSecureLineEdit::Normal) + return; + + if (completer->completionMode() == QCompleter::InlineCompletion) { + if (key == Qt::Key_Backspace) + return; + int n = 0; + if (key == Qt::Key_Up || key == Qt::Key_Down) { + if (selend != 0 && selend != text.length()) + return; + QString prefix = hasSelectedText() ? text.left(selstart) : text; + if (text.compare(completer->currentCompletion(), completer->caseSensitivity()) != 0 + || prefix.compare(completer->completionPrefix(), completer->caseSensitivity()) != 0) { + completer->setCompletionPrefix(prefix); + } else { + n = (key == Qt::Key_Up) ? -1 : +1; + } + } else { + completer->setCompletionPrefix(text); + } + if (!advanceToEnabledItem(n)) + return; + } else { +#ifndef QT_KEYPAD_NAVIGATION + if (text.isEmpty()) { + completer->popup()->hide(); + return; + } +#endif + completer->setCompletionPrefix(text); + } + + completer->complete(); +} + +void QSecureLineEditPrivate::_q_completionHighlighted(QString newText) +{ + Q_Q(QSecureLineEdit); + if (completer->completionMode() != QCompleter::InlineCompletion) + q->setText(newText); + else { + int c = cursor; + q->setText(text.left(c) + newText.mid(c)); + q->setSelection(text.length(), c - newText.length()); + } +} +#endif // QT_NO_COMPLETER + +/*! + Returns a recommended size for the widget. + + The width returned, in pixels, is usually enough for about 15 to + 20 characters. +*/ + +QSize QSecureLineEdit::sizeHint() const +{ + Q_D(const QSecureLineEdit); + ensurePolished(); + QFontMetrics fm(font()); + int leftmargin, topmargin, rightmargin, bottommargin; + getContentsMargins( &leftmargin, &topmargin, &rightmargin, &bottommargin ); + int h = qMax(fm.lineSpacing(), 14) + 2*verticalMargin + + topmargin + bottommargin; + int w = fm.width(QLatin1Char('x')) * 17 + 2*horizontalMargin + + leftmargin + rightmargin; // "some" + QStyleOptionFrameV2 opt; + initStyleOption(&opt); + return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h). + expandedTo(QApplication::globalStrut()), this)); +} + + +/*! + Returns a minimum size for the line edit. + + The width returned is enough for at least one character. +*/ + +QSize QSecureLineEdit::minimumSizeHint() const +{ + Q_D(const QSecureLineEdit); + ensurePolished(); + QFontMetrics fm = fontMetrics(); + int leftmargin, topmargin, rightmargin, bottommargin; + getContentsMargins( &leftmargin, &topmargin, &rightmargin, &bottommargin ); + int h = fm.height() + qMax(2*verticalMargin, fm.leading()) + + topmargin + bottommargin; + int w = fm.maxWidth() + leftmargin + rightmargin; + QStyleOptionFrameV2 opt; + initStyleOption(&opt); + return (style()->sizeFromContents(QStyle::CT_LineEdit, &opt, QSize(w, h). + expandedTo(QApplication::globalStrut()), this)); +} + + +/*! + \property QSecureLineEdit::cursorPosition + \brief the current cursor position for this line edit + + Setting the cursor position causes a repaint when appropriate. +*/ + +int QSecureLineEdit::cursorPosition() const +{ + Q_D(const QSecureLineEdit); + return d->cursor; +} + +void QSecureLineEdit::setCursorPosition(int pos) +{ + Q_D(QSecureLineEdit); + if (pos < 0) + pos = 0; + + if (pos <= d->text.length()) + d->moveCursor(pos); +} + +/*! + Returns the cursor position under the point \a pos. +*/ +// ### What should this do if the point is outside of contentsRect? Currently returns 0. +int QSecureLineEdit::cursorPositionAt(const QPoint &pos) +{ + Q_D(QSecureLineEdit); + return d->xToPos(pos.x()); +} + + +#ifdef QT3_SUPPORT +/*! \obsolete + + Use setText(), setCursorPosition() and setSelection() instead. +*/ +bool QSecureLineEdit::validateAndSet(const QString &newText, int newPos, + int newMarkAnchor, int newMarkDrag) +{ + Q_D(QSecureLineEdit); + int priorState = d->undoState; + d->selstart = 0; + d->selend = d->text.length(); + d->removeSelectedText(); + d->insert(newText); + d->finishChange(priorState); + if (d->undoState > priorState) { + d->cursor = newPos; + d->selstart = qMin(newMarkAnchor, newMarkDrag); + d->selend = qMax(newMarkAnchor, newMarkDrag); + update(); + d->emitCursorPositionChanged(); + return true; + } + return false; +} +#endif //QT3_SUPPORT + +/*! + \property QSecureLineEdit::alignment + \brief the alignment of the line edit + + Both horizontal and vertical alignment is allowed here, Qt::AlignJustify + will map to Qt::AlignLeft. + + \sa Qt::Alignment +*/ + +Qt::Alignment QSecureLineEdit::alignment() const +{ + Q_D(const QSecureLineEdit); + return QFlag(d->alignment); +} + +void QSecureLineEdit::setAlignment(Qt::Alignment alignment) +{ + Q_D(QSecureLineEdit); + d->alignment = alignment; + update(); +} + + +/*! + Moves the cursor forward \a steps characters. If \a mark is true + each character moved over is added to the selection; if \a mark is + false the selection is cleared. + + \sa cursorBackward() +*/ + +void QSecureLineEdit::cursorForward(bool mark, int steps) +{ + Q_D(QSecureLineEdit); + int cursor = d->cursor; + if (steps > 0) { + while(steps--) + cursor = d->textLayout.nextCursorPosition(cursor); + } else if (steps < 0) { + while (steps++) + cursor = d->textLayout.previousCursorPosition(cursor); + } + d->moveCursor(cursor, mark); +} + + +/*! + Moves the cursor back \a steps characters. If \a mark is true each + character moved over is added to the selection; if \a mark is + false the selection is cleared. + + \sa cursorForward() +*/ +void QSecureLineEdit::cursorBackward(bool mark, int steps) +{ + cursorForward(mark, -steps); +} + +/*! + Moves the cursor one word forward. If \a mark is true, the word is + also selected. + + \sa cursorWordBackward() +*/ +void QSecureLineEdit::cursorWordForward(bool mark) +{ + Q_D(QSecureLineEdit); + d->moveCursor(d->textLayout.nextCursorPosition(d->cursor, QTextLayout::SkipWords), mark); +} + +/*! + Moves the cursor one word backward. If \a mark is true, the word + is also selected. + + \sa cursorWordForward() +*/ + +void QSecureLineEdit::cursorWordBackward(bool mark) +{ + Q_D(QSecureLineEdit); + d->moveCursor(d->textLayout.previousCursorPosition(d->cursor, QTextLayout::SkipWords), mark); +} + + +/*! + If no text is selected, deletes the character to the left of the + text cursor and moves the cursor one position to the left. If any + text is selected, the cursor is moved to the beginning of the + selected text and the selected text is deleted. + + \sa del() +*/ +void QSecureLineEdit::backspace() +{ + Q_D(QSecureLineEdit); + int priorState = d->undoState; + if (d->hasSelectedText()) { + d->removeSelectedText(); + } else if (d->cursor) { + --d->cursor; + if (d->maskData) + d->cursor = d->prevMaskBlank(d->cursor); + QChar uc = d->text.at(d->cursor); + if (d->cursor > 0 && uc.unicode() >= 0xdc00 && uc.unicode() < 0xe000) { + // second half of a surrogate, check if we have the first half as well, + // if yes delete both at once + uc = d->text.at(d->cursor - 1); + if (uc.unicode() >= 0xd800 && uc.unicode() < 0xdc00) { + d->del(true); + --d->cursor; + } + } + d->del(true); + } + d->finishChange(priorState); +} + +/*! + If no text is selected, deletes the character to the right of the + text cursor. If any text is selected, the cursor is moved to the + beginning of the selected text and the selected text is deleted. + + \sa backspace() +*/ + +void QSecureLineEdit::del() +{ + Q_D(QSecureLineEdit); + int priorState = d->undoState; + if (d->hasSelectedText()) { + d->removeSelectedText(); + } else { + int n = d->textLayout.nextCursorPosition(d->cursor) - d->cursor; + while (n--) + d->del(); + } + d->finishChange(priorState); +} + +/*! + Moves the text cursor to the beginning of the line unless it is + already there. If \a mark is true, text is selected towards the + first position; otherwise, any selected text is unselected if the + cursor is moved. + + \sa end() +*/ + +void QSecureLineEdit::home(bool mark) +{ + Q_D(QSecureLineEdit); + d->moveCursor(0, mark); +} + +/*! + Moves the text cursor to the end of the line unless it is already + there. If \a mark is true, text is selected towards the last + position; otherwise, any selected text is unselected if the cursor + is moved. + + \sa home() +*/ + +void QSecureLineEdit::end(bool mark) +{ + Q_D(QSecureLineEdit); + d->moveCursor(d->text.length(), mark); +} + + +/*! + \property QSecureLineEdit::modified + \brief whether the line edit's contents has been modified by the user + + The modified flag is never read by QSecureLineEdit; it has a default value + of false and is changed to true whenever the user changes the line + edit's contents. + + This is useful for things that need to provide a default value but + do not start out knowing what the default should be (perhaps it + depends on other fields on the form). Start the line edit without + the best default, and when the default is known, if modified() + returns false (the user hasn't entered any text), insert the + default value. + + Calling setText() resets the modified flag to false. +*/ + +bool QSecureLineEdit::isModified() const +{ + Q_D(const QSecureLineEdit); + return d->modifiedState != d->undoState; +} + +void QSecureLineEdit::setModified(bool modified) +{ + Q_D(QSecureLineEdit); + if (modified) + d->modifiedState = -1; + else + d->modifiedState = d->undoState; +} + + +/*!\fn QSecureLineEdit::clearModified() + +Use setModified(false) instead. + + \sa isModified() +*/ + + +/*! + \property QSecureLineEdit::hasSelectedText + \brief whether there is any text selected + + hasSelectedText() returns true if some or all of the text has been + selected by the user; otherwise returns false. + + \sa selectedText() +*/ + + +bool QSecureLineEdit::hasSelectedText() const +{ + Q_D(const QSecureLineEdit); + return d->hasSelectedText(); +} + +/*! + \property QSecureLineEdit::selectedText + \brief the selected text + + If there is no selected text this property's value is + an empty string. + + \sa hasSelectedText() +*/ + +secqstring QSecureLineEdit::selectedText() const +{ + Q_D(const QSecureLineEdit); + if (d->hasSelectedText()) + return d->text.substr(d->selstart, d->selend - d->selstart); + return secqstring(); +} + +/*! + selectionStart() returns the index of the first selected character in the + line edit or -1 if no text is selected. + + \sa selectedText() +*/ + +int QSecureLineEdit::selectionStart() const From cvs at cvs.gnupg.org Thu Feb 19 17:19:16 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 19 Feb 2009 17:19:16 +0100 Subject: [svn] GnuPG - r4930 - in trunk: doc scd tests tests/pkits Message-ID: Author: wk Date: 2009-02-19 17:19:16 +0100 (Thu, 19 Feb 2009) New Revision: 4930 Modified: trunk/doc/faq.raw trunk/scd/ChangeLog trunk/scd/scdaemon.c trunk/tests/ChangeLog trunk/tests/Makefile.am trunk/tests/inittests trunk/tests/pkits/ChangeLog trunk/tests/pkits/Makefile.am trunk/tests/pkits/common.sh Log: Fix bug 1001. Documentation updates. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-02-12 17:45:40 UTC (rev 4929) +++ trunk/scd/ChangeLog 2009-02-19 16:19:16 UTC (rev 4930) @@ -154,7 +154,6 @@ 2008-10-14 Werner Koch - * apdu.c (reader_table_s): Add fields connect_card and disconnect_card. (new_reader_slot): Set them to NULL. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-02-12 17:45:40 UTC (rev 4929) +++ trunk/tests/ChangeLog 2009-02-19 16:19:16 UTC (rev 4930) @@ -1,3 +1,8 @@ +2009-02-19 Werner Koch + + * Makefile.am (TESTS_ENVIRONMENT): Use /bin/pwd. + * inittests: Ditto. Fixes bug#1001. + 2008-10-20 Werner Koch * asschk.c (cmd_echo): Mark unused arg. Modified: trunk/tests/pkits/ChangeLog =================================================================== --- trunk/tests/pkits/ChangeLog 2009-02-12 17:45:40 UTC (rev 4929) +++ trunk/tests/pkits/ChangeLog 2009-02-19 16:19:16 UTC (rev 4930) @@ -1,3 +1,8 @@ +2009-02-19 Werner Koch + + * Makefile.am (TESTS_ENVIRONMENT): Use /bin/pwd + * common.sh: Ditto. + 2008-02-19 Werner Koch * inittests: Unpack test data onlyu if available. Modified: trunk/doc/faq.raw =================================================================== --- trunk/doc/faq.raw 2009-02-12 17:45:40 UTC (rev 4929) +++ trunk/doc/faq.raw 2009-02-19 16:19:16 UTC (rev 4930) @@ -1326,7 +1326,19 @@ timestamp of the self-signature is increased by one second when running this command. + How can I import all the missing signer keys? + If you imported a key and you want to also import all the signer's + keys, you can do this with this command: + + gpg --check-sigs --with-colon KEYID \ + | awk -F: '$1 == "sig" && $2 == "?" { print $5 }' \ + | sort | uniq | xargs echo gpg --recv-keys + + Note that the invocation of sort is also required to wait for the + of the listing before before starting the import. + + ACKNOWLEDGEMENTS Many thanks to Nils Ellmenreich for maintaining this FAQ file for Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2009-02-12 17:45:40 UTC (rev 4929) +++ trunk/scd/scdaemon.c 2009-02-19 16:19:16 UTC (rev 4930) @@ -1075,7 +1075,7 @@ FD2INT(ctrl->thread_startup.fd)); /* If this is a pipe server, we request a shutdown if the command - hanlder asked for it. With the next ticker event and given that + handler asked for it. With the next ticker event and given that no other connections are running the shutdown will then happen. */ if (scd_command_handler (ctrl, FD2INT(ctrl->thread_startup.fd)) Modified: trunk/tests/Makefile.am =================================================================== --- trunk/tests/Makefile.am 2009-02-12 17:45:40 UTC (rev 4929) +++ trunk/tests/Makefile.am 2009-02-19 16:19:16 UTC (rev 4930) @@ -29,10 +29,12 @@ GPGSM = ../sm/gpgsm +# Note that we need to use /bin/pwd so that we don't get into trouble +# if the shell used for inittests would uses an internal version of +# pwd which handles symlinks differently. +TESTS_ENVIRONMENT = GNUPGHOME=`/bin/pwd` GPG_AGENT_INFO= LC_ALL=C \ + GPGSM=$(GPGSM) $(srcdir)/runtest -TESTS_ENVIRONMENT = GNUPGHOME=`pwd` GPG_AGENT_INFO= LC_ALL=C GPGSM=$(GPGSM) \ - $(srcdir)/runtest - testscripts = sm-sign+verify sm-verify EXTRA_DIST = runtest inittests $(testscripts) \ Modified: trunk/tests/inittests =================================================================== --- trunk/tests/inittests 2009-02-12 17:45:40 UTC (rev 4929) +++ trunk/tests/inittests 2009-02-19 16:19:16 UTC (rev 4930) @@ -51,7 +51,7 @@ exit 0 fi -if [ "$GNUPGHOME" != "`pwd`" ]; then +if [ "$GNUPGHOME" != "`/bin/pwd`" ]; then echo "inittests: please set GNUPGHOME to the test directory" >&2 exit 1 fi Modified: trunk/tests/pkits/Makefile.am =================================================================== --- trunk/tests/pkits/Makefile.am 2009-02-12 17:45:40 UTC (rev 4929) +++ trunk/tests/pkits/Makefile.am 2009-02-19 16:19:16 UTC (rev 4930) @@ -20,8 +20,8 @@ GPGSM = ../../sm/gpgsm -TESTS_ENVIRONMENT = GNUPGHOME=`pwd` GPG_AGENT_INFO= LC_ALL=C GPGSM=$(GPGSM) \ - silent=yes +TESTS_ENVIRONMENT = GNUPGHOME=`/bin/pwd` GPG_AGENT_INFO= LC_ALL=C \ + GPGSM=$(GPGSM) silent=yes testscripts = import-all-certs validate-all-certs \ Modified: trunk/tests/pkits/common.sh =================================================================== --- trunk/tests/pkits/common.sh 2009-02-12 17:45:40 UTC (rev 4929) +++ trunk/tests/pkits/common.sh 2009-02-19 16:19:16 UTC (rev 4930) @@ -42,7 +42,7 @@ MYTIME="20080508T120000" -if [ "$GNUPGHOME" != "`pwd`" ]; then +if [ "$GNUPGHOME" != "`/bin/pwd`" ]; then echo "inittests: please set GNUPGHOME to the tests/pkits directory" >&2 exit 1 fi From cvs at cvs.gnupg.org Fri Feb 20 16:41:11 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 20 Feb 2009 16:41:11 +0100 Subject: [svn] pinentry - r192 - in trunk: . secmem Message-ID: Author: marcus Date: 2009-02-20 16:41:11 +0100 (Fri, 20 Feb 2009) New Revision: 192 Added: trunk/secmem/secmem++.h Modified: trunk/ChangeLog Log: 2009-02-19 Marcus Brinkmann * secmem/secmem++.h: New file. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-02-19 16:18:41 UTC (rev 191) +++ trunk/ChangeLog 2009-02-20 15:41:11 UTC (rev 192) @@ -1,3 +1,14 @@ +2009-02-19 Marcus Brinkmann + + * secmem/secmem++.h: New file. + * qt4/Makefile.am, qt4/main.cpp, qt4/pinentrydialog.cpp, + qt4/pinentrydialog.h: Changes to use secure memory. + * qt4/pinentrydialog.moc, qt4/qsecurelineedit.moc: New files. + * qt4/qsecurelineedit.cpp, qt4/qsecurelineedit.h, + qt4/qsecurelineedit_p.h, qt4/secstring.h, qt4/secstring.cpp: New + files. + Submitted by Marc Mutz . + 2008-12-08 Werner Koch * qt/main.cpp (qt_cmd_handler) : Translate from utf8. Added: trunk/secmem/secmem++.h =================================================================== --- trunk/secmem/secmem++.h (rev 0) +++ trunk/secmem/secmem++.h 2009-02-20 15:41:11 UTC (rev 192) @@ -0,0 +1,91 @@ +/* STL allocator for secmem + * Copyright (C) 2008 Marc Mutz + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __SECMEM_SECMEMPP_H__ +#define __SECMEM_SECMEMPP_H__ + +#include "secmem/memory.h" +#include + +namespace secmem { + + template + class alloc { + public: + // type definitions: + typedef size_t size_type; + typedef ptrdiff_t difference_type; + typedef T* pointer; + typedef const T* const_pointer; + typedef T& reference; + typedef const T& const_reference; + typedef T value_type; + + // rebind + template + struct rebind { + typedef alloc other; + }; + + // address + pointer address( reference value ) const { + return &value; + } + const_pointer address( const_reference value ) const { + return &value; + } + + // (trivial) ctors and dtors + alloc() {} + alloc( const alloc & ) {} + template alloc( const alloc & ) {} + // copy ctor is ok + ~alloc() {} + + // de/allocation + size_type max_size() const { + return secmem_get_max_size(); + } + + pointer allocate( size_type n, void * =0 ) { + return static_cast( secmem_malloc( n * sizeof(T) ) ); + } + + void deallocate( pointer p, size_type ) { + secmem_free( p ); + } + + // de/construct + void construct( pointer p, const T & value ) { + void * loc = p; + new (loc)T(value); + } + void destruct( pointer p ) { + p->~T(); + } + }; + + // equality comparison + template + bool operator==( const alloc &, const alloc & ) { return true; } + template + bool operator!=( const alloc &, const alloc & ) { return false; } + +} + +#endif /* __SECMEM_SECMEMPP_H__ */ From cvs at cvs.gnupg.org Sun Feb 22 22:19:32 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Sun, 22 Feb 2009 22:19:32 +0100 Subject: [svn] gcry - r1392 - in trunk: . doc Message-ID: Author: wk Date: 2009-02-22 22:19:31 +0100 (Sun, 22 Feb 2009) New Revision: 1392 Modified: trunk/THANKS trunk/doc/ChangeLog trunk/doc/gcrypt.texi Log: Doc fixes Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2009-02-16 21:05:37 UTC (rev 1391) +++ trunk/doc/ChangeLog 2009-02-22 21:19:31 UTC (rev 1392) @@ -1,3 +1,8 @@ +2009-02-22 Werner Koch + + * gcrypt.texi (Memory allocation): Fix describion of gcry-calloc. + Reported by Sergi Blanch i Torn?. + 2008-12-10 Werner Koch * gcrypt.texi (Cryptographic Functions): Explain the domain Modified: trunk/THANKS =================================================================== --- trunk/THANKS 2009-02-16 21:05:37 UTC (rev 1391) +++ trunk/THANKS 2009-02-22 21:19:31 UTC (rev 1392) @@ -118,6 +118,7 @@ Roland Rosenfeld roland at spinnaker.rhein.de Ross Golder rossigee at bigfoot.com Serge Munhoven munhoven at mema.ucl.ac.be +Sergi Blanch i Torn? sergi at calcurco cat Simon Josefsson jas at extundo.com SL Baur steve at xemacs.org Stephan Austermuehle au at hcsd.de Modified: trunk/doc/gcrypt.texi =================================================================== --- trunk/doc/gcrypt.texi 2009-02-16 21:05:37 UTC (rev 1391) +++ trunk/doc/gcrypt.texi 2009-02-22 21:19:31 UTC (rev 1392) @@ -4643,15 +4643,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 From cvs at cvs.gnupg.org Tue Feb 24 12:47:26 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 24 Feb 2009 12:47:26 +0100 Subject: [svn] GnuPG - r4931 - trunk/g10 Message-ID: Author: wk Date: 2009-02-24 12:47:25 +0100 (Tue, 24 Feb 2009) New Revision: 4931 Modified: trunk/g10/ChangeLog trunk/g10/pkglue.c Log: Replace a call to BUG by an error return. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-02-19 16:19:16 UTC (rev 4930) +++ trunk/g10/ChangeLog 2009-02-24 11:47:25 UTC (rev 4931) @@ -1,3 +1,8 @@ +2009-02-24 Werner Koch + + * pkglue.c (pk_verify): Return an error for improper DATA instead + of calling BUG(). + 2009-02-09 Werner Koch * keylist.c (print_capabilities): Take care of cert-only keys. Modified: trunk/g10/pkglue.c =================================================================== --- trunk/g10/pkglue.c 2009-02-19 16:19:16 UTC (rev 4930) +++ trunk/g10/pkglue.c 2009-02-24 11:47:25 UTC (rev 4931) @@ -134,13 +134,14 @@ return GPG_ERR_PUBKEY_ALGO; if (rc) - BUG (); + BUG (); /* gcry_sexp_build should never fail. */ /* put hash into a S-Exp s_hash */ if (gcry_sexp_build (&s_hash, NULL, "%m", hash)) - BUG (); + BUG (); /* gcry_sexp_build should never fail. */ - /* put data into a S-Exp s_sig */ + /* Put data into a S-Exp s_sig. */ + s_sig = NULL; if (algo == GCRY_PK_DSA) { if (!data[0] || !data[1]) @@ -167,11 +168,9 @@ else BUG (); - if (rc) - BUG (); + if (!rc) + rc = gcry_pk_verify (s_sig, s_hash, s_pkey); - - rc = gcry_pk_verify (s_sig, s_hash, s_pkey); gcry_sexp_release (s_sig); gcry_sexp_release (s_hash); gcry_sexp_release (s_pkey); From cvs at cvs.gnupg.org Tue Feb 24 16:13:02 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 24 Feb 2009 16:13:02 +0100 Subject: [svn] gpgme - r1357 - in trunk: . assuan src tests tests/opassuan Message-ID: Author: wk Date: 2009-02-24 16:13:01 +0100 (Tue, 24 Feb 2009) New Revision: 1357 Modified: trunk/NEWS trunk/assuan/ChangeLog trunk/assuan/assuan-buffer.c trunk/src/ChangeLog trunk/src/engine-assuan.c trunk/src/gpgme.h.in trunk/src/opassuan.c trunk/tests/ChangeLog trunk/tests/opassuan/t-command.c Log: Chnaged the op-assuan interface. Modified: trunk/assuan/ChangeLog =================================================================== --- trunk/assuan/ChangeLog 2009-02-04 16:48:25 UTC (rev 1356) +++ trunk/assuan/ChangeLog 2009-02-24 15:13:01 UTC (rev 1357) @@ -1,3 +1,8 @@ +2009-02-24 Werner Koch + + * assuan-buffer.c (assuan_send_data): Add hack to optionally send + a final "CAN". + 2008-11-03 Marcus Brinkmann * Makefile.am (INCLUDES): Replace gpgme path with src. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-02-04 16:48:25 UTC (rev 1356) +++ trunk/src/ChangeLog 2009-02-24 15:13:01 UTC (rev 1357) @@ -1,3 +1,20 @@ +2009-02-24 Werner Koch + + * gpgme.h.in (struct _gpgme_op_assuan_result): New. + (gpgme_assuan_result_t): New. + (gpgme_op_assuan_result): Change return type. + (struct _gpgme_assuan_sendfnc_ctx) + (gpgme_assuan_sendfnc_ctx_t, gpgme_assuan_sendfnc_t):Remove. + (gpgme_assuan_inquire_cb_t): Changed. + * opassuan.c (op_data_t): Make use of a result structure. + (gpgme_op_assuan_result): Change return type. + (opassuan_start): Use result structure. + (result_cb): Ditto. + * engine-assuan.c (struct _gpgme_assuan_sendfnc_ctx): Remove. + (inquire_cb_sendfnc): Remove. + (inquire_cb): Change for new callback scheme. Not yet finished. + (llass_status_handler): Allow sending a CANCEL from the inquire CB. + 2009-02-04 Werner Koch * w32-glib-io.c (_gpgme_io_spawn): Make ARGV argument const to Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-02-04 16:48:25 UTC (rev 1356) +++ trunk/tests/ChangeLog 2009-02-24 15:13:01 UTC (rev 1357) @@ -1,3 +1,7 @@ +2009-02-24 Werner Koch + + * opassuan/t-command.c: Adjust for changed new op_assuan interface. + 2009-02-03 Werner Koch * gpg/t-keylist.c (main): Check that new fields is_cardkey and Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-02-04 16:48:25 UTC (rev 1356) +++ trunk/NEWS 2009-02-24 15:13:01 UTC (rev 1357) @@ -5,7 +5,6 @@ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GPGME_PROTOCOL_ASSUAN NEW. gpgme_assuan_data_cb_t NEW. - gpgme_assuan_sendfnc_ctx_t NEW. gpgme_assuan_inquire_cb_t NEW. gpgme_assuan_status_cb_t NEW. gpgme_op_assuan_transact_start NEW. Modified: trunk/assuan/assuan-buffer.c =================================================================== --- trunk/assuan/assuan-buffer.c 2009-02-04 16:48:25 UTC (rev 1356) +++ trunk/assuan/assuan-buffer.c 2009-02-24 15:13:01 UTC (rev 1357) @@ -491,6 +491,9 @@ * a INQUIRE response. However, when assuan_transact() is used, this * function takes care of sending END itself. * + * If BUFFER is NULL and LENGTH is 1 and we are a client, a "CAN" is + * send instead of an "END". + * * Return value: 0 on success or an error code **/ @@ -499,7 +502,7 @@ { if (!ctx) return _assuan_error (ASSUAN_Invalid_Value); - if (!buffer && length) + if (!buffer && length > 1) return _assuan_error (ASSUAN_Invalid_Value); if (!buffer) @@ -508,7 +511,7 @@ if (ctx->outbound.data.error) return ctx->outbound.data.error; if (!ctx->is_server) - return assuan_write_line (ctx, "END"); + return assuan_write_line (ctx, length == 1? "CAN":"END"); } else { Modified: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c 2009-02-04 16:48:25 UTC (rev 1356) +++ trunk/src/engine-assuan.c 2009-02-24 15:13:01 UTC (rev 1357) @@ -94,14 +94,8 @@ }; typedef struct engine_llass *engine_llass_t; -/* Helper to pass data to a callback. */ -struct _gpgme_assuan_sendfnc_ctx -{ - assuan_context_t assuan_ctx; -}; - /* Prototypes. */ static void llass_io_event (void *engine, gpgme_event_io_t type, void *type_data); @@ -212,6 +206,8 @@ { home_dir++; /* Very simple parser only working for the one option we support. */ + /* Note that wk promised to write a regression test if this + parser will be extended. */ if (!strncmp (home_dir, "GPG_AGENT", 9) && (!home_dir[9] || home_dir[9] == ' ')) llass->opt.gpg_agent = 1; @@ -372,18 +368,6 @@ } - -static gpgme_error_t -inquire_cb_sendfnc (gpgme_assuan_sendfnc_ctx_t ctx, - const void *data, size_t datalen) -{ - if (data && datalen) - return assuan_send_data (ctx->assuan_ctx, data, datalen); - else - return 0; /* Don't allow an inquire to send a flush. */ -} - - /* This is the inquiry callback. It handles stuff which ee need to handle here and passes everything on to the user callback. */ static gpgme_error_t @@ -398,12 +382,18 @@ if (llass->user.inq_cb) { - struct _gpgme_assuan_sendfnc_ctx sendfnc_ctx; + gpgme_data_t data = NULL; - sendfnc_ctx.assuan_ctx = llass->assuan_ctx; err = llass->user.inq_cb (llass->user.inq_cb_value, - keyword, args, - inquire_cb_sendfnc, &sendfnc_ctx); + keyword, args, &data); + if (!err && data) + { + /* FIXME: Returning data is not yet implemented. However we + need to allow the caller to cleanup his data object. + Thus we run the callback in finish mode immediately. */ + err = llass->user.inq_cb (llass->user.inq_cb_value, + NULL, NULL, &data); + } } else err = 0; @@ -528,8 +518,16 @@ args++; err = inquire_cb (llass, src, args); - if (!err) /* Flush and send END. */ - err = assuan_send_data (llass->assuan_ctx, NULL, 0); + if (!err) + { + /* Flush and send END. */ + err = assuan_send_data (llass->assuan_ctx, NULL, 0); + } + else if (gpg_err_code (err) == GPG_ERR_ASS_CANCELED) + { + /* Flush and send CANcel. */ + err = assuan_send_data (llass->assuan_ctx, NULL, 1); + } } else if (linelen >= 3 && line[0] == 'E' && line[1] == 'R' && line[2] == 'R' Modified: trunk/src/gpgme.h.in =================================================================== --- trunk/src/gpgme.h.in 2009-02-04 16:48:25 UTC (rev 1356) +++ trunk/src/gpgme.h.in 2009-02-24 15:13:01 UTC (rev 1357) @@ -1671,21 +1671,24 @@ typedef gpgme_error_t (*gpgme_assuan_data_cb_t) (void *opaque, const void *data, size_t datalen); -struct _gpgme_assuan_sendfnc_ctx; -typedef struct _gpgme_assuan_sendfnc_ctx *gpgme_assuan_sendfnc_ctx_t; -typedef gpgme_error_t (*gpgme_assuan_sendfnc_t) - (gpgme_assuan_sendfnc_ctx_t ctx, const void *data, size_t datalen); - typedef gpgme_error_t (*gpgme_assuan_inquire_cb_t) (void *opaque, const char *name, const char *args, - gpgme_assuan_sendfnc_t sendfnc, - gpgme_assuan_sendfnc_ctx_t sendfnc_ctx); + gpgme_data_t *r_data); typedef gpgme_error_t (*gpgme_assuan_status_cb_t) (void *opaque, const char *status, const char *args); +struct _gpgme_op_assuan_result +{ + /* The result of the actual assuan command. An OK is indicated by a + value of 0 and an ERR by the respective error error value. */ + gpgme_error_t err; +}; +typedef struct _gpgme_op_assuan_result *gpgme_assuan_result_t; + + /* Return the result of the last Assuan command. */ -gpgme_error_t gpgme_op_assuan_result (gpgme_ctx_t ctx); +gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx); /* Send the Assuan COMMAND and return results via the callbacks. Asynchronous variant. */ Modified: trunk/src/opassuan.c =================================================================== --- trunk/src/opassuan.c 2009-02-04 16:48:25 UTC (rev 1356) +++ trunk/src/opassuan.c 2009-02-24 15:13:01 UTC (rev 1357) @@ -26,11 +26,11 @@ #include "ops.h" #include "util.h" + typedef struct { - /* The result of the assuan command with 0 for OK and an error value - for ERR. */ - gpgme_error_t result; + struct _gpgme_op_assuan_result result; + } *op_data_t; @@ -55,12 +55,12 @@ if (!opd) return gpg_error (GPG_ERR_INTERNAL); - opd->result = result; + opd->result.err = result; return 0; } -gpgme_error_t +gpgme_assuan_result_t gpgme_op_assuan_result (gpgme_ctx_t ctx) { gpgme_error_t err; @@ -69,12 +69,12 @@ err = _gpgme_op_data_lookup (ctx, OPDATA_ASSUAN, &hook, -1, NULL); opd = hook; - if (err) - return err; - if (!opd) - return gpg_error (GPG_ERR_INTERNAL); + /* Check in case this function is used without having run a command + before. */ + if (err || !opd) + return NULL; - return opd->result; + return &opd->result; } @@ -105,7 +105,7 @@ opd = hook; if (err) return err; - opd->result = gpg_error (GPG_ERR_UNFINISHED); + opd->result.err = gpg_error (GPG_ERR_UNFINISHED); return _gpgme_engine_op_assuan_transact (ctx->engine, command, result_cb, ctx, Modified: trunk/tests/opassuan/t-command.c =================================================================== --- trunk/tests/opassuan/t-command.c 2009-02-04 16:48:25 UTC (rev 1356) +++ trunk/tests/opassuan/t-command.c 2009-02-24 15:13:01 UTC (rev 1357) @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -52,11 +53,37 @@ static gpg_error_t inq_cb (void *opaque, const char *name, const char *args, - gpgme_assuan_sendfnc_t sendfnc, - gpgme_assuan_sendfnc_ctx_t sendfnc_value) + gpgme_data_t *r_data) { - printf ("INQ_CB: name=`%s' args=`%s'\n", name, args); + gpgme_data_t data; + gpg_error_t err; + if (name) + { + printf ("INQ_CB: name=`%s' args=`%s'\n", name, args); + /* There shall be no data object. */ + assert (!*r_data); + + err = gpgme_data_new (&data); + fail_if_err (err); + *r_data = data; + printf (" sending data object %p\n", data); + } + else /* Finished using the formerly returned data object. */ + { + printf ("INQ_CB: data object %p finished\n", *r_data); + /* There shall be a data object so that it can be cleaned up. */ + assert (r_data); + + gpgme_data_release (*r_data); + } + + /* Uncomment the next lines and send a "SCD LEARN" to test sending + cancel from in inquiry. */ + /* if (name && !strcmp (name, "KNOWNCARDP")) */ + /* return gpg_error (GPG_ERR_ASS_CANCELED); */ + + return 0; } @@ -70,9 +97,6 @@ - - - int main (int argc, char **argv) { @@ -106,7 +130,7 @@ inq_cb, NULL, status_cb, NULL); fail_if_err (err); - err = gpgme_op_assuan_result (ctx); + err = gpgme_op_assuan_result (ctx)->err; if (err) fprintf (stderr, "assuan command `%s' failed: %s <%s> (%d)\n", command, gpg_strerror (err), gpg_strsource (err), err); From cvs at cvs.gnupg.org Tue Feb 24 16:24:58 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 24 Feb 2009 16:24:58 +0100 Subject: [svn] assuan - r294 - in trunk: . doc src Message-ID: Author: wk Date: 2009-02-24 16:24:58 +0100 (Tue, 24 Feb 2009) New Revision: 294 Modified: trunk/AUTHORS trunk/doc/assuan.texi trunk/src/ChangeLog trunk/src/assuan-buffer.c Log: Add hack for the inquiry feature. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-01-22 15:06:28 UTC (rev 293) +++ trunk/src/ChangeLog 2009-02-24 15:24:58 UTC (rev 294) @@ -1,3 +1,8 @@ +2009-02-24 Werner Koch + + * assuan-buffer.c (assuan_send_data): Add hack to optionally send + a final "CAN". + 2008-11-03 Marcus Brinkmann * assuan-handler.c (std_handler_help): Make I unsigned to silence Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2009-01-22 15:06:28 UTC (rev 293) +++ trunk/AUTHORS 2009-02-24 15:24:58 UTC (rev 294) @@ -2,7 +2,8 @@ Maintainer: Werner Koch Bug reports: gnupg-devel at gnupg.org Security related bug reports: security at gnupg.org -License: LGPLv2.1+ +License (library): LGPLv2.1+ +License (manual): GPLv3+ Werner Koch Modified: trunk/doc/assuan.texi =================================================================== --- trunk/doc/assuan.texi 2009-01-22 15:06:28 UTC (rev 293) +++ trunk/doc/assuan.texi 2009-02-24 15:24:58 UTC (rev 294) @@ -247,7 +247,9 @@ specific except for a few common ones. @item S @var{keyword} -Informational output by the server, still processing the request. +Informational output by the server, still processing the request. A +client may not send such lines to the server while processing an Inquiry +command. @item # Comment line issued only for debugging purposes. Totally ignored. Modified: trunk/src/assuan-buffer.c =================================================================== --- trunk/src/assuan-buffer.c 2009-01-22 15:06:28 UTC (rev 293) +++ trunk/src/assuan-buffer.c 2009-02-24 15:24:58 UTC (rev 294) @@ -507,6 +507,9 @@ * a INQUIRE response. However, when assuan_transact() is used, this * function takes care of sending END itself. * + * If BUFFER is NULL and LENGTH is 1 and we are a client, a "CAN" is + * send instead of an "END". + * * Return value: 0 on success or an error code **/ @@ -515,7 +518,7 @@ { if (!ctx) return _assuan_error (ASSUAN_Invalid_Value); - if (!buffer && length) + if (!buffer && length > 1) return _assuan_error (ASSUAN_Invalid_Value); if (!buffer) @@ -524,7 +527,7 @@ if (ctx->outbound.data.error) return ctx->outbound.data.error; if (!ctx->is_server) - return assuan_write_line (ctx, "END"); + return assuan_write_line (ctx, length == 1? "CAN":"END"); } else { From cvs at cvs.gnupg.org Tue Feb 24 21:41:44 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 24 Feb 2009 21:41:44 +0100 Subject: [svn] GnuPG - r4932 - trunk/scd Message-ID: Author: wk Date: 2009-02-24 21:41:44 +0100 (Tue, 24 Feb 2009) New Revision: 4932 Modified: trunk/scd/ChangeLog trunk/scd/ccid-driver.c Log: Better debug output. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-02-24 11:47:25 UTC (rev 4931) +++ trunk/scd/ChangeLog 2009-02-24 20:41:44 UTC (rev 4932) @@ -1,3 +1,26 @@ +2009-02-24 Werner Koch + + * ccid-driver.c (ccid_get_atr): Move debug output to .. + (print_r2p_parameters): .. new. + (print_r2p_header, print_pr_data, print_r2p_unknown) + (print_r2p_datablock, print_r2p_slotstatus, print_r2p_escape) + (print_r2p_datarate): New. + (bulk_in): Call parameter printing. + (ccid_set_debug_level): Add debug level 3. + (convert_le_u16): New. + (print_p2r_header, print_p2r_iccpoweron, print_p2r_iccpoweroff) + (print_p2r_getslotstatus, print_p2r_xfrblock) + (print_p2r_getparameters, print_p2r_resetparameters) + (print_p2r_setparameters, print_p2r_escape, print_p2r_iccclock) + (print_p2r_to0apdu, print_p2r_secure, print_p2r_mechanical) + (print_p2r_abort, print_p2r_setdatarate, print_r2p_unknown): New. + (bulk_out): Add arg NO_DEBUG and change all callers to pass 0. + Call parameter printing. + (ccid_slot_status): Call with NO_DEBUG set. + (abort_cmd, send_escape_cmd, ccid_get_atr, ccid_get_atr) + (ccid_transceive_apdu_level, ccid_transceive) + (ccid_transceive_secure): Remove old debug print code. + 2009-02-12 Werner Koch * command.c (cmd_getinfo): Add new subcommand "deny_admin". Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2009-02-24 11:47:25 UTC (rev 4931) +++ trunk/scd/ccid-driver.c 2009-02-24 20:41:44 UTC (rev 4932) @@ -253,13 +253,15 @@ static int debug_level; /* Flag to control the debug output. 0 = No debugging 1 = USB I/O info - 2 = T=1 protocol tracing + 2 = Level 1 + T=1 protocol tracing + 3 = Level 2 + USB/I/O tracing of SlotStatus. */ static unsigned int compute_edc (const unsigned char *data, size_t datalen, int use_crc); -static int bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen); +static int bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen, + int no_debug); static int bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, size_t *nread, int expected_type, int seqno, int timeout, int no_debug); @@ -273,6 +275,15 @@ return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24); } + +/* Convert a little endian stored 2 byte value into an unsigned + integer. */ +static unsigned int +convert_le_u16 (const unsigned char *buf) +{ + return buf[0] | (buf[1] << 8); +} + static void set_msg_len (unsigned char *msg, unsigned int length) { @@ -328,8 +339,318 @@ } DEBUGOUT_1 ("CCID command failed: %s\n", t); } + + +static void +print_pr_data (const unsigned char *data, size_t datalen, size_t off) +{ + int any = 0; + + for (; off < datalen; off++) + { + if (!any || !(off % 16)) + { + if (any) + DEBUGOUT_LF (); + DEBUGOUT_1 (" [%04d] ", off); + } + DEBUGOUT_CONT_1 (" %02X", data[off]); + any = 1; + } + if (any && !(off % 16)) + DEBUGOUT_LF (); +} + + +static void +print_p2r_header (const char *name, const unsigned char *msg, size_t msglen) +{ + DEBUGOUT_1 ("%s:\n", name); + if (msglen < 7) + return; + DEBUGOUT_1 (" dwLength ..........: %u\n", convert_le_u32 (msg+1)); + DEBUGOUT_1 (" bSlot .............: %u\n", msg[5]); + DEBUGOUT_1 (" bSeq ..............: %u\n", msg[6]); +} + + +static void +print_p2r_iccpoweron (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_IccPowerOn", msg, msglen); + if (msglen < 10) + return; + DEBUGOUT_2 (" bPowerSelect ......: 0x%02x (%s)\n", msg[7], + msg[7] == 0? "auto": + msg[7] == 1? "5.0 V": + msg[7] == 2? "3.0 V": + msg[7] == 3? "1.8 V":""); + print_pr_data (msg, msglen, 8); +} + + +static void +print_p2r_iccpoweroff (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_IccPowerOff", msg, msglen); + print_pr_data (msg, msglen, 7); +} + + +static void +print_p2r_getslotstatus (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_GetSlotStatus", msg, msglen); + print_pr_data (msg, msglen, 7); +} + + +static void +print_p2r_xfrblock (const unsigned char *msg, size_t msglen) +{ + unsigned int val; + + print_p2r_header ("PC_to_RDR_XfrBlock", msg, msglen); + if (msglen < 10) + return; + DEBUGOUT_1 (" bBWI ..............: 0x%02x\n", msg[7]); + val = convert_le_u16 (msg+8); + DEBUGOUT_2 (" wLevelParameter ...: 0x%04x%s\n", val, + val == 1? " (continued)": + val == 2? " (continues+ends)": + val == 3? " (continues+continued)": + val == 16? " (DataBlock-expected)":""); + print_pr_data (msg, msglen, 10); +} + + +static void +print_p2r_getparameters (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_GetParameters", msg, msglen); + print_pr_data (msg, msglen, 7); +} + + +static void +print_p2r_resetparameters (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_ResetParameters", msg, msglen); + print_pr_data (msg, msglen, 7); +} + + +static void +print_p2r_setparameters (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_SetParameters", msg, msglen); + if (msglen < 10) + return; + DEBUGOUT_1 (" bProtocolNum ......: 0x%02x\n", msg[7]); + print_pr_data (msg, msglen, 8); +} + + +static void +print_p2r_escape (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_Escape", msg, msglen); + print_pr_data (msg, msglen, 7); +} + + +static void +print_p2r_iccclock (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_IccClock", msg, msglen); + if (msglen < 10) + return; + DEBUGOUT_1 (" bClockCommand .....: 0x%02x\n", msg[7]); + print_pr_data (msg, msglen, 8); +} + + +static void +print_p2r_to0apdu (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_T0APDU", msg, msglen); + if (msglen < 10) + return; + DEBUGOUT_1 (" bmChanges .........: 0x%02x\n", msg[7]); + DEBUGOUT_1 (" bClassGetResponse .: 0x%02x\n", msg[8]); + DEBUGOUT_1 (" bClassEnvelope ....: 0x%02x\n", msg[9]); + print_pr_data (msg, msglen, 10); +} + + +static void +print_p2r_secure (const unsigned char *msg, size_t msglen) +{ + unsigned int val; + + print_p2r_header ("PC_to_RDR_Secure", msg, msglen); + if (msglen < 10) + return; + DEBUGOUT_1 (" bBMI ..............: 0x%02x\n", msg[7]); + val = convert_le_u16 (msg+8); + DEBUGOUT_2 (" wLevelParameter ...: 0x%04x%s\n", val, + val == 1? " (continued)": + val == 2? " (continues+ends)": + val == 3? " (continues+continued)": + val == 16? " (DataBlock-expected)":""); + print_pr_data (msg, msglen, 10); +} + + +static void +print_p2r_mechanical (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_Mechanical", msg, msglen); + if (msglen < 10) + return; + DEBUGOUT_1 (" bFunction .........: 0x%02x\n", msg[7]); + print_pr_data (msg, msglen, 8); +} + + +static void +print_p2r_abort (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_Abort", msg, msglen); + print_pr_data (msg, msglen, 7); +} + + +static void +print_p2r_setdatarate (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("PC_to_RDR_SetDataRate", msg, msglen); + if (msglen < 10) + return; + print_pr_data (msg, msglen, 7); +} + + +static void +print_p2r_unknown (const unsigned char *msg, size_t msglen) +{ + print_p2r_header ("Unknown PC_to_RDR command", msg, msglen); + if (msglen < 10) + return; + print_pr_data (msg, msglen, 0); +} + + +static void +print_r2p_header (const char *name, const unsigned char *msg, size_t msglen) +{ + DEBUGOUT_1 ("%s:\n", name); + if (msglen < 9) + return; + DEBUGOUT_1 (" dwLength ..........: %u\n", convert_le_u32 (msg+1)); + DEBUGOUT_1 (" bSlot .............: %u\n", msg[5]); + DEBUGOUT_1 (" bSeq ..............: %u\n", msg[6]); + DEBUGOUT_1 (" bStatus ...........: %u\n", msg[7]); + if (msg[8]) + DEBUGOUT_1 (" bError ............: %u\n", msg[8]); +} + + +static void +print_r2p_datablock (const unsigned char *msg, size_t msglen) +{ + print_r2p_header ("RDR_to_PC_DataBlock", msg, msglen); + if (msglen < 10) + return; + if (msg[9]) + DEBUGOUT_2 (" bChainParameter ...: 0x%02x%s\n", msg[9], + msg[9] == 1? " (continued)": + msg[9] == 2? " (continues+ends)": + msg[9] == 3? " (continues+continued)": + msg[9] == 16? " (XferBlock-expected)":""); + print_pr_data (msg, msglen, 10); +} + + +static void +print_r2p_slotstatus (const unsigned char *msg, size_t msglen) +{ + print_r2p_header ("RDR_to_PC_SlotStatus", msg, msglen); + if (msglen < 10) + return; + DEBUGOUT_2 (" bClockStatus ......: 0x%02x%s\n", msg[9], + msg[9] == 0? " (running)": + msg[9] == 1? " (stopped-L)": + msg[9] == 2? " (stopped-H)": + msg[9] == 3? " (stopped)":""); + print_pr_data (msg, msglen, 10); +} +static void +print_r2p_parameters (const unsigned char *msg, size_t msglen) +{ + print_r2p_header ("RDR_to_PC_Parameters", msg, msglen); + if (msglen < 10) + return; + + DEBUGOUT_1 (" protocol ..........: T=%d\n", msg[9]); + if (msglen == 17 && msg[9] == 1) + { + /* Protocol T=1. */ + DEBUGOUT_1 (" bmFindexDindex ....: %02X\n", msg[10]); + DEBUGOUT_1 (" bmTCCKST1 .........: %02X\n", msg[11]); + DEBUGOUT_1 (" bGuardTimeT1 ......: %02X\n", msg[12]); + DEBUGOUT_1 (" bmWaitingIntegersT1: %02X\n", msg[13]); + DEBUGOUT_1 (" bClockStop ........: %02X\n", msg[14]); + DEBUGOUT_1 (" bIFSC .............: %d\n", msg[15]); + DEBUGOUT_1 (" bNadValue .........: %d\n", msg[16]); + } + else + print_pr_data (msg, msglen, 10); +} + + +static void +print_r2p_escape (const unsigned char *msg, size_t msglen) +{ + print_r2p_header ("RDR_to_PC_Escape", msg, msglen); + if (msglen < 10) + return; + DEBUGOUT_1 (" buffer[9] .........: %02X\n", msg[9]); + print_pr_data (msg, msglen, 10); +} + + +static void +print_r2p_datarate (const unsigned char *msg, size_t msglen) +{ + print_r2p_header ("RDR_to_PC_DataRate", msg, msglen); + if (msglen < 10) + return; + if (msglen >= 18) + { + DEBUGOUT_1 (" dwClockFrequency ..: %u\n", convert_le_u32 (msg+10)); + DEBUGOUT_1 (" dwDataRate ..... ..: %u\n", convert_le_u32 (msg+14)); + print_pr_data (msg, msglen, 18); + } + else + print_pr_data (msg, msglen, 10); +} + + +static void +print_r2p_unknown (const unsigned char *msg, size_t msglen) +{ + print_r2p_header ("Unknown RDR_to_PC command", msg, msglen); + if (msglen < 10) + return; + DEBUGOUT_1 (" bMessageType ......: %02X\n", msg[0]); + DEBUGOUT_1 (" buffer[9] .........: %02X\n", msg[9]); + print_pr_data (msg, msglen, 10); +} + + /* Given a handle used for special transport prepare it for use. In particular setup all information in way that resembles what parse_cccid_descriptor does. */ @@ -1071,7 +1392,8 @@ /* 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, other values are not yet defined. + protocol, 3 additionally enables debuggng for GetSlotStatus, other + values are not yet defined. Note that libusb may provide its own debugging feature which is enabled by setting the envvar USB_DEBUG. */ @@ -1247,7 +1569,7 @@ set_msg_len (msg, 0); msglen = 10; - rc = bulk_out (handle, msg, msglen); + rc = bulk_out (handle, msg, msglen, 0); if (!rc) bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_SlotStatus, seqno, 2000, 0); @@ -1391,10 +1713,63 @@ /* Write a MSG of length MSGLEN to the designated bulk out endpoint. Returns 0 on success. */ static int -bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen) +bulk_out (ccid_driver_t handle, unsigned char *msg, size_t msglen, + int no_debug) { int rc; + if (debug_level && (!no_debug || debug_level >= 3)) + { + switch (msglen? msg[0]:0) + { + case PC_to_RDR_IccPowerOn: + print_p2r_iccpoweron (msg, msglen); + break; + case PC_to_RDR_IccPowerOff: + print_p2r_iccpoweroff (msg, msglen); + break; + case PC_to_RDR_GetSlotStatus: + print_p2r_getslotstatus (msg, msglen); + break; + case PC_to_RDR_XfrBlock: + print_p2r_xfrblock (msg, msglen); + break; + case PC_to_RDR_GetParameters: + print_p2r_getparameters (msg, msglen); + break; + case PC_to_RDR_ResetParameters: + print_p2r_resetparameters (msg, msglen); + break; + case PC_to_RDR_SetParameters: + print_p2r_setparameters (msg, msglen); + break; + case PC_to_RDR_Escape: + print_p2r_escape (msg, msglen); + break; + case PC_to_RDR_IccClock: + print_p2r_iccclock (msg, msglen); + break; + case PC_to_RDR_T0APDU: + print_p2r_to0apdu (msg, msglen); + break; + case PC_to_RDR_Secure: + print_p2r_secure (msg, msglen); + break; + case PC_to_RDR_Mechanical: + print_p2r_mechanical (msg, msglen); + break; + case PC_to_RDR_Abort: + print_p2r_abort (msg, msglen); + break; + case PC_to_RDR_SetDataRate: + print_p2r_setdatarate (msg, msglen); + break; + default: + print_p2r_unknown (msg, msglen); + break; + } + } + if (handle->idev) { rc = usb_bulk_write (handle->idev, @@ -1426,13 +1801,14 @@ is the sequence number used to send the request and EXPECTED_TYPE the type of message we expect. Does checks on the ccid header. TIMEOUT is the timeout value in ms. NO_DEBUG may be set to - avoid debug messages in case of no error. Returns 0 on success. */ + avoid debug messages in case of no error; this can be overriden + with a glibal debug level of at least 3. Returns 0 on success. */ static int bulk_in (ccid_driver_t handle, unsigned char *buffer, size_t length, size_t *nread, int expected_type, int seqno, int timeout, int no_debug) { - int i, rc; + int rc; size_t msglen; /* Fixme: The next line for the current Valgrind without support @@ -1486,7 +1862,7 @@ } /* We need to handle the time extension request before we check that - we go the expected message type. This is in particular required + we got the expected message type. This is in particular required for the Cherry keyboard which sends a time extension request for each key hit. */ if ( !(buffer[7] & 0x03) && (buffer[7] & 0xC0) == 0x80) @@ -1505,13 +1881,29 @@ } - if (!no_debug) + if (debug_level && (!no_debug || debug_level >= 3)) { - DEBUGOUT_3 ("status: %02X error: %02X octet[9]: %02X\n" - " data:", buffer[7], buffer[8], buffer[9] ); - for (i=10; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", buffer[i]); - DEBUGOUT_LF (); + switch (buffer[0]) + { + case RDR_to_PC_DataBlock: + print_r2p_datablock (buffer, msglen); + break; + case RDR_to_PC_SlotStatus: + print_r2p_slotstatus (buffer, msglen); + break; + case RDR_to_PC_Parameters: + print_r2p_parameters (buffer, msglen); + break; + case RDR_to_PC_Escape: + print_r2p_escape (buffer, msglen); + break; + case RDR_to_PC_DataRate: + print_r2p_datarate (buffer, msglen); + break; + default: + print_r2p_unknown (buffer, msglen); + break; + } } if (CCID_COMMAND_FAILED (buffer)) print_command_failed (buffer); @@ -1540,7 +1932,6 @@ unsigned char seqno; unsigned char msg[100]; size_t msglen; - int i; if (!handle->idev) { @@ -1579,10 +1970,6 @@ set_msg_len (msg, 0); handle->seqno++; /* Bumb up for the next use. */ - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); rc = usb_bulk_write (handle->idev, handle->ep_bulk_out, (char*)msg, msglen, @@ -1647,7 +2034,7 @@ const unsigned char *data, size_t datalen, unsigned char *result, size_t resultmax, size_t *resultlen) { - int i, rc; + int rc; unsigned char msg[100]; size_t msglen; unsigned char seqno; @@ -1668,11 +2055,7 @@ msglen = 10 + datalen; set_msg_len (msg, datalen); - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - rc = bulk_out (handle, msg, msglen); + rc = bulk_out (handle, msg, msglen, 0); if (rc) return rc; rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Escape, @@ -1793,7 +2176,7 @@ msg[9] = 0; /* RFU */ set_msg_len (msg, 0); - rc = bulk_out (handle, msg, 10); + rc = bulk_out (handle, msg, 10, 1); if (rc) return rc; /* Note that we set the NO_DEBUG flag here, so that the logs won't @@ -1837,7 +2220,6 @@ unsigned char seqno; int use_crc = 0; unsigned int edc; - int i; int tried_iso = 0; int got_param; @@ -1860,7 +2242,7 @@ set_msg_len (msg, 0); msglen = 10; - rc = bulk_out (handle, msg, msglen); + rc = bulk_out (handle, msg, msglen, 0); if (rc) return rc; rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_DataBlock, @@ -1905,34 +2287,14 @@ msg[9] = 0; /* RFU */ set_msg_len (msg, 0); msglen = 10; - rc = bulk_out (handle, msg, msglen); + rc = bulk_out (handle, msg, msglen, 0); if (!rc) rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters, seqno, 2000, 0); if (rc) DEBUGOUT ("GetParameters failed\n"); - else - { - DEBUGOUT ("GetParametes returned"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - if (msglen >= 10) - { - DEBUGOUT_1 (" protocol ..........: T=%d\n", msg[9]); - if (msglen == 17 && msg[9] == 1) - { - DEBUGOUT_1 (" bmFindexDindex ....: %02X\n", msg[10]); - DEBUGOUT_1 (" bmTCCKST1 .........: %02X\n", msg[11]); - DEBUGOUT_1 (" bGuardTimeT1 ......: %02X\n", msg[12]); - DEBUGOUT_1 (" bmWaitingIntegersT1: %02X\n", msg[13]); - DEBUGOUT_1 (" bClockStop ........: %02X\n", msg[14]); - DEBUGOUT_1 (" bIFSC .............: %d\n", msg[15]); - DEBUGOUT_1 (" bNadValue .........: %d\n", msg[16]); - got_param = 1; - } - } - } + else if (msglen == 17 && msg[9] == 1) + got_param = 1; /* Setup parameters to select T=1. */ msg[0] = PC_to_RDR_SetParameters; @@ -1956,12 +2318,7 @@ set_msg_len (msg, 7); msglen = 10 + 7; - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - - rc = bulk_out (handle, msg, msglen); + rc = bulk_out (handle, msg, msglen, 0); if (rc) return rc; rc = bulk_in (handle, msg, sizeof msg, &msglen, RDR_to_PC_Parameters, @@ -1996,11 +2353,6 @@ set_msg_len (msg, tpdulen); msglen = 10 + tpdulen; - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - if (debug_level > 1) DEBUGOUT_3 ("T=1: put %c-block seq=%d%s\n", ((msg[11] & 0xc0) == 0x80)? 'R' : @@ -2009,7 +2361,7 @@ : !!(msg[11] & 0x40)), (!(msg[11] & 0x80) && (msg[11] & 0x20)? " [more]":"")); - rc = bulk_out (handle, msg, msglen); + rc = bulk_out (handle, msg, msglen, 0); if (rc) return rc; @@ -2080,7 +2432,6 @@ unsigned char *msg; size_t msglen; unsigned char seqno; - int i; msg = send_buffer; @@ -2090,7 +2441,7 @@ /* The maximum length for a short APDU T=1 block is 261. For an extended APDU T=1 block the maximum length 65544; however - extended APDU exchange levele is not yet supported. */ + extended APDU exchange level is not yet supported. */ if (apdulen > 261) return CCID_DRIVER_ERR_INV_VALUE; /* Invalid length. */ @@ -2104,12 +2455,7 @@ set_msg_len (msg, apdulen); msglen = 10 + apdulen; - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - - rc = bulk_out (handle, msg, msglen); + rc = bulk_out (handle, msg, msglen, 0); if (rc) return rc; @@ -2205,7 +2551,6 @@ unsigned char *msg, *tpdu, *p; size_t msglen, tpdulen, last_tpdulen, n; unsigned char seqno; - int i; unsigned int edc; int use_crc = 0; size_t dummy_nresp; @@ -2274,11 +2619,6 @@ msglen = 10 + tpdulen; last_tpdulen = tpdulen; - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - if (debug_level > 1) DEBUGOUT_3 ("T=1: put %c-block seq=%d%s\n", ((msg[11] & 0xc0) == 0x80)? 'R' : @@ -2287,7 +2627,7 @@ : !!(msg[11] & 0x40)), (!(msg[11] & 0x80) && (msg[11] & 0x20)? " [more]":"")); - rc = bulk_out (handle, msg, msglen); + rc = bulk_out (handle, msg, msglen, 0); if (rc) return rc; @@ -2464,7 +2804,6 @@ unsigned char *msg, *tpdu, *p; size_t msglen, tpdulen, n; unsigned char seqno; - int i; size_t dummy_nresp; int testmode; int cherry_mode = 0; @@ -2585,12 +2924,7 @@ /* An EDC is not required. */ set_msg_len (msg, msglen - 10); - DEBUGOUT ("sending"); - for (i=0; i < msglen; i++) - DEBUGOUT_CONT_1 (" %02X", msg[i]); - DEBUGOUT_LF (); - - rc = bulk_out (handle, msg, msglen); + rc = bulk_out (handle, msg, msglen, 0); if (rc) return rc; @@ -2733,6 +3067,7 @@ fprintf (stderr, "operation failed: %s\n", p); } + static void print_data (const unsigned char *data, size_t length) { From cvs at cvs.gnupg.org Wed Feb 25 11:58:56 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 25 Feb 2009 11:58:56 +0100 Subject: [svn] GnuPG - r4933 - in trunk: agent doc jnlib scd Message-ID: Author: wk Date: 2009-02-25 11:58:56 +0100 (Wed, 25 Feb 2009) New Revision: 4933 Modified: trunk/agent/gpg-agent.c trunk/doc/scdaemon.texi trunk/jnlib/ChangeLog trunk/jnlib/logging.c trunk/jnlib/logging.h trunk/scd/ChangeLog trunk/scd/apdu.c trunk/scd/ccid-driver.c trunk/scd/scdaemon.c Log: Fixed a nasty bug in scdaemon which led to a card reset if the card was inserted during scdaemon startup and a connection was made before the ticker had a chance to run. Add some stuff for better debugging. Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2009-02-24 20:41:44 UTC (rev 4932) +++ trunk/jnlib/ChangeLog 2009-02-25 10:58:56 UTC (rev 4933) @@ -1,3 +1,9 @@ +2009-02-25 Werner Koch + + * logging.c (get_tid_callback): New. + (do_logv): Use it. + (log_set_get_tid_callback): New. + 2009-01-22 Werner Koch * t-support.c (gpg_err_code_from_errno) Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-02-24 20:41:44 UTC (rev 4932) +++ trunk/scd/ChangeLog 2009-02-25 10:58:56 UTC (rev 4933) @@ -1,3 +1,13 @@ +2009-02-25 Werner Koch + + * apdu.c (apdu_get_status): Factor all code out to ... + (apdu_private_get_status): .. new. Add arg NO_ATR_RESET. + (apdu_connect): Call new function. + + * scdaemon.c: New option --debug-log-tid. + (tid_log_callback): New. + (main): Move debug-wait code after debug stream init. + 2009-02-24 Werner Koch * ccid-driver.c (ccid_get_atr): Move debug output to .. Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2009-02-24 20:41:44 UTC (rev 4932) +++ trunk/agent/gpg-agent.c 2009-02-25 10:58:56 UTC (rev 4933) @@ -2065,7 +2065,7 @@ tattr = pth_attr_new(); pth_attr_set (tattr, PTH_ATTR_JOINABLE, 0); pth_attr_set (tattr, PTH_ATTR_STACK_SIZE, 256*1024); - pth_attr_set (tattr, PTH_ATTR_NAME, "check-owb-socket"); + pth_attr_set (tattr, PTH_ATTR_NAME, "check-own-socket"); if (!pth_spawn (tattr, check_own_socket_thread, sockname)) log_error ("error spawning check_own_socket_thread: %s\n", Modified: trunk/doc/scdaemon.texi =================================================================== --- trunk/doc/scdaemon.texi 2009-02-24 20:41:44 UTC (rev 4932) +++ trunk/doc/scdaemon.texi 2009-02-25 10:58:56 UTC (rev 4933) @@ -205,7 +205,11 @@ dump. This options enables it and also changes the working directory to @file{/tmp} when running in @option{--server} mode. + at item --debug-log-tid + at opindex debug-log-tid +This option appends a thread ID to the PID in the log output. + @item --no-detach @opindex no-detach Don't detach the process from the console. This is mainly useful for Modified: trunk/jnlib/logging.c =================================================================== --- trunk/jnlib/logging.c 2009-02-24 20:41:44 UTC (rev 4932) +++ trunk/jnlib/logging.c 2009-02-25 10:58:56 UTC (rev 4933) @@ -1,6 +1,6 @@ /* logging.c - Useful logging functions * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004, 2005, 2006 Free Software Foundation, Inc. + * 2004, 2005, 2006, 2009 Free Software Foundation, Inc. * * This file is part of JNLIB. * @@ -61,6 +61,7 @@ static int with_time; static int with_prefix; static int with_pid; +static unsigned long (*get_tid_callback)(void); static int running_detached; static int force_prefixes; @@ -366,6 +367,13 @@ void +log_set_get_tid_callback (unsigned long (*cb)(void)) +{ + get_tid_callback = cb; +} + + +void log_set_prefix (const char *text, unsigned int flags) { if (text) @@ -460,7 +468,13 @@ if (with_prefix || force_prefixes) fputs (prefix_buffer, logstream); if (with_pid || force_prefixes) - fprintf (logstream, "[%u]", (unsigned int)getpid ()); + { + if (get_tid_callback) + fprintf (logstream, "[%u.%lx]", + (unsigned int)getpid (), get_tid_callback ()); + else + fprintf (logstream, "[%u]", (unsigned int)getpid ()); + } 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-02-24 20:41:44 UTC (rev 4932) +++ trunk/jnlib/logging.h 2009-02-25 10:58:56 UTC (rev 4933) @@ -33,6 +33,7 @@ void log_inc_errorcount (void); void log_set_file( const char *name ); void log_set_fd (int fd); +void log_set_get_tid_callback (unsigned long (*cb)(void)); 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/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2009-02-24 20:41:44 UTC (rev 4932) +++ trunk/scd/apdu.c 2009-02-25 10:58:56 UTC (rev 4933) @@ -1,5 +1,5 @@ /* apdu.c - ISO 7816 APDU functions and low level I/O - * Copyright (C) 2003, 2004, 2008 Free Software Foundation, Inc. + * Copyright (C) 2003, 2004, 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -295,6 +295,9 @@ /* 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); @@ -2565,9 +2568,18 @@ } else sw = 0; + + /* We need to call apdu_get_status_internal, so that the last-status + machinery gets setup properly even if a card is inserted while + scdaemon is fired up and apdu_get_status has not yet been called. + Without that we would force a reset of the card with the next + call to apdu_get_status. */ + apdu_get_status_internal (slot, 1, 1, NULL, NULL); + return sw; } + int apdu_disconnect (int slot) { @@ -2706,9 +2718,9 @@ of card insertions. This value may be used to detect a card change. */ -int -apdu_get_status (int slot, int hang, - unsigned int *status, unsigned int *changed) +static int +apdu_get_status_internal (int slot, int hang, int no_atr_reset, + unsigned int *status, unsigned int *changed) { int sw; unsigned int s; @@ -2736,8 +2748,9 @@ { reader_table[slot].change_counter++; /* Make sure that the ATR is invalid so that a reset will be - triggered by activate. */ - reader_table[slot].atrlen = 0; + triggered by apdu_activate. */ + if (!no_atr_reset) + reader_table[slot].atrlen = 0; } reader_table[slot].any_status = 1; reader_table[slot].last_status = s; @@ -2750,6 +2763,15 @@ } +/* See above for a description. */ +int +apdu_get_status (int slot, int hang, + unsigned int *status, unsigned int *changed) +{ + return apdu_get_status_internal (slot, hang, 0, status, changed); +} + + /* Check whether the reader supports the ISO command code COMMAND on the keypad. Return 0 on success. For a description of the pin parameters, see ccid-driver.c */ Modified: trunk/scd/ccid-driver.c =================================================================== --- trunk/scd/ccid-driver.c 2009-02-24 20:41:44 UTC (rev 4932) +++ trunk/scd/ccid-driver.c 2009-02-25 10:58:56 UTC (rev 4933) @@ -357,7 +357,7 @@ DEBUGOUT_CONT_1 (" %02X", data[off]); any = 1; } - if (any && !(off % 16)) + if (any && (off % 16)) DEBUGOUT_LF (); } Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2009-02-24 20:41:44 UTC (rev 4932) +++ trunk/scd/scdaemon.c 2009-02-25 10:58:56 UTC (rev 4933) @@ -1,6 +1,6 @@ /* scdaemon.c - The GnuPG Smartcard Daemon * Copyright (C) 2001, 2002, 2004, 2005, - * 2007, 2008 Free Software Foundation, Inc. + * 2007, 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -69,6 +69,7 @@ oDebugWait, oDebugAllowCoreDump, oDebugCCIDDriver, + oDebugLogTid, oNoGreeting, oNoOptions, oHomedir, @@ -117,6 +118,7 @@ ARGPARSE_s_n (oDebugAllowCoreDump, "debug-allow-core-dump", "@"), ARGPARSE_s_n (oDebugCCIDDriver, "debug-ccid-driver", "@"), ARGPARSE_s_n (oDebugDisableTicker, "debug-disable-ticker", "@"), + ARGPARSE_s_n (oDebugLogTid, "debug-log-tid", "@"), ARGPARSE_s_n (oNoDetach, "no-detach", N_("do not detach from the console")), ARGPARSE_s_s (oLogFile, "log-file", N_("|FILE|write a log to FILE")), ARGPARSE_s_s (oReaderPort, "reader-port", @@ -263,9 +265,20 @@ } +static unsigned long +tid_log_callback (void) +{ +#ifdef PTH_HAVE_PTH_THREAD_ID + return pth_thread_id (); +#else + return (unsigned long)pth_self (); +#endif +} + + /* Setup the debugging. With a LEVEL of NULL only the active debug flags are propagated to the subsystems. With LEVEL set, a specific set of debug flags is set; thus overriding all flags already @@ -505,6 +518,9 @@ #endif /*HAVE_LIBUSB*/ break; case oDebugDisableTicker: ticker_disabled = 1; break; + case oDebugLogTid: + log_set_get_tid_callback (tid_log_callback); + break; case oOptions: /* config files may not be nested (silently ignore them) */ @@ -586,14 +602,6 @@ set_debug (debug_level); - if (debug_wait && pipe_server) - { - log_debug ("waiting for debugger - my pid is %u .....\n", - (unsigned int)getpid()); - gnupg_sleep (debug_wait); - log_debug ("... okay\n"); - } - initialize_module_command (); if (gpgconf_list == 2) @@ -638,13 +646,21 @@ scd_exit (0); } - /* now start with logging to a file if this is desired */ + /* Now start with logging to a file if this is desired. */ if (logfile) { log_set_file (logfile); log_set_prefix (NULL, 1|2|4); } + if (debug_wait && pipe_server) + { + log_debug ("waiting for debugger - my pid is %u .....\n", + (unsigned int)getpid()); + gnupg_sleep (debug_wait); + log_debug ("... okay\n"); + } + if (pipe_server) { /* This is the simple pipe based server */ From cvs at cvs.gnupg.org Wed Feb 25 16:05:15 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 25 Feb 2009 16:05:15 +0100 Subject: [svn] GpgOL - r295 - in trunk: . doc po src Message-ID: Author: wk Date: 2009-02-25 16:05:15 +0100 (Wed, 25 Feb 2009) New Revision: 295 Modified: trunk/NEWS trunk/doc/gpgol.texi trunk/po/de.po trunk/src/ChangeLog trunk/src/Makefile.am trunk/src/ext-commands.cpp trunk/src/mapihelp.cpp trunk/src/mapihelp.h trunk/src/mimemaker.c trunk/src/myexchext.h Log: Save cryto settings in a draft. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-01-28 10:27:50 UTC (rev 294) +++ trunk/src/ChangeLog 2009-02-25 15:05:15 UTC (rev 295) @@ -1,3 +1,11 @@ +2009-02-25 Werner Koch + + * mapihelp.cpp (get_gpgoldraftinfo_tag): New. + (mapi_get_gpgol_draft_info, mapi_set_gpgol_draft_info): New. + * ext-commands.cpp (DoCommand): Save encryption selection. + (InstallCommands): Get encryption selection from the draft info. + * mimemaker.c (finalize_message): Delete the property. + 2009-01-28 Werner Koch * mimeparser.c (t2body): Take care of x-pkcs7-mime as used by Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-01-28 10:27:50 UTC (rev 294) +++ trunk/NEWS 2009-02-25 15:05:15 UTC (rev 295) @@ -1,3 +1,9 @@ +Noteworthy changes for version 0.10.19 +=================================================== + + * Save the crypto settings in a message draft. + + Noteworthy changes for version 0.10.18 (2009-01-28) =================================================== Modified: trunk/doc/gpgol.texi =================================================================== --- trunk/doc/gpgol.texi 2009-01-28 10:27:50 UTC (rev 294) +++ trunk/doc/gpgol.texi 2009-02-25 15:05:15 UTC (rev 295) @@ -253,6 +253,11 @@ the orginal message. The content are lines of colon delimited fields. The specification has not yet been finished. + at item GpgOL Draft Info +This is a property of type STRING8 used to preserve crypto settings in a +draft message. For details see the function + at code{mapi_set_gpgol_draft_info}. + @end table Modified: trunk/po/de.po [not shown] Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2009-01-28 10:27:50 UTC (rev 294) +++ trunk/src/Makefile.am 2009-02-25 15:05:15 UTC (rev 295) @@ -14,6 +14,7 @@ unused_sources = item-events.cpp bin_PROGRAMS = gpgol +#treeview EXTRA_DIST = versioninfo.rc.in mapi32.def $(unused_sources) Outlook.gpl \ logo.bmp decrypt.bmp encrypt.bmp sign.bmp key_mana.bmp \ proto-auto.bmp proto-pgpmime.bmp proto-smime.bmp \ @@ -65,6 +66,8 @@ w32-gettext.c w32-gettext.h +#treeview_SOURCES = treeview.c + # W32API 3.2 comes with an unusable libmapi32.a. We build our own # version. Note the omission of -k (--kill-at) from the DLLTOOL # command line. We also create our own virtual copies to the _static_ Modified: trunk/src/ext-commands.cpp =================================================================== --- trunk/src/ext-commands.cpp 2009-01-28 10:27:50 UTC (rev 294) +++ trunk/src/ext-commands.cpp 2009-02-25 15:05:15 UTC (rev 295) @@ -387,6 +387,8 @@ DISPPARAMS dispparams; VARIANT aVariant; int force_encrypt = 0; + char *draft_info = NULL; + (void)hMenu; @@ -494,6 +496,12 @@ xfree (key); } + /* Because we have the message open, we use it to get the draft + info property. */ + if (message) + draft_info = mapi_get_gpgol_draft_info (message); + + ul_release (message, __func__, __LINE__); ul_release (mdb, __func__, __LINE__); } @@ -591,13 +599,30 @@ "Sign", IDB_SIGN, m_nCmdSign, NULL, 0, 0); - - m_pExchExt->m_protoSelection = opt.default_protocol; + if (draft_info && strlen (draft_info) >= 3 && draft_info[2] == 'A') + m_pExchExt->m_protoSelection = PROTOCOL_UNKNOWN; + else if (draft_info && strlen (draft_info) >= 3 && draft_info[2] == 'P') + m_pExchExt->m_protoSelection = PROTOCOL_OPENPGP; + else if (draft_info && strlen (draft_info) >= 3 && draft_info[2] == 'X') + m_pExchExt->m_protoSelection = PROTOCOL_SMIME; + else + m_pExchExt->m_protoSelection = opt.default_protocol; update_protocol_menu (eecb); - m_pExchExt->m_gpgEncrypt = opt.encrypt_default; + if (draft_info && draft_info[0] == 'E') + m_pExchExt->m_gpgEncrypt = true; + else if (draft_info && draft_info[0] == 'e') + m_pExchExt->m_gpgEncrypt = false; + else + m_pExchExt->m_gpgEncrypt = opt.encrypt_default; - m_pExchExt->m_gpgSign = opt.sign_default; + if (draft_info && draft_info[0] && draft_info[1] == 'S') + m_pExchExt->m_gpgSign = true; + else if (draft_info && draft_info[0] && draft_info[1] == 's') + m_pExchExt->m_gpgSign = false; + else + m_pExchExt->m_gpgSign = opt.sign_default; + if (force_encrypt) m_pExchExt->m_gpgEncrypt = true; check_menu (eecb, m_nCmdEncrypt, m_pExchExt->m_gpgEncrypt); @@ -615,6 +640,9 @@ _("Open the certificate manager"), IDB_KEY_MANAGER, m_nCmdKeyManager, NULL, 0, 0); } + + xfree (draft_info); + return S_FALSE; } @@ -868,6 +896,32 @@ ul_release (message, __func__, __LINE__); ul_release (mdb, __func__, __LINE__); } + else if (nCommandID == EECMDID_SaveMessage + && m_lContext == EECONTEXT_SENDNOTEMESSAGE) + { + char buf[4]; + + log_debug ("%s:%s: command SaveMessage called\n", SRCNAME, __func__); + buf[0] = m_pExchExt->m_gpgEncrypt? 'E':'e'; + buf[1] = m_pExchExt->m_gpgSign? 'S':'s'; + switch (m_pExchExt->m_protoSelection) + { + case PROTOCOL_UNKNOWN: buf[2] = 'A'; break; + case PROTOCOL_OPENPGP: buf[2] = 'P'; break; + case PROTOCOL_SMIME: buf[2] = 'X'; break; + default: buf[2] = '-'; break; + } + buf[3] = 0; + + hr = eecb->GetObject (&mdb, (LPMAPIPROP *)&message); + if (SUCCEEDED (hr)) + mapi_set_gpgol_draft_info (message, buf); + else + log_debug ("%s:%s: getObject failed: hr=%#lx\n",SRCNAME, __func__, hr); + ul_release (message, __func__, __LINE__); + ul_release (mdb, __func__, __LINE__); + return S_FALSE; /* Pass on to next handler. */ + } else { if (debug_commands) Modified: trunk/src/mapihelp.cpp =================================================================== --- trunk/src/mapihelp.cpp 2009-01-28 10:27:50 UTC (rev 294) +++ trunk/src/mapihelp.cpp 2009-02-25 15:05:15 UTC (rev 295) @@ -223,6 +223,17 @@ } +/* Return the property tag for GpgOL Draft Info. */ +int +get_gpgoldraftinfo_tag (LPMESSAGE message, ULONG *r_tag) +{ + if (!(*r_tag = create_gpgol_tag (message, L"GpgOL Draft Info", __func__))) + return -1; + *r_tag |= PT_STRING8; + return 0; +} + + /* Return the tag of the Internet Charset Body property which seems to hold the PR_BODY as received and thus before charset conversion. */ @@ -2490,6 +2501,81 @@ } + +/* Return GpgOL's draft info string as an allocated string. If no + draft info is available, NULL is returned. */ +char * +mapi_get_gpgol_draft_info (LPMESSAGE msg) +{ + HRESULT hr; + LPSPropValue propval = NULL; + ULONG tag; + char *retstr; + + if (get_gpgoldraftinfo_tag (msg, &tag) ) + return NULL; + hr = HrGetOneProp ((LPMAPIPROP)msg, tag, &propval); + if (FAILED (hr)) + return NULL; + if (PROP_TYPE (propval->ulPropTag) == PT_STRING8) + retstr = xstrdup (propval->Value.lpszA); + else + retstr = NULL; + + MAPIFreeBuffer (propval); + return retstr; +} + + +/* Set GpgOL's draft info string to STRING. This string is defined as: + + Character 1: 'E' = encrypt selected, + 'e' = encrypt not selected. + '-' = don't care + Character 2: 'S' = sign selected, + 's' = sign not selected. + '-' = don't care + Character 3: 'A' = Auto protocol + 'P' = OpenPGP protocol + 'X' = S/MIME protocol + '-' = don't care + + If string is NULL, the property will get deleted. + + Note that this function does not call SaveChanges. */ +int +mapi_set_gpgol_draft_info (LPMESSAGE message, const char *string) +{ + HRESULT hr; + SPropValue prop; + SPropTagArray proparray; + + if (get_gpgoldraftinfo_tag (message, &prop.ulPropTag) ) + return -1; + if (string) + { + prop.Value.lpszA = xstrdup (string); + hr = HrSetOneProp (message, &prop); + xfree (prop.Value.lpszA); + } + else + { + proparray.cValues = 1; + proparray.aulPropTag[0] = prop.ulPropTag; + hr = message->DeleteProps (&proparray, NULL); + } + if (hr) + { + log_error ("%s:%s: can't %s %s property: hr=%#lx\n", + SRCNAME, __func__, string?"set":"delete", + "GpgOL Draft Info", hr); + return -1; + } + + return 0; +} + + /* Return the MIME info as an allocated string. Will never return NULL. */ char * Modified: trunk/src/mapihelp.h =================================================================== --- trunk/src/mapihelp.h 2009-01-28 10:27:50 UTC (rev 294) +++ trunk/src/mapihelp.h 2009-02-25 15:05:15 UTC (rev 295) @@ -145,6 +145,10 @@ char *mapi_get_gpgol_charset (LPMESSAGE obj); int mapi_set_gpgol_charset (LPMESSAGE obj, const char *charset); +char *mapi_get_gpgol_draft_info (LPMESSAGE msg); +int mapi_set_gpgol_draft_info (LPMESSAGE message, const char *string); + + int mapi_set_attach_hidden (LPATTACH attach); int mapi_test_attach_hidden (LPATTACH attach); Modified: trunk/src/mimemaker.c =================================================================== --- trunk/src/mimemaker.c 2009-01-28 10:27:50 UTC (rev 294) +++ trunk/src/mimemaker.c 2009-02-25 15:05:15 UTC (rev 295) @@ -1075,6 +1075,10 @@ if (delete_all_attachments (message, att_table)) return -1; + /* Remove the draft info so that we don't leak the information on + whether the message has been signed etc. */ + mapi_set_gpgol_draft_info (message, NULL); + return mapi_save_changes (message, KEEP_OPEN_READWRITE|FORCE_SAVE); } Modified: trunk/src/myexchext.h =================================================================== --- trunk/src/myexchext.h 2009-01-28 10:27:50 UTC (rev 294) +++ trunk/src/myexchext.h 2009-02-25 15:05:15 UTC (rev 295) @@ -69,6 +69,7 @@ /* Command IDs. */ +#define EECMDID_SaveMessage 13 /* (name guessed) */ #define EECMDID_PrevMessage 87 /* (name guessed) */ #define EECMDID_NextMessage 88 /* (name guessed) */ #define EECMDID_Format 110 From cvs at cvs.gnupg.org Thu Feb 26 10:47:02 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 26 Feb 2009 10:47:02 +0100 Subject: [svn] GpgOL - r296 - trunk/src Message-ID: Author: wk Date: 2009-02-26 10:47:01 +0100 (Thu, 26 Feb 2009) New Revision: 296 Modified: 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: Send SENDER command also for encryption. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-02-25 15:05:15 UTC (rev 295) +++ trunk/src/ChangeLog 2009-02-26 09:47:01 UTC (rev 296) @@ -1,3 +1,11 @@ +2009-02-26 Werner Koch + + * engine.c (engine_encrypt_prepare): Add arg SENDER. + * engine-assuan.c (op_assuan_encrypt): Ditto. + * mimemaker.c (do_mime_sign): Free sender string. + (mime_encrypt): Pass the sender address to the engine. + (mime_sign_encrypt): Ditto. + 2009-02-25 Werner Koch * mapihelp.cpp (get_gpgoldraftinfo_tag): New. Modified: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c 2009-02-25 15:05:15 UTC (rev 295) +++ trunk/src/engine-assuan.c 2009-02-26 09:47:01 UTC (rev 296) @@ -1563,12 +1563,15 @@ this function returns success, the data objects may only be destroyed after an engine_wait or engine_cancel. On success the function returns a poiunter to the encryption state and thus - requires that op_assuan_encrypt_bottom will be run later. */ + requires that op_assuan_encrypt_bottom will be run later. + SENDER is the sender's mailbox or NULL; this information may be + used by the UI-server for role selection. */ int op_assuan_encrypt (protocol_t protocol, gpgme_data_t indata, gpgme_data_t outdata, engine_filter_t filter, void *hwnd, - char **recipients, protocol_t *r_used_protocol, + const char *sender, char **recipients, + protocol_t *r_used_protocol, struct engine_assuan_encstate_s **r_encstate) { gpg_error_t err; @@ -1608,6 +1611,17 @@ if (err) goto leave; send_session_info (ctx, filter); + + /* If a sender has been supplied, tell the server about it. We + don't care about error because servers may not implement SENDER + in an encryption context. */ + if (sender && *sender) + { + snprintf (line, sizeof line, "SENDER --info -- %s", sender); + assuan_transact (ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + } + + /* Send the recipients to the server. */ for (i=0; recipients && recipients[i]; i++) { snprintf (line, sizeof line, "RECIPIENT %s", recipients[i]); Modified: trunk/src/engine-assuan.h =================================================================== --- trunk/src/engine-assuan.h 2009-02-25 15:05:15 UTC (rev 295) +++ trunk/src/engine-assuan.h 2009-02-26 09:47:01 UTC (rev 296) @@ -40,7 +40,8 @@ int op_assuan_encrypt (protocol_t protocol, gpgme_data_t indata, gpgme_data_t outdata, engine_filter_t notify_data, void *hwnd, - char **recipients, protocol_t *r_used_protocol, + const char *sender, char **recipients, + protocol_t *r_used_protocol, struct engine_assuan_encstate_s **r_encstate); int op_assuan_encrypt_bottom (struct engine_assuan_encstate_s *encstate, int cancel); Modified: trunk/src/engine.c =================================================================== --- trunk/src/engine.c 2009-02-25 15:05:15 UTC (rev 295) +++ trunk/src/engine.c 2009-02-26 09:47:01 UTC (rev 296) @@ -835,10 +835,15 @@ R_PROTOCOL. This is a two part fucntion. engine_encrypt_prepare needs to be called first followed by engine_encrypt_start. The latter command has just one argument CANCEL which can be set to - true to cancel the prepared command. */ + true to cancel the prepared command. + + 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, char **recipients, + protocol_t req_protocol, + const char *sender, char **recipients, protocol_t *r_protocol) { gpg_error_t err; @@ -848,8 +853,8 @@ if (filter->use_assuan) { err = op_assuan_encrypt (req_protocol, filter->indata, filter->outdata, - filter, hwnd, recipients, &used_protocol, - &filter->encstate); + filter, hwnd, sender, recipients, + &used_protocol, &filter->encstate); if (!err) *r_protocol = used_protocol; } Modified: trunk/src/engine.h =================================================================== --- trunk/src/engine.h 2009-02-25 15:05:15 UTC (rev 295) +++ trunk/src/engine.h 2009-02-26 09:47:01 UTC (rev 296) @@ -72,7 +72,8 @@ void engine_cancel (engine_filter_t filter); int engine_encrypt_prepare (engine_filter_t filter, HWND hwnd, - protocol_t req_protocol, char **recipients, + protocol_t req_protocol, + const char *sender, char **recipients, protocol_t *r_protocol); int engine_encrypt_start (engine_filter_t filter, int cancel); int engine_sign_start (engine_filter_t filter, HWND hwnd, protocol_t protocol, Modified: trunk/src/mimemaker.c =================================================================== --- trunk/src/mimemaker.c 2009-02-25 15:05:15 UTC (rev 295) +++ trunk/src/mimemaker.c 2009-02-26 09:47:01 UTC (rev 296) @@ -1170,6 +1170,7 @@ char top_header[BOUNDARYSIZE+200]; engine_filter_t filter = NULL; struct databuf_s sigbuffer; + char *sender = NULL; *r_att_table = NULL; @@ -1219,8 +1220,8 @@ } } - if (engine_sign_start (filter, hwnd, protocol, - mapi_get_sender (message), &protocol)) + sender = mapi_get_sender (message); + if (engine_sign_start (filter, hwnd, protocol, sender, &protocol)) goto failure; protocol = check_protocol (protocol); @@ -1386,6 +1387,7 @@ else *r_att_table = att_table; xfree (sigbuffer.buf); + xfree (sender); return result; } @@ -1602,6 +1604,7 @@ char *body = NULL; int n_att_usable; engine_filter_t filter = NULL; + char *sender = NULL; memset (sink, 0, sizeof *sink); memset (encsink, 0, sizeof *encsink); @@ -1644,7 +1647,9 @@ xfree (tmp); } - if (engine_encrypt_prepare (filter, hwnd, protocol, recipients, &protocol)) + sender = mapi_get_sender (message); + if (engine_encrypt_prepare (filter, hwnd, protocol, + sender, recipients, &protocol)) goto failure; if (engine_encrypt_start (filter, 0)) goto failure; @@ -1723,6 +1728,7 @@ cancel_mapi_attachment (&attach, sink); xfree (body); mapi_release_attach_table (att_table); + xfree (sender); return result; } @@ -1749,6 +1755,7 @@ mapi_attach_item_t *att_table = NULL; engine_filter_t filter = NULL; unsigned int session_number; + char *sender = NULL; memset (sink, 0, sizeof *sink); memset (encsink, 0, sizeof *encsink); @@ -1820,8 +1827,9 @@ xfree (tmp); } + sender = mapi_get_sender (message); if ((rc=engine_encrypt_prepare (filter, hwnd, - protocol, recipients, &protocol))) + protocol, sender, recipients, &protocol))) goto failure; protocol = check_protocol (protocol); @@ -1934,5 +1942,6 @@ if (tmpstream) IStream_Release (tmpstream); mapi_release_attach_table (att_table); + xfree (sender); return result; } From cvs at cvs.gnupg.org Thu Feb 26 11:06:18 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 26 Feb 2009 11:06:18 +0100 Subject: [svn] GpgOL - r297 - trunk/src Message-ID: Author: wk Date: 2009-02-26 11:06:18 +0100 (Thu, 26 Feb 2009) New Revision: 297 Modified: trunk/src/ChangeLog trunk/src/ext-commands.cpp Log: No decrypt menu item for non GpgOL messages. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-02-26 09:47:01 UTC (rev 296) +++ trunk/src/ChangeLog 2009-02-26 10:06:18 UTC (rev 297) @@ -1,5 +1,8 @@ 2009-02-26 Werner Koch + * ext-commands.cpp (InstallCommands): Disable decrypt button for + non GpgOl messages. + * engine.c (engine_encrypt_prepare): Add arg SENDER. * engine-assuan.c (op_assuan_encrypt): Ditto. * mimemaker.c (do_mime_sign): Free sender string. Modified: trunk/src/ext-commands.cpp =================================================================== --- trunk/src/ext-commands.cpp 2009-02-26 09:47:01 UTC (rev 296) +++ trunk/src/ext-commands.cpp 2009-02-26 10:06:18 UTC (rev 297) @@ -541,11 +541,10 @@ ul_release (message, __func__, __LINE__); ul_release (mdb, __func__, __LINE__); - /* We always enable the verify button as it might be useful on - an already decrypted message. */ add_menu (eecb, pnCommandIDBase, "@", NULL, - opt.disable_gpgol? "":_("GpgOL Decrypt/Verify"), &m_nCmdCryptoState, + (opt.disable_gpgol || not_a_gpgol_message)? + "" : _("GpgOL Decrypt/Verify"), &m_nCmdCryptoState, opt.enable_debug? "GpgOL Debug-0 (display crypto info)":"", &m_nCmdDebug0, (opt.enable_debug && !opt.disable_gpgol)? From cvs at cvs.gnupg.org Thu Feb 26 17:55:47 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 26 Feb 2009 17:55:47 +0100 Subject: [svn] GpgOL - r298 - in trunk: . src Message-ID: Author: wk Date: 2009-02-26 17:55:47 +0100 (Thu, 26 Feb 2009) New Revision: 298 Modified: trunk/NEWS trunk/src/ChangeLog trunk/src/mimeparser.c Log: Chmage suffix of unnamed attachments. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-02-26 10:06:18 UTC (rev 297) +++ trunk/src/ChangeLog 2009-02-26 16:55:47 UTC (rev 298) @@ -1,5 +1,8 @@ 2009-02-26 Werner Koch + * mimeparser.c (start_attachment): Try to figure out a good file + name suffix for the FILENAME property. + * ext-commands.cpp (InstallCommands): Disable decrypt button for non GpgOl messages. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-02-26 10:06:18 UTC (rev 297) +++ trunk/NEWS 2009-02-26 16:55:47 UTC (rev 298) @@ -3,7 +3,10 @@ * Save the crypto settings in a message draft. + * Unnamed attachments are now shown with a suffix matching its MIME + type. + Noteworthy changes for version 0.10.18 (2009-01-28) =================================================== Modified: trunk/src/mimeparser.c =================================================================== --- trunk/src/mimeparser.c 2009-02-26 10:06:18 UTC (rev 297) +++ trunk/src/mimeparser.c 2009-02-26 16:55:47 UTC (rev 298) @@ -1,5 +1,5 @@ /* mimeparser.c - Parse multipart MIME message - * Copyright (C) 2005, 2007, 2008 g10 Code GmbH + * Copyright (C) 2005, 2007, 2008, 2009 g10 Code GmbH * * This file is part of GpgOL. * @@ -361,7 +361,13 @@ /* We need to insert a short filename . Without it, the _displayed_ list of attachments won't get updated although the attachment has - been created. */ + been created. If we know the content type we use an appropriate + suffix for the filename. This is useful so that if no filename + is known for the attachment (to be stored in + PR_ATTACH_LONG_FILENAME), Outlooks gets an idea about the content + of the attachment from this made up filename. This allows for + example to click on the attachment and open it with an + appropriate application. */ prop.ulPropTag = PR_ATTACH_FILENAME_A; { char buf[100]; @@ -370,7 +376,36 @@ prop.Value.lpszA = is_body == 2? "gpgol000.htm":"gpgol000.txt"; else { - snprintf (buf, 100, "gpgol%03d.dat", ctx->part_counter); + static struct { + const char *suffix; + const char *ct; + } suffix_table[] = { + { "doc", "application/msword" }, + { "eml", "message/rfc822" }, + { "htm", "text/html" }, + { "jpg", "image/jpeg" }, + { "pdf", "application/pdf" }, + { "png", "image/png" }, + { "pps", "application/vnd.ms-powerpoint" }, + { "ppt", "application/vnd.ms-powerpoint" }, + { "ps", "application/postscript" }, + { NULL, NULL } + }; + const char *suffix = "dat"; /* Default. */ + int idx; + + if (ctx->mimestruct_cur && ctx->mimestruct_cur->content_type) + { + for (idx=0; suffix_table[idx].ct; idx++) + if (!strcmp (ctx->mimestruct_cur->content_type, + suffix_table[idx].ct)) + { + suffix = suffix_table[idx].suffix; + break; + } + } + + snprintf (buf, 100, "gpgol%03d.%s", ctx->part_counter, suffix); prop.Value.lpszA = buf; } hr = HrSetOneProp ((LPMAPIPROP)newatt, &prop); From cvs at cvs.gnupg.org Fri Feb 27 12:20:27 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 27 Feb 2009 12:20:27 +0100 Subject: [svn] GpgOL - r299 - in trunk: . po Message-ID: Author: wk Date: 2009-02-27 12:20:26 +0100 (Fri, 27 Feb 2009) New Revision: 299 Modified: trunk/ChangeLog trunk/NEWS trunk/configure.ac trunk/po/de.po trunk/po/sv.po Log: Preparing a release Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-02-26 16:55:47 UTC (rev 298) +++ trunk/ChangeLog 2009-02-27 11:20:26 UTC (rev 299) @@ -1,3 +1,7 @@ +2009-02-27 Werner Koch + + Release 0.10.19. + 2009-01-28 Werner Koch Release 0.10.18. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-02-26 16:55:47 UTC (rev 298) +++ trunk/NEWS 2009-02-27 11:20:26 UTC (rev 299) @@ -1,4 +1,4 @@ -Noteworthy changes for version 0.10.19 +Noteworthy changes for version 0.10.19 (2009-02-27) =================================================== * Save the crypto settings in a message draft. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-02-26 16:55:47 UTC (rev 298) +++ trunk/configure.ac 2009-02-27 11:20:26 UTC (rev 299) @@ -16,7 +16,7 @@ # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an # "svn up" and "autogen.sh" right before creating a distribution. -m4_define([my_version], [0.10.18]) +m4_define([my_version], [0.10.19]) m4_define([my_issvn], [no]) m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ Modified: trunk/po/de.po [not shown] Modified: trunk/po/sv.po [not shown] From cvs at cvs.gnupg.org Fri Feb 27 15:37:00 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 27 Feb 2009 15:37:00 +0100 Subject: [svn] GnuPG - r4934 - in trunk: . g10 scd tools Message-ID: Author: wk Date: 2009-02-27 15:36:59 +0100 (Fri, 27 Feb 2009) New Revision: 4934 Modified: trunk/NEWS trunk/g10/ChangeLog trunk/g10/call-agent.c trunk/scd/ChangeLog trunk/scd/app-common.h trunk/scd/app.c trunk/scd/command.c trunk/tools/ChangeLog trunk/tools/gpgconf-comp.c Log: Fix a gpg2 problem with removed cards. Allow runtime conf change for scdaemon. New commands for scdaemon. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-02-25 10:58:56 UTC (rev 4933) +++ trunk/g10/ChangeLog 2009-02-27 14:36:59 UTC (rev 4934) @@ -1,3 +1,8 @@ +2009-02-27 Werner Koch + + * call-agent.c (agent_scd_pksign, agent_scd_pkdecrypt): First send + the SERIALNO command. + 2009-02-24 Werner Koch * pkglue.c (pk_verify): Return an error for improper DATA instead Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-02-25 10:58:56 UTC (rev 4933) +++ trunk/scd/ChangeLog 2009-02-27 14:36:59 UTC (rev 4934) @@ -1,3 +1,12 @@ +2009-02-27 Werner Koch + + * app.c (get_supported_applications): New. + * command.c (cmd_getinfo): New subcommand "app_list" + (cmd_killscd): New. + (register_commands): Register command KILLSCD. + (struct server_local_s): Add field STOPME. + (scd_command_handler): Act upon this. + 2009-02-25 Werner Koch * apdu.c (apdu_get_status): Factor all code out to ... Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2009-02-25 10:58:56 UTC (rev 4933) +++ trunk/tools/ChangeLog 2009-02-27 14:36:59 UTC (rev 4934) @@ -1,3 +1,10 @@ +2009-02-27 Werner Koch + + * gpgconf-comp.c (gpg_agent_runtime_change): Declare static. + (scdaemon_runtime_change): New. + (gc_backend_scdaemon): Register new function. + (gc_options_scdaemon): Make most options runtime changable. + 2009-01-20 Werner Koch * gpgconf.c (main): Print more directories. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-02-25 10:58:56 UTC (rev 4933) +++ trunk/NEWS 2009-02-27 14:36:59 UTC (rev 4934) @@ -1,10 +1,12 @@ Noteworthy changes in version 2.0.11 (unreleased) ------------------------------------------------- - * The SCDAEMON option --allow-admin is now used by default. + * Fixed a problem in SCDAEMON which caused unexpected card resets. * SCDAEMON is now aware of the Geldkarte. + * The SCDAEMON option --allow-admin is now used by default. + * The default cipher algorithm in GPGSM is now again 3DES. This is due to interoperability problems with Outlook 2003 which still can't cope with AES. Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2009-02-25 10:58:56 UTC (rev 4933) +++ trunk/g10/call-agent.c 2009-02-27 14:36:59 UTC (rev 4934) @@ -698,6 +698,15 @@ if (indatalen*2 + 50 > DIM(line)) return gpg_error (GPG_ERR_GENERAL); + /* Send the serialno command to initialize the connection. We don't + care about the data returned. If the card has already been + initialized, this is a very fast command. We request the openpgp + card because that is waht we expect. */ + rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp", + NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return rc; + sprintf (line, "SCD SETDATA "); p = line + strlen (line); for (i=0; i < indatalen ; i++, p += 2 ) @@ -754,6 +763,15 @@ if (indatalen*2 + 50 > DIM(line)) return gpg_error (GPG_ERR_GENERAL); + /* Send the serialno command to initialize the connection. We don't + care about the data returned. If the card has already been + initialized, this is a very fast command. We request the openpgp + card because that is waht we expect. */ + rc = assuan_transact (agent_ctx, "SCD SERIALNO openpgp", + NULL, NULL, NULL, NULL, NULL, NULL); + if (rc) + return rc; + sprintf (line, "SCD SETDATA "); p = line + strlen (line); for (i=0; i < indatalen ; i++, p += 2 ) Modified: trunk/scd/app-common.h =================================================================== --- trunk/scd/app-common.h 2009-02-25 10:58:56 UTC (rev 4933) +++ trunk/scd/app-common.h 2009-02-27 14:36:59 UTC (rev 4934) @@ -141,6 +141,7 @@ gpg_error_t check_application_conflict (ctrl_t ctrl, const char *name); gpg_error_t select_application (ctrl_t ctrl, int slot, const char *name, app_t *r_app); +char *get_supported_applications (void); void release_application (app_t app); gpg_error_t app_munge_serialno (app_t app); gpg_error_t app_get_serial_and_stamp (app_t app, char **serial, time_t *stamp); Modified: trunk/scd/app.c =================================================================== --- trunk/scd/app.c 2009-02-25 10:58:56 UTC (rev 4933) +++ trunk/scd/app.c 2009-02-27 14:36:59 UTC (rev 4934) @@ -22,7 +22,7 @@ #include #include #include -# include +#include #include "scdaemon.h" #include "app-common.h" @@ -373,7 +373,7 @@ } app->ref_count = 1; - log_debug ("USING application context (refcount=%u) (new)\n", app->ref_count); + lock_table[slot].app = app; *r_app = app; unlock_reader (slot); @@ -381,6 +381,37 @@ } +char * +get_supported_applications (void) +{ + const char *list[] = { + "openpgp", + "nks", + "p15", + "dinsig", + "geldkarte", + NULL + }; + int idx; + size_t nbytes; + char *buffer, *p; + + for (nbytes=1, idx=0; list[idx]; idx++) + nbytes += strlen (list[idx]) + 1 + 1; + + buffer = xtrymalloc (nbytes); + if (!buffer) + return NULL; + + for (p=buffer, idx=0; list[idx]; idx++) + if (is_app_allowed (list[idx])) + p = stpcpy (stpcpy (p, list[idx]), ":\n"); + *p = 0; + + return buffer; +} + + /* Deallocate the application. */ static void deallocate_app (app_t app) Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2009-02-25 10:58:56 UTC (rev 4933) +++ trunk/scd/command.c 2009-02-27 14:36:59 UTC (rev 4934) @@ -114,6 +114,11 @@ /* A disconnect command has been sent. */ int disconnect_allowed; + + /* If set to true we will be terminate ourself at the end of the + this session. */ + int stopme; + }; @@ -1561,6 +1566,9 @@ deny_admin - Returns OK if admin commands are not allowed or GPG_ERR_GENERAL if admin commands are allowed. + app_list - Return a list of supported applciations. One + application per line, fields delimited by colons, + first field is the name. */ static int @@ -1628,6 +1636,15 @@ } else if (!strcmp (line, "deny_admin")) rc = opt.allow_admin? gpg_error (GPG_ERR_GENERAL) : 0; + else if (!strcmp (line, "app_list")) + { + char *s = get_supported_applications (); + if (s) + rc = assuan_send_data (ctx, s, strlen (s)); + else + rc = 0; + xfree (s); + } else rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); return rc; @@ -1767,8 +1784,19 @@ } +/* KILLSCD - Commit suicide. */ +static int +cmd_killscd (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + (void)line; + ctrl->server_local->stopme = 1; + return gpg_error (GPG_ERR_EOF); +} + + /* Tell the assuan library about our commands */ static int @@ -1802,6 +1830,7 @@ { "RESTART", cmd_restart }, { "DISCONNECT", cmd_disconnect }, { "APDU", cmd_apdu }, + { "KILLSCD", cmd_killscd }, { NULL } }; int i, rc; @@ -1919,6 +1948,9 @@ /* Release the Assuan context. */ assuan_deinit_server (ctx); + if (ctrl->server_local->stopme) + scd_exit (0); + /* If there are no more sessions return true. */ return !session_list; } Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2009-02-25 10:58:56 UTC (rev 4933) +++ trunk/tools/gpgconf-comp.c 2009-02-27 14:36:59 UTC (rev 4934) @@ -104,7 +104,8 @@ /* Forward declaration. */ -void gpg_agent_runtime_change (void); +static void gpg_agent_runtime_change (void); +static void scdaemon_runtime_change (void); /* Backend configuration. Backends are used to decide how the default and current value of an option can be determined, and how the @@ -181,7 +182,7 @@ { "GPG Agent", "gpg-agent", GNUPG_MODULE_NAME_AGENT, gpg_agent_runtime_change, "gpgconf-gpg-agent.conf" }, { "SCDaemon", "scdaemon", GNUPG_MODULE_NAME_SCDAEMON, - NULL, "gpgconf-scdaemon.conf" }, + scdaemon_runtime_change, "gpgconf-scdaemon.conf" }, { "DirMngr", "dirmngr", GNUPG_MODULE_NAME_DIRMNGR, NULL, "gpgconf-dirmngr.conf" }, { "DirMngr LDAP Server List", NULL, 0, @@ -574,7 +575,7 @@ { "Monitor", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, "gnupg", N_("Options controlling the diagnostic output") }, - { "verbose", GC_OPT_FLAG_LIST, GC_LEVEL_BASIC, + { "verbose", GC_OPT_FLAG_LIST|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "verbose", GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, { "quiet", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, @@ -590,39 +591,39 @@ { "options", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, "gnupg", "|FILE|read options from FILE", GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON }, - { "reader-port", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + { "reader-port", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "|N|connect to reader at port N", GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "ctapi-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + { "ctapi-driver", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, "gnupg", "|NAME|use NAME as ct-API driver", GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "pcsc-driver", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + { "pcsc-driver", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, "gnupg", "|NAME|use NAME as PC/SC driver", GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "disable-ccid", GC_OPT_FLAG_NONE, GC_LEVEL_EXPERT, + { "disable-ccid", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_EXPERT, "gnupg", "do not use the internal CCID driver", GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - { "disable-keypad", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + { "disable-keypad", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "do not use a reader's keypad", GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, - { "card-timeout", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + { "card-timeout", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "|N|disconnect the card after N seconds of inactivity", GC_ARG_TYPE_UINT32, GC_BACKEND_SCDAEMON }, { "Debug", GC_OPT_FLAG_GROUP, GC_LEVEL_ADVANCED, "gnupg", N_("Options useful for debugging") }, - { "debug-level", GC_OPT_FLAG_ARG_OPT, GC_LEVEL_ADVANCED, + { "debug-level", GC_OPT_FLAG_ARG_OPT|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, "gnupg", "|LEVEL|set the debugging level to LEVEL", GC_ARG_TYPE_STRING, GC_BACKEND_SCDAEMON }, - { "log-file", GC_OPT_FLAG_NONE, GC_LEVEL_ADVANCED, + { "log-file", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_ADVANCED, "gnupg", N_("|FILE|write a log to FILE"), GC_ARG_TYPE_FILENAME, GC_BACKEND_SCDAEMON }, { "Security", GC_OPT_FLAG_GROUP, GC_LEVEL_BASIC, "gnupg", N_("Options controlling the security") }, - { "deny-admin", GC_OPT_FLAG_NONE, GC_LEVEL_BASIC, + { "deny-admin", GC_OPT_FLAG_NONE|GC_OPT_FLAG_RUNTIME, GC_LEVEL_BASIC, "gnupg", "deny the use of admin card commands", GC_ARG_TYPE_NONE, GC_BACKEND_SCDAEMON }, @@ -994,7 +995,7 @@ /* Engine specific support. */ -void +static void gpg_agent_runtime_change (void) { #ifndef HAVE_W32_SYSTEM @@ -1045,6 +1046,27 @@ } +static void +scdaemon_runtime_change (void) +{ + gpg_error_t err; + const char *pgmname; + const char *argv[2]; + pid_t pid; + + pgmname = gnupg_module_name (GNUPG_MODULE_NAME_CONNECT_AGENT); + argv[0] = "scd killscd"; + argv[1] = NULL; + + err = gnupg_spawn_process_fd (pgmname, argv, -1, -1, -1, &pid); + if (!err) + err = gnupg_wait_process (pgmname, pid, NULL); + if (err) + gc_error (0, 0, "error running `%s%s': %s", + pgmname, " scd killscd", gpg_strerror (err)); +} + + /* More or less Robust version of dgettext. It has the side effect of switching the codeset to utf-8 because this is what we want to