From cvs at cvs.gnupg.org Wed Apr 1 12:51:55 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 01 Apr 2009 12:51:55 +0200 Subject: [svn] GnuPG - r4972 - in trunk: . agent common g10 scd sm tools Message-ID: Author: wk Date: 2009-04-01 12:51:53 +0200 (Wed, 01 Apr 2009) New Revision: 4972 Added: trunk/common/get-passphrase.c trunk/common/get-passphrase.h Modified: trunk/NEWS trunk/agent/ChangeLog trunk/agent/Makefile.am trunk/agent/call-pinentry.c trunk/agent/call-scd.c trunk/agent/command.c trunk/agent/protect-tool.c trunk/common/ChangeLog trunk/common/Makefile.am trunk/common/exechelp.c trunk/common/membuf.c trunk/common/percent.c trunk/common/sysutils.c trunk/common/t-percent.c trunk/common/util.h trunk/g10/ChangeLog trunk/g10/call-agent.c trunk/g10/main.h trunk/g10/misc.c trunk/g10/passphrase.c trunk/scd/ChangeLog trunk/scd/command.c trunk/sm/ChangeLog trunk/sm/export.c trunk/sm/import.c trunk/tools/gpg-connect-agent.c trunk/tools/gpgconf-comp.c Log: Import/export of pkcs#12 now uses the gpg-agent directly. Removed duplicated code (percent unescaping). [The diff below has been truncated] Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/agent/ChangeLog 2009-04-01 10:51:53 UTC (rev 4972) @@ -1,3 +1,21 @@ +2009-04-01 Werner Koch + + * protect-tool.c (pe_opt): New. + (opts): Add option --agent-program. Use ARGPARSE macros. + (get_new_passphrase): Remove. + (get_passphrase): Use gpg-agent directly. Remove arg OPT_CHECK and + change all callers. + * Makefile.am (gpg_protect_tool_LDADD): Replace pwquery_libs by + LIBASSUAN_LIBS. + (gpg_protect_tool_CFLAGS): New. + + * command.c (percent_plus_unescape): Remove. + (cmd_putval): Use percent_plus_unescape_inplace. + * call-scd.c (unescape_status_string): Remove. + (card_getattr_cb): Use percent_plus_unescape. + * protect-tool.c (main): Use percent_plus_unescape from common/. + (percent_plus_unescape, percent_plus_unescape_string): Remove. + 2009-03-27 Werner Koch * learncard.c (agent_handle_learn): Add new certtype 111. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/common/ChangeLog 2009-04-01 10:51:53 UTC (rev 4972) @@ -1,3 +1,22 @@ +2009-04-01 Werner Koch + + * exechelp.c (gnupg_spawn_process): Implement new flag bit 6. + * sysutils.c (gnupg_allow_set_foregound_window): Allow the use of + ASFW_ANY. + + * membuf.c (put_membuf, get_membuf): Wipe memory on out of core. + +2009-03-31 Werner Koch + + * percent.c (percent_unescape, percent_plus_unescape): New. + (percent_plus_unescape_inplace, percent_unescape_inplace): New. + (do_plus_or_plain_unescape, count_unescape, do_unescape): New. + (do_unescape_inplace): New. + * t-percent.c (test_percent_plus_escape): Test percent_plus_unescape. + + * get-passphrase.c, get-passphrase.h: New. + * Makefile.am (without_pth_sources): New. + 2009-03-18 Werner Koch * exechelp.c: Include sys/resource.h and sys/stat.h. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/g10/ChangeLog 2009-04-01 10:51:53 UTC (rev 4972) @@ -1,3 +1,11 @@ +2009-03-31 Werner Koch + + * passphrase.c (ask_passphrase): Use percent_plus_unescape. + * misc.c (unescape_percent_string): Remove. + + * call-agent.c (unescape_status_string): Chnage to use + percent_plus_unescape. + 2009-03-25 Werner Koch * mainproc.c (print_pkenc_list): Use snprintf. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/scd/ChangeLog 2009-04-01 10:51:53 UTC (rev 4972) @@ -1,3 +1,8 @@ +2009-03-31 Werner Koch + + * command.c (percent_plus_unescape): Remove. + (cmd_setattr): Use percent_plus_unescape_inplace. + 2009-03-30 Werner Koch * app-nks.c (do_decipher): Make it work for TCOS 3. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/sm/ChangeLog 2009-04-01 10:51:53 UTC (rev 4972) @@ -1,3 +1,9 @@ +2009-04-01 Werner Koch + + * export.c (popen_protect_tool): Add command line option + --agent-program and pass flag bit 6. + * import.c (popen_protect_tool): Ditto. + 2009-03-26 Werner Koch * gpgsm.c (main): s/def_digest_string/forced_digest_algo/ and Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/NEWS 2009-04-01 10:51:53 UTC (rev 4972) @@ -19,7 +19,10 @@ * Support for the Telesec Netkey 3 cards. + * The gpg-protect-tool now uses gpg-agent via libassuan. Under + Windows the Pinentry will now be put into the foreground. + Noteworthy changes in version 2.0.11 (2009-03-03) ------------------------------------------------- Modified: trunk/agent/Makefile.am =================================================================== --- trunk/agent/Makefile.am 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/agent/Makefile.am 2009-04-01 10:51:53 UTC (rev 4972) @@ -74,9 +74,9 @@ protect.c \ minip12.c minip12.h -# Needs $(NETLIBS) for libsimple-pwquery.la. -gpg_protect_tool_LDADD = $(pwquery_libs) $(common_libs) \ - $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) +gpg_protect_tool_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_CFLAGS) +gpg_protect_tool_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) \ + $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) gpg_preset_passphrase_SOURCES = \ preset-passphrase.c Modified: trunk/agent/call-pinentry.c =================================================================== --- trunk/agent/call-pinentry.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/agent/call-pinentry.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -105,6 +105,7 @@ dump_mutex_state (pth_mutex_t *m) { #ifdef _W32_PTH_H + (void)m; log_printf ("unknown under W32"); #else if (!(m->mx_state & PTH_MUTEX_INITIALIZED)) Modified: trunk/agent/call-scd.c =================================================================== --- trunk/agent/call-scd.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/agent/call-scd.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -136,6 +136,7 @@ dump_mutex_state (pth_mutex_t *m) { #ifdef _W32_PTH_H + (void)m; log_printf ("unknown under W32"); #else if (!(m->mx_state & PTH_MUTEX_INITIALIZED)) @@ -562,43 +563,6 @@ -/* Return a new malloced string by unescaping the string S. Escaping - is percent escaping and '+'/space mapping. A binary Nul will - silently be replaced by a 0xFF. Function returns NULL to indicate - an out of memory status. */ -static char * -unescape_status_string (const unsigned char *s) -{ - char *buffer, *d; - - buffer = d = xtrymalloc (strlen ((const char*)s)+1); - if (!buffer) - return NULL; - while (*s) - { - if (*s == '%' && s[1] && s[2]) - { - s++; - *d = xtoi_2 (s); - if (!*d) - *d = '\xff'; - d++; - s += 2; - } - else if (*s == '+') - { - *d++ = ' '; - s++; - } - else - *d++ = *s++; - } - *d = 0; - return buffer; -} - - - static int learn_status_cb (void *opaque, const char *line) { @@ -1045,7 +1009,7 @@ if (keywordlen == parm->keywordlen && !memcmp (keyword, parm->keyword, keywordlen)) { - parm->data = unescape_status_string ((const unsigned char*)line); + parm->data = percent_plus_unescape ((const unsigned char*)line, 0xff); if (!parm->data) parm->error = errno; } Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/agent/command.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -236,42 +236,6 @@ } -/* Do the percent and plus/space unescaping in place and return the - length of the valid buffer. */ -static size_t -percent_plus_unescape (char *string) -{ - unsigned char *p = (unsigned char *)string; - size_t n = 0; - - while (*string) - { - if (*string == '%' && string[1] && string[2]) - { - string++; - *p++ = xtoi_2 (string); - n++; - string+= 2; - } - else if (*string == '+') - { - *p++ = ' '; - n++; - string++; - } - else - { - *p++ = *string++; - n++; - } - } - - return n; -} - - - - /* Parse a hex string. Return an Assuan error code or 0 on success and the length of the parsed string in LEN. */ static int @@ -1494,7 +1458,7 @@ p = strchr (value, ' '); if (p) *p = 0; - valuelen = percent_plus_unescape (value); + valuelen = percent_plus_unescape_inplace (value, 0); } } if (!key || !*key) Modified: trunk/agent/protect-tool.c =================================================================== --- trunk/agent/protect-tool.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/agent/protect-tool.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -41,13 +41,14 @@ #define JNLIB_NEED_LOG_LOGV #include "agent.h" #include "minip12.h" -#include "simple-pwquery.h" #include "i18n.h" +#include "get-passphrase.h" #include "sysutils.h" enum cmd_and_opt_values -{ aNull = 0, +{ + aNull = 0, oVerbose = 'v', oArmor = 'a', oPassphrase = 'P', @@ -72,17 +73,19 @@ oPrompt, oStatusMsg, -aTest }; + oAgentProgram +}; + struct rsa_secret_key_s - { - gcry_mpi_t n; /* public modulus */ - gcry_mpi_t e; /* public exponent */ - gcry_mpi_t d; /* exponent */ - gcry_mpi_t p; /* prime p. */ - gcry_mpi_t q; /* prime q. */ - gcry_mpi_t u; /* inverse of p mod q. */ - }; +{ + gcry_mpi_t n; /* public modulus */ + gcry_mpi_t e; /* public exponent */ + gcry_mpi_t d; /* exponent */ + gcry_mpi_t p; /* prime p. */ + gcry_mpi_t q; /* prime q. */ + gcry_mpi_t u; /* inverse of p mod q. */ +}; static const char *opt_homedir; @@ -96,41 +99,51 @@ static char *opt_prompt; static int opt_status_msg; static const char *opt_p12_charset; +static const char *opt_agent_program; -static char *get_passphrase (int promptno, int opt_check); -static char *get_new_passphrase (int promptno); +static char *get_passphrase (int promptno); static void release_passphrase (char *pw); static int store_private_key (const unsigned char *grip, const void *buffer, size_t length, int force); static ARGPARSE_OPTS opts[] = { + ARGPARSE_group (300, N_("@Commands:\n ")), + + ARGPARSE_c (oProtect, "protect", "protect a private key"), + ARGPARSE_c (oUnprotect, "unprotect", "unprotect a private key"), + ARGPARSE_c (oShadow, "shadow", "create a shadow entry for a public key"), + ARGPARSE_c (oShowShadowInfo, "show-shadow-info", "return the shadow info"), + ARGPARSE_c (oShowKeygrip, "show-keygrip", "show the \"keygrip\""), + ARGPARSE_c (oP12Import, "p12-import", + "import a pkcs#12 encoded private key"), + ARGPARSE_c (oP12Export, "p12-export", + "export a private key pkcs#12 encoded"), - { 301, NULL, 0, N_("@Options:\n ") }, + ARGPARSE_group (301, N_("@\nOptions:\n ")), - { oVerbose, "verbose", 0, "verbose" }, - { oArmor, "armor", 0, "write output in advanced format" }, - { oCanonical, "canonical", 0, "write output in canonical format" }, - { oPassphrase, "passphrase", 2, "|STRING|use passphrase STRING" }, - { oProtect, "protect", 256, "protect a private key"}, - { oUnprotect, "unprotect", 256, "unprotect a private key"}, - { oShadow, "shadow", 256, "create a shadow entry for a public key"}, - { oShowShadowInfo, "show-shadow-info", 256, "return the shadow info"}, - { oShowKeygrip, "show-keygrip", 256, "show the \"keygrip\""}, + ARGPARSE_s_n (oVerbose, "verbose", "verbose"), + ARGPARSE_s_n (oArmor, "armor", "write output in advanced format"), + ARGPARSE_s_n (oCanonical, "canonical", "write output in canonical format"), - { oP12Import, "p12-import", 256, "import a pkcs#12 encoded private key"}, - { oP12Export, "p12-export", 256, "export a private key pkcs#12 encoded"}, - { oP12Charset,"p12-charset", 2, - "|NAME|set charset for a new PKCS#12 passphrase to NAME" }, - { oHaveCert, "have-cert", 0, "certificate to export provided on STDIN"}, - { oStore, "store", 0, "store the created key in the appropriate place"}, - { oForce, "force", 0, "force overwriting"}, - { oNoFailOnExist, "no-fail-on-exist", 0, "@" }, - { oHomedir, "homedir", 2, "@" }, - { oPrompt, "prompt", 2, "|ESCSTRING|use ESCSTRING as prompt in pinentry"}, - { oStatusMsg, "enable-status-msg", 0, "@"}, + ARGPARSE_s_s (oPassphrase, "passphrase", "|STRING|use passphrase STRING"), + ARGPARSE_s_s (oP12Charset,"p12-charset", + "|NAME|set charset for a new PKCS#12 passphrase to NAME"), + ARGPARSE_s_n (oHaveCert, "have-cert", + "certificate to export provided on STDIN"), + ARGPARSE_s_n (oStore, "store", + "store the created key in the appropriate place"), + ARGPARSE_s_n (oForce, "force", + "force overwriting"), + ARGPARSE_s_n (oNoFailOnExist, "no-fail-on-exist", "@"), + ARGPARSE_s_s (oHomedir, "homedir", "@"), + ARGPARSE_s_s (oPrompt, "prompt", + "|ESCSTRING|use ESCSTRING as prompt in pinentry"), + ARGPARSE_s_n (oStatusMsg, "enable-status-msg", "@"), - {0} + ARGPARSE_s_s (oAgentProgram, "agent-program", "@"), + + ARGPARSE_end () }; static const char * @@ -158,9 +171,6 @@ } -/* Include the implementation of map_spwq_error. */ -MAP_SPWQ_ERROR_IMPL - /* static void */ /* print_mpi (const char *text, gcry_mpi_t a) */ /* { */ @@ -333,7 +343,7 @@ if (!key) return; - pw = get_passphrase (1, 0); + pw = get_passphrase (1); rc = agent_protect (key, pw, &result, &resultlen); release_passphrase (pw); xfree (key); @@ -372,7 +382,7 @@ if (!key) return; - rc = agent_unprotect (key, (pw=get_passphrase (1, 0)), + rc = agent_unprotect (key, (pw=get_passphrase (1)), protected_at, &result, &resultlen); release_passphrase (pw); xfree (key); @@ -678,7 +688,7 @@ buf_off = 0; kparms = p12_parse ((unsigned char*)buf+buf_off, buflen-buf_off, - (pw=get_passphrase (2, 0)), + (pw=get_passphrase (2)), import_p12_cert_cb, NULL); release_passphrase (pw); xfree (buf); @@ -753,12 +763,8 @@ assert (buflen); gcry_sexp_release (s_key); - - pw = get_new_passphrase (4); - if (!pw) - rc = gpg_error (GPG_ERR_CANCELED); - else - rc = agent_protect (key, pw, &result, &resultlen); + pw = get_passphrase (4); + rc = agent_protect (key, pw, &result, &resultlen); release_passphrase (pw); xfree (key); if (rc) @@ -896,7 +902,7 @@ unsigned char *tmpkey; size_t tmplen; - rc = agent_unprotect (key, (pw=get_passphrase (1, 0)), + rc = agent_unprotect (key, (pw=get_passphrase (1)), NULL, &tmpkey, &tmplen); release_passphrase (pw); if (rc) @@ -985,11 +991,8 @@ kparms[7] = sk.u; kparms[8] = NULL; - pw = get_new_passphrase (3); - if (!pw) - key = NULL; - else - key = p12_build (kparms, cert, certlen, pw, opt_p12_charset, &keylen); + pw = get_passphrase (3); + key = p12_build (kparms, cert, certlen, pw, opt_p12_charset, &keylen); release_passphrase (pw); xfree (cert); for (i=0; i < 8; i++) @@ -1005,54 +1008,6 @@ } - -/* Do the percent and plus/space unescaping in place and return the - length of the valid buffer. */ -static size_t -percent_plus_unescape (unsigned char *string) -{ - unsigned char *p = string; - size_t n = 0; - - while (*string) - { - if (*string == '%' && string[1] && string[2]) - { - string++; - *p++ = xtoi_2 (string); - n++; - string+= 2; - } - else if (*string == '+') - { - *p++ = ' '; - n++; - string++; - } - else - { - *p++ = *string++; - n++; - } - } - - return n; -} - -/* Remove percent and plus escaping and make sure that the reuslt is a - string. This is done in place. Returns STRING. */ -static char * -percent_plus_unescape_string (char *string) -{ - unsigned char *p = (unsigned char*)string; - size_t n; - - n = percent_plus_unescape (p); - p[n] = 0; - - return string; -} - int main (int argc, char **argv ) @@ -1094,6 +1049,8 @@ case oCanonical: opt_canonical=1; break; case oHomedir: opt_homedir = pargs.r.ret_str; break; + case oAgentProgram: opt_agent_program = pargs.r.ret_str; break; + case oProtect: cmd = oProtect; break; case oUnprotect: cmd = oUnprotect; break; case oShadow: cmd = oShadow; break; @@ -1111,11 +1068,11 @@ case oPrompt: opt_prompt = pargs.r.ret_str; break; case oStatusMsg: opt_status_msg = 1; break; - default : pargs.err = 2; break; + default: pargs.err = ARGPARSE_PRINT_ERROR; break; } } - if (log_get_errorcount(0)) - exit(2); + if (log_get_errorcount (0)) + exit (2); fname = "-"; if (argc == 1) @@ -1123,15 +1080,15 @@ else if (argc > 1) usage (1); - /* Tell simple-pwquery about the the standard socket name. */ - { - char *tmp = make_filename (opt_homedir, "S.gpg-agent", NULL); - simple_pw_set_socket (tmp); - xfree (tmp); - } + /* Set the information which can't be taken from envvars. */ + gnupg_prepare_get_passphrase (GPG_ERR_SOURCE_DEFAULT, + opt.verbose, + opt_homedir, + opt_agent_program, + NULL, NULL, NULL, NULL, NULL, NULL, NULL); if (opt_prompt) - opt_prompt = percent_plus_unescape_string (xstrdup (opt_prompt)); + opt_prompt = percent_plus_unescape (opt_prompt, 0); if (cmd == oProtect) read_and_protect (fname); @@ -1169,102 +1126,65 @@ 2 = for unprotecting a pkcs#12 object 3 = for protecting a new pkcs#12 object 4 = for protecting an imported pkcs#12 in our system - 5 = reenter the passphrase - When adding 100 to the values, a "does not match - try again" error - message is shown. */ static char * -get_passphrase (int promptno, int opt_check) +get_passphrase (int promptno) { char *pw; int err; const char *desc; char *orig_codeset; - int error_msgno; + int repeat = 0; if (opt_passphrase) return xstrdup (opt_passphrase); - error_msgno = promptno / 100; - promptno %= 100; - orig_codeset = i18n_switchto_utf8 (); if (promptno == 1 && opt_prompt) - desc = opt_prompt; + { + desc = opt_prompt; + } else if (promptno == 2) - desc = _("Please enter the passphrase to unprotect the " - "PKCS#12 object."); + { + desc = _("Please enter the passphrase to unprotect the " + "PKCS#12 object."); + } else if (promptno == 3) - desc = _("Please enter the passphrase to protect the " - "new PKCS#12 object."); + { + desc = _("Please enter the passphrase to protect the " + "new PKCS#12 object."); + repeat = 1; + } else if (promptno == 4) - desc = _("Please enter the passphrase to protect the " - "imported object within the GnuPG system."); - else if (promptno == 5) - desc = _("Please re-enter this passphrase"); + { + desc = _("Please enter the passphrase to protect the " + "imported object within the GnuPG system."); + repeat = 1; + } else desc = _("Please enter the passphrase or the PIN\n" "needed to complete this operation."); - pw = simple_pwquery (NULL, - error_msgno == 1? _("does not match - try again"):NULL, - _("Passphrase:"), desc, opt_check, &err); - err = map_spwq_error (err); - i18n_switchback (orig_codeset); - if (!pw) + err = gnupg_get_passphrase (NULL, NULL, _("Passphrase:"), desc, + repeat, repeat, 1, &pw); + if (err) { - if (err) + if (gpg_err_code (err) == GPG_ERR_CANCELED) + log_info (_("cancelled\n")); + else log_error (_("error while asking for the passphrase: %s\n"), gpg_strerror (err)); - else - log_info (_("cancelled\n")); agent_exit (0); } + assert (pw); return pw; } -/* Same as get_passphrase but requests it a second time and compares - it to the one entered the first time. */ -static char * -get_new_passphrase (int promptno) -{ - char *pw; - int i, secondpromptno; - - pw = get_passphrase (promptno, 1); - if (!pw) - return NULL; /* Canceled. */ - if (!*pw) - return pw; /* Empty passphrase - no need to ask for repeating it. */ - - secondpromptno = 5; - for (i=0; i < 3; i++) - { - char *pw2 = get_passphrase (secondpromptno, 0); - if (!pw2) - { - xfree (pw); - return NULL; /* Canceled. */ - } - if (!strcmp (pw, pw2)) - { - xfree (pw2); - return pw; /* Okay. */ - } - secondpromptno = 105; - xfree (pw2); - } - xfree (pw); - return NULL; /* 3 times repeated wrong - cancel. */ -} - - - static void release_passphrase (char *pw) { Modified: trunk/common/Makefile.am =================================================================== --- trunk/common/Makefile.am 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/common/Makefile.am 2009-04-01 10:51:53 UTC (rev 4972) @@ -71,9 +71,12 @@ localename.c \ helpfile.c +# Sources only useful without PTH. +without_pth_sources = \ + get-passphrase.c get-passphrase.h -libcommon_a_SOURCES = $(common_sources) +libcommon_a_SOURCES = $(common_sources) $(without_pth_sources) if USE_DNS_SRV libcommon_a_SOURCES += srv.c endif Modified: trunk/common/exechelp.c =================================================================== --- trunk/common/exechelp.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/common/exechelp.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -52,6 +52,7 @@ #include "util.h" #include "i18n.h" +#include "sysutils.h" #include "exechelp.h" /* Define to 1 do enable debugging. */ @@ -471,6 +472,10 @@ This flag is only useful under W32 systems, so that no new console is created and pops up a console window when starting the server + + Bit 6: On W32 run AllowSetForegroundWindow for the child. Due to + error problems this actually allows SetForegroundWindow for + childs of this process. Returns 0 on success or an error code. */ gpg_error_t @@ -568,6 +573,12 @@ /* " dwProcessID=%d dwThreadId=%d\n", */ /* pi.hProcess, pi.hThread, */ /* (int) pi.dwProcessId, (int) pi.dwThreadId); */ + + /* Fixme: For unknown reasons AllowSetForegroundWindow returns an + invalid argument error if we pass the the correct processID to + it. As a workaround we use -1 (ASFW_ANY). */ + if ( (flags & 64) ) + gnupg_allow_set_foregound_window ((pid_t)(-1)/*pi.dwProcessId*/); /* Process has been created suspended; resume it now. */ ResumeThread (pi.hThread); Added: trunk/common/get-passphrase.c =================================================================== --- trunk/common/get-passphrase.c (rev 0) +++ trunk/common/get-passphrase.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -0,0 +1,277 @@ +/* get-passphrase.c - Ask for a passphrase via the agent + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "util.h" +#include "i18n.h" +#include "asshelp.h" +#include "membuf.h" +#include "sysutils.h" +#include "get-passphrase.h" + +/* The context used by this process to ask for the passphrase. */ +static assuan_context_t agent_ctx; +static struct +{ + gpg_err_source_t errsource; + int verbosity; + const char *homedir; + const char *agent_program; + const char *display; + const char *ttyname; + const char *ttytype; + const char *lc_ctype; + const char *lc_messages; + const char *xauthority; + const char *pinentry_user_data; +} agentargs; + + +/* Set local variable to be used for a possible agent startup. Note + that the strings are just pointers and should not anymore be + modified by the caller. */ +void +gnupg_prepare_get_passphrase (gpg_err_source_t errsource, + int verbosity, + const char *homedir, + const char *agent_program, + const char *opt_display, + const char *opt_ttyname, + const char *opt_ttytype, + const char *opt_lc_ctype, + const char *opt_lc_messages, + const char *opt_xauthority, + const char *opt_pinentry_user_data) +{ + agentargs.errsource = errsource; + agentargs.verbosity = verbosity; + agentargs.homedir = homedir; + agentargs.agent_program = agent_program; + agentargs.display = opt_display; + agentargs.ttyname = opt_ttyname; + agentargs.ttytype = opt_ttytype; + agentargs.lc_ctype = opt_lc_ctype; + agentargs.lc_messages = opt_lc_messages; + agentargs.xauthority = opt_xauthority; + agentargs.pinentry_user_data = opt_pinentry_user_data; +} + + +/* Try to connect to the agent via socket or fork it off and work by + pipes. Handle the server's initial greeting. */ +static gpg_error_t +start_agent (void) +{ + gpg_error_t err; + + /* Fixme: This code is not thread safe, thus we don't build it with + pth. We will need a context for each thread or serialize the + access to the agent. */ + if (agent_ctx) + return 0; + + err = start_new_gpg_agent (&agent_ctx, + agentargs.errsource, + agentargs.homedir, + agentargs.agent_program, + agentargs.display, + agentargs.ttyname, + agentargs.ttytype, + agentargs.lc_ctype, + agentargs.lc_messages, + agentargs.xauthority, + agentargs.pinentry_user_data, + agentargs.verbosity, 0, NULL, NULL); + if (!err) + { + /* Tell the agent that we support Pinentry notifications. No + error checking so that it will work with older agents. */ + assuan_transact (agent_ctx, "OPTION allow-pinentry-notify", + NULL, NULL, NULL, NULL, NULL, NULL); + } + + return err; +} + + +/* This is the default inquiry callback. It merely handles the + Pinentry notification. */ +static int +default_inq_cb (void *opaque, const char *line) +{ + (void)opaque; + + if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17])) + { + gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10)); + /* We do not return errors to avoid breaking other code. */ + } + else + log_debug ("ignoring gpg-agent inquiry `%s'\n", line); + + return 0; +} + + +static int +membuf_data_cb (void *opaque, const void *buffer, size_t length) +{ + membuf_t *data = opaque; + + if (buffer) + put_membuf (data, buffer, length); + return 0; +} + + +/* Ask for a passphrase via gpg-agent. On success the caller needs to + free the string stored at R_PASSPHRASE. On error NULL will be + stored at R_PASSPHRASE and an appropriate gpg error code is + returned. With REPEAT set to 1, gpg-agent will ask the user to + repeat the just entered passphrase. CACHE_ID is a gpg-agent style + passphrase cache id or NULL. ERR_MSG is a error message to be + presented to the user (e.g. "bad passphrase - try again") or NULL. + PROMPT is the prompt string to label the entry box, it may be NULL + for a default one. DESC_MSG is a longer description to be + displayed above the entry box, if may be NULL for a default one. + If USE_SECMEM is true, the returned passphrase is retruned in + secure memory. The length of all these strings is limited; they + need to fit in their encoded form into a standard Assuan line (i.e + less then about 950 characters). All strings shall be UTF-8. */ +gpg_error_t +gnupg_get_passphrase (const char *cache_id, + const char *err_msg, + const char *prompt, + const char *desc_msg, + int repeat, + int check_quality, + int use_secmem, + char **r_passphrase) +{ + gpg_error_t err; + char line[ASSUAN_LINELENGTH]; + const char *arg1 = NULL; + char *arg2 = NULL; + char *arg3 = NULL; + char *arg4 = NULL; + membuf_t data; + + *r_passphrase = NULL; + + err = start_agent (); + if (err) + return err; + + /* Check that the gpg-agent understands the repeat option. */ + if (assuan_transact (agent_ctx, + "GETINFO cmd_has_option GET_PASSPHRASE repeat", + NULL, NULL, NULL, NULL, NULL, NULL)) + return gpg_error (GPG_ERR_NOT_SUPPORTED); + + arg1 = cache_id && *cache_id? cache_id:NULL; + if (err_msg && *err_msg) + if (!(arg2 = percent_plus_escape (err_msg))) + goto no_mem; + if (prompt && *prompt) + if (!(arg3 = percent_plus_escape (prompt))) + goto no_mem; + if (desc_msg && *desc_msg) + if (!(arg4 = percent_plus_escape (desc_msg))) + goto no_mem; + + snprintf (line, DIM(line)-1, + "GET_PASSPHRASE --data %s--repeat=%d -- %s %s %s %s", + check_quality? "--check ":"", + repeat, + arg1? arg1:"X", + arg2? arg2:"X", + arg3? arg3:"X", + arg4? arg4:"X"); + line[DIM(line)-1] = 0; + xfree (arg2); + xfree (arg3); + xfree (arg4); + + if (use_secmem) + init_membuf_secure (&data, 64); + else + init_membuf (&data, 64); + err = assuan_transact (agent_ctx, line, + membuf_data_cb, &data, + default_inq_cb, NULL, NULL, NULL); + + /* Older Pinentries return the old assuan error code for canceled + which gets translated bt libassuan to GPG_ERR_ASS_CANCELED and + not to the code for a user cancel. Fix this here. */ + if (err && gpg_err_source (err) + && gpg_err_code (err) == GPG_ERR_ASS_CANCELED) + err = gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED); + + if (err) + { + void *p; + size_t n; + + p = get_membuf (&data, &n); + if (p) + wipememory (p, n); + xfree (p); + } + else + { + put_membuf (&data, "", 1); + *r_passphrase = get_membuf (&data, NULL); + if (!*r_passphrase) + err = gpg_error_from_syserror (); + } + return err; + no_mem: + err = gpg_error_from_syserror (); + xfree (arg2); + xfree (arg3); + xfree (arg4); + return err; +} + + +/* Flush the passphrase cache with Id CACHE_ID. */ +gpg_error_t +gnupg_clear_passphrase (const char *cache_id) +{ + gpg_error_t err; + char line[ASSUAN_LINELENGTH]; + + if (!cache_id || !*cache_id) + return 0; + + err = start_agent (); + if (err) + return err; + + snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id); + line[DIM(line)-1] = 0; + return assuan_transact (agent_ctx, line, NULL, NULL, + default_inq_cb, NULL, NULL, NULL); +} Added: trunk/common/get-passphrase.h =================================================================== --- trunk/common/get-passphrase.h (rev 0) +++ trunk/common/get-passphrase.h 2009-04-01 10:51:53 UTC (rev 4972) @@ -0,0 +1,47 @@ +/* get-passphrase.h - Definitions to ask for a passphrase via the agent. + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef GNUPG_COMMON_GET_PASSPHRASE_H +#define GNUPG_COMMON_GET_PASSPHRASE_H + +void gnupg_prepare_get_passphrase (gpg_err_source_t errsource, + int verbosity, + const char *homedir, + const char *agent_program, + const char *opt_display, + const char *opt_ttyname, + const char *opt_ttytype, + const char *opt_lc_ctype, + const char *opt_lc_messages, + const char *opt_xauthority, + const char *opt_pinentry_user_data); + +gpg_error_t gnupg_get_passphrase (const char *cache_id, + const char *err_msg, + const char *prompt, + const char *desc_msg, + int repeat, + int check_quality, + int use_secmem, + char **r_passphrase); + +gpg_error_t gnupg_clear_passphrase (const char *cache_id); + + +#endif /*GNUPG_COMMON_GET_PASSPHRASE_H*/ Modified: trunk/common/membuf.c =================================================================== --- trunk/common/membuf.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/common/membuf.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -1,5 +1,5 @@ -/* membuf.c - A simple implementation of a dynamic buffer - * Copyright (C) 2001, 2003 Free Software Foundation, Inc. +/* membuf.c - A simple implementation of a dynamic buffer. + * Copyright (C) 2001, 2003, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -75,7 +75,7 @@ in case we are storing sensitive data here. The membuf API does not provide another way to cleanup after an error. */ - memset (mb->buf, 0, mb->len); + wipememory (mb->buf, mb->len); return; } mb->buf = p; @@ -99,8 +99,12 @@ if (mb->out_of_core) { - xfree (mb->buf); - mb->buf = NULL; + if (mb->buf) + { + wipememory (mb->buf, mb->len); + xfree (mb->buf); + mb->buf = NULL; + } errno = mb->out_of_core; return NULL; } Modified: trunk/common/percent.c =================================================================== --- trunk/common/percent.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/common/percent.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -1,5 +1,5 @@ /* percent.c - Percent escaping - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -21,6 +21,7 @@ #include #include #include +#include #include "util.h" @@ -74,3 +75,155 @@ return buffer; } + + +/* Do the percent and plus/space unescaping from STRING to BUFFER and + return the length of the valid buffer. Plus unescaping is only + done if WITHPLUS is true. An escaped Nul character will be + replaced by NULREPL. */ +static size_t +do_unescape (unsigned char *buffer, const unsigned char *string, + int withplus, int nulrepl) +{ + unsigned char *p = buffer; + + while (*string) + { + if (*string == '%' && string[1] && string[2]) + { + string++; + *p = xtoi_2 (string); + if (!*p) + *p = nulrepl; + string++; + } + else if (*string == '+' && withplus) + *p = ' '; + else + *p = *string; + p++; + string++; + } + + return (p - buffer); +} + + +/* Count space required after unescaping STRING. Note that this will + never be larger than strlen (STRING). */ +static size_t +count_unescape (const unsigned char *string) +{ + size_t n = 0; + + while (*string) + { + if (*string == '%' && string[1] && string[2]) + { + string++; + string++; + } + string++; + n++; + } + + return n; +} + + +/* Helper. */ +static char * +do_plus_or_plain_unescape (const char *string, int withplus, int nulrepl) +{ + size_t nbytes, n; + char *newstring; + + nbytes = count_unescape (string); + newstring = xtrymalloc (nbytes+1); + if (newstring) + { + n = do_unescape (newstring, string, withplus, nulrepl); + assert (n == nbytes); + newstring[n] = 0; + } + return newstring; +} + + +/* Create a new allocated string from STRING with all "%xx" sequences + decoded and all plus signs replaced by a space. Embedded Nul + characters are replaced by the value of NULREPL. The function + returns the new string or NULL in case of a malloc failure. */ +char * +percent_plus_unescape (const char *string, int nulrepl) +{ + return do_plus_or_plain_unescape (string, 1, nulrepl); +} + + +/* Create a new allocated string from STRING with all "%xx" sequences + decoded. Embedded Nul characters are replaced by the value of + NULREPL. The function returns the new string or NULL in case of a + malloc failure. */ +char * +percent_unescape (const char *string, int nulrepl) +{ + return do_plus_or_plain_unescape (string, 0, nulrepl); +} + + +static size_t +do_unescape_inplace (char *string, int withplus, int nulrepl) +{ + unsigned char *p, *p0; + + p = p0 = string; + while (*string) + { + if (*string == '%' && string[1] && string[2]) + { + string++; + *p = xtoi_2 (string); + if (!*p) + *p = nulrepl; + string++; + } + else if (*string == '+' && withplus) + *p = ' '; + else + *p = *string; + p++; + string++; + } + + return (p - p0); +} + + +/* Perform percent and plus unescaping in STRING and return the new + valid length of the string. Embedded Nul characters are replaced + by the value of NULREPL. A terminating Nul character is not + inserted; the caller might want to call this function this way: + + foo[percent_plus_unescape_inplace (foo, 0)] = 0; + */ +size_t +percent_plus_unescape_inplace (char *string, int nulrepl) +{ + return do_unescape_inplace (string, 1, nulrepl); +} + + +/* Perform percent unescaping in STRING and return the new valid + length of the string. Embedded Nul characters are replaced by the + value of NULREPL. A terminating Nul character is not inserted; the + caller might want to call this function this way: + + foo[percent_unescape_inplace (foo, 0)] = 0; + */ +size_t +percent_unescape_inplace (char *string, int nulrepl) +{ + return do_unescape_inplace (string, 0, nulrepl); +} + Modified: trunk/common/sysutils.c =================================================================== --- trunk/common/sysutils.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/common/sysutils.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -471,7 +471,9 @@ if (did_stdin == 2 || did_stdout == 2 || did_stderr == 2) exit (3); -#endif /* HAVE_STAT && !HAVE_W32_SYSTEM */ +#else /* !(HAVE_STAT && !HAVE_W32_SYSTEM) */ + (void)pgmname; +#endif } @@ -479,11 +481,11 @@ void gnupg_allow_set_foregound_window (pid_t pid) { - if (!pid || pid == (pid_t)(-1)) + if (!pid) log_info ("%s called with invalid pid %lu\n", "gnupg_allow_set_foregound_window", (unsigned long)pid); #ifdef HAVE_W32_SYSTEM - else if (!AllowSetForegroundWindow (pid)) + else if (!AllowSetForegroundWindow ((pid_t)pid == (pid_t)(-1)?ASFW_ANY:pid)) log_info ("AllowSetForegroundWindow(%lu) failed: %s\n", (unsigned long)pid, w32_strerror (-1)); #endif Modified: trunk/common/t-percent.c =================================================================== --- trunk/common/t-percent.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/common/t-percent.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -66,8 +66,9 @@ "%0A+ABC%09" }, { NULL, NULL } }; - char *buf; + char *buf, *buf2; int i; + size_t len; for (i=0; tbl[i].string; i++) { @@ -79,17 +80,34 @@ } if (strcmp (buf, tbl[i].expect)) fail (i); + buf2 = percent_plus_unescape (buf, 0); + if (!buf2) + { + fprintf (stderr, "out of core: %s\n", strerror (errno)); + exit (2); + } + if (strcmp (buf2, tbl[i].string)) + fail (i); + xfree (buf2); + /* Now test the inplace conversion. */ + len = percent_plus_unescape_inplace (buf, 0); + buf[len] = 0; + if (strcmp (buf, tbl[i].string)) + fail (i); xfree (buf); } } + int main (int argc, char **argv) { (void)argc; (void)argv; + /* FIXME: We escape_unescape is not tested - only + percent_plus_unescape. */ test_percent_plus_escape (); return 0; Modified: trunk/common/util.h =================================================================== --- trunk/common/util.h 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/common/util.h 2009-04-01 10:51:53 UTC (rev 4972) @@ -204,8 +204,13 @@ /*-- percent.c --*/ char *percent_plus_escape (const char *string); +char *percent_plus_unescape (const char *string, int nulrepl); +char *percent_unescape (const char *string, int nulrepl); +size_t percent_plus_unescape_inplace (char *string, int nulrepl); +size_t percent_unescape_inplace (char *string, int nulrepl); + /*-- homedir.c --*/ const char *standard_homedir (void); const char *default_homedir (void); Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/g10/call-agent.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -116,32 +116,7 @@ static char * unescape_status_string (const unsigned char *s) { - char *buffer, *d; - - buffer = d = xtrymalloc (strlen (s)+1); - if (!buffer) - return NULL; - while (*s) - { - if (*s == '%' && s[1] && s[2]) - { - s++; - *d = xtoi_2 (s); - if (!*d) - *d = '\xff'; - d++; - s += 2; - } - else if (*s == '+') - { - *d++ = ' '; - s++; - } - else - *d++ = *s++; - } - *d = 0; - return buffer; + return percent_plus_unescape (s, 0xff); } Modified: trunk/g10/main.h =================================================================== --- trunk/g10/main.h 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/g10/main.h 2009-04-01 10:51:53 UTC (rev 4972) @@ -135,7 +135,6 @@ char *argsplit(char *string); int parse_options(char *str,unsigned int *options, struct parse_options *opts,int noisy); -char *unescape_percent_string (const unsigned char *s); int has_invalid_email_chars (const char *s); int is_valid_mailbox (const char *name); const char *get_libexecdir (void); Modified: trunk/g10/misc.c =================================================================== --- trunk/g10/misc.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/g10/misc.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -1215,39 +1215,6 @@ } -/* Return a new malloced string by unescaping the string S. Escaping - is percent escaping and '+'/space mapping. A binary nul will - silently be replaced by a 0xFF. */ -char * -unescape_percent_string (const unsigned char *s) -{ - char *buffer, *d; - - buffer = d = xmalloc (strlen (s)+1); - while (*s) - { - if (*s == '%' && s[1] && s[2]) - { - s++; - *d = xtoi_2 (s); - if (!*d) - *d = '\xff'; - d++; - s += 2; - } - else if (*s == '+') - { - *d++ = ' '; - s++; - } - else - *d++ = *s++; - } - *d = 0; - return buffer; -} - - /* Check whether the string has characters not valid in an RFC-822 address. To cope with OpenPGP we ignore allow non-ascii characters so that for example umlauts are legal in an email address. An Modified: trunk/g10/passphrase.c =================================================================== --- trunk/g10/passphrase.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/g10/passphrase.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -453,8 +453,9 @@ { if (strchr (description, '%')) { - char *tmp = unescape_percent_string - ((const unsigned char*)description); + char *tmp = percent_plus_unescape (description, 0xff); + if (!tmp) + log_fatal(_("out of core\n")); tty_printf ("\n%s\n", tmp); xfree (tmp); } Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/scd/command.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -462,41 +462,6 @@ } -/* Do the percent and plus/space unescaping in place and return the - length of the valid buffer. */ -static size_t -percent_plus_unescape (unsigned char *string) -{ - unsigned char *p = string; - size_t n = 0; - - while (*string) - { - if (*string == '%' && string[1] && string[2]) - { - string++; - *p++ = xtoi_2 (string); - n++; - string+= 2; - } - else if (*string == '+') - { - *p++ = ' '; - n++; - string++; - } - else - { - *p++ = *string++; - n++; - } - } - - return n; -} - - - /* SERIALNO [APPTYPE] Return the serial number of the card using a status reponse. This @@ -1153,7 +1118,7 @@ *line++ = 0; while (spacep (line)) line++; - nbytes = percent_plus_unescape ((unsigned char*)line); + nbytes = percent_plus_unescape_inplace (line, 0); rc = app_setattr (ctrl->app_ctx, keyword, pin_cb, ctx, (const unsigned char*)line, nbytes); Modified: trunk/sm/export.c =================================================================== --- trunk/sm/export.c 2009-03-30 12:46:06 UTC (rev 4971) +++ trunk/sm/export.c 2009-04-01 10:51:53 UTC (rev 4972) @@ -574,13 +574,14 @@ const char *prompt, const char *keygrip, pid_t *pid) { - const char *argv[20]; + const char *argv[22]; int i=0; /* Make sure that the agent is running so that the protect tool is able to ask for a passphrase. This has only an effect under W32 where the agent is started on demand; sending a NOP does not harm - on other platforms. */ + on other platforms. This is not really necessary anymore because + the protect tool does this now by itself; it does not harm either.*/ gpgsm_agent_send_nop (ctrl); argv[i++] = "--homedir"; @@ -595,13 +596,18 @@ From cvs at cvs.gnupg.org Wed Apr 1 15:23:27 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 01 Apr 2009 15:23:27 +0200 Subject: [svn] GnuPG - r4973 - in trunk: . agent common g10 Message-ID: Author: wk Date: 2009-04-01 15:23:27 +0200 (Wed, 01 Apr 2009) New Revision: 4973 Modified: trunk/ChangeLog trunk/agent/findkey.c trunk/common/ChangeLog trunk/common/iobuf.c trunk/configure.ac trunk/g10/ChangeLog trunk/g10/gpg.c trunk/g10/keyring.c Log: Ported changes from 1.4. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-01 10:51:53 UTC (rev 4972) +++ trunk/ChangeLog 2009-04-01 13:23:27 UTC (rev 4973) @@ -1,3 +1,7 @@ +2009-04-01 Werner Koch + + * configure.ac: Test for fsync. + 2009-03-18 Werner Koch * configure.ac: Test for getrlimit. Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2009-04-01 10:51:53 UTC (rev 4972) +++ trunk/common/ChangeLog 2009-04-01 13:23:27 UTC (rev 4973) @@ -1,5 +1,14 @@ 2009-04-01 Werner Koch + * iobuf.c: Port David's changes from 1.4: + (fd_cache_invalidate): Pass return code from close back. + (direct_open, iobuf_ioctl): Check that eturn value. + (fd_cache_synchronize): New. + (iobuf_ioctl): Add new sub command 4 (fsync). + + * iobuf.c (fd_cache_strcmp): New. Taken from 1.4. + (fd_cache_invalidate, fd_cache_close, fd_cache_open): Use it. + * exechelp.c (gnupg_spawn_process): Implement new flag bit 6. * sysutils.c (gnupg_allow_set_foregound_window): Allow the use of ASFW_ANY. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-04-01 10:51:53 UTC (rev 4972) +++ trunk/g10/ChangeLog 2009-04-01 13:23:27 UTC (rev 4973) @@ -1,3 +1,16 @@ +2009-04-01 Werner Koch + + * gpg.c (main): Properly handle UTF8 usernames with --sign-key and + --lsign-key. From 1.4, David 2008-12-21. + +2009-03-20 David Shaw (wk) + + * keyring.c (rename_tmp_file): Force a fsync (via iobuf_ioctl) on + secret keyring files to be extra safe on filesystems that may not + sync data and metadata together (ext4). Also check return code + from the cache invalidation to make sure we're safe over NFS and + similar. + 2009-03-31 Werner Koch * passphrase.c (ask_passphrase): Use percent_plus_unescape. Modified: trunk/agent/findkey.c =================================================================== --- trunk/agent/findkey.c 2009-04-01 10:51:53 UTC (rev 4972) +++ trunk/agent/findkey.c 2009-04-01 13:23:27 UTC (rev 4973) @@ -50,7 +50,7 @@ /* Write an S-expression formatted key to our key storage. With FORCE - pased as true an existing key with the given GRIP will get + passed as true an existing key with the given GRIP will get overwritten. */ int agent_write_private_key (const unsigned char *grip, Modified: trunk/common/iobuf.c =================================================================== --- trunk/common/iobuf.c 2009-04-01 10:51:53 UTC (rev 4972) +++ trunk/common/iobuf.c 2009-04-01 13:23:27 UTC (rev 4973) @@ -1,6 +1,6 @@ /* iobuf.c - File Handling for OpenPGP. * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, - * 2007, 2008 Free Software Foundation, Inc. + * 2007, 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -48,7 +48,8 @@ test "armored_key_8192" in armor.test! */ #define IOBUF_BUFFER_SIZE 8192 -/* We don't want to use the STDIO based backend. */ +/* We don't want to use the STDIO based backend. If you change this + be aware that there is no fsync support for the stdio backend. */ #undef FILE_FILTER_USES_STDIO /*-- End configurable part. --*/ @@ -187,13 +188,32 @@ #ifndef FILE_FILTER_USES_STDIO +/* This is a replacement for strcmp. Under W32 it does not + distinguish between backslash and slash. */ +static int +fd_cache_strcmp (const char *a, const char *b) +{ +#ifdef HAVE_DOSISH_SYSTEM + for (; *a && *b; a++, b++) + { + if (*a != *b && !((*a == '/' && *b == '\\') + || (*a == '\\' && *b == '/')) ) + break; + } + return *(const unsigned char *)a - *(const unsigned char *)b; +#else + return strcmp (a, b); +#endif +} + /* * Invalidate (i.e. close) a cached iobuf */ -static void +static int fd_cache_invalidate (const char *fname) { close_cache_t cc; + int rc = 0; assert (fname); if (DBG_IOBUF) @@ -201,21 +221,55 @@ for (cc = close_cache; cc; cc = cc->next) { - if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname)) + if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname)) { if (DBG_IOBUF) log_debug (" did (%s)\n", cc->fname); #ifdef HAVE_W32_SYSTEM - CloseHandle (cc->fp); + if (!CloseHandle (cc->fp)) + rc = -1; #else - close (cc->fp); + rc = close (cc->fp); #endif cc->fp = INVALID_FP; } } + return rc; } +/* Try to sync changes to the disk. This is to avoid data loss during + a system crash in write/close/rename cycle on some file + systems. */ +static int +fd_cache_synchronize (const char *fname) +{ + int err = 0; + +#ifdef HAVE_FSYNC + close_cache_t cc; + + if (DBG_IOBUF) + log_debug ("fd_cache_synchronize (%s)\n", fname); + + for (cc=close_cache; cc; cc = cc->next ) + { + if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname)) + { + if (DBG_IOBUF) + log_debug (" did (%s)\n", cc->fname); + + err = fsync (cc->fp); + } + } +#else + (void)fname; +#endif /*HAVE_FSYNC*/ + + return err; +} + + static fp_or_fd_t direct_open (const char *fname, const char *mode) { @@ -226,19 +280,21 @@ /* Note, that we do not handle all mode combinations */ /* According to the ReactOS source it seems that open() of the - * standard MSW32 crt does open the file in share mode which is + * standard MSW32 crt does open the file in shared mode which is * something new for MS applications ;-) */ if (strchr (mode, '+')) { - fd_cache_invalidate (fname); + if (fd_cache_invalidate (fname)) + return INVALID_FP; da = GENERIC_READ | GENERIC_WRITE; cd = OPEN_EXISTING; sm = FILE_SHARE_READ | FILE_SHARE_WRITE; } else if (strchr (mode, 'w')) { - fd_cache_invalidate (fname); + if (fd_cache_invalidate (fname)) + return INVALID_FP; da = GENERIC_WRITE; cd = CREATE_ALWAYS; sm = FILE_SHARE_WRITE; @@ -259,12 +315,14 @@ /* Note, that we do not handle all mode combinations */ if (strchr (mode, '+')) { - fd_cache_invalidate (fname); + if (fd_cache_invalidate (fname)) + return INVALID_FP; oflag = O_RDWR; } else if (strchr (mode, 'w')) { - fd_cache_invalidate (fname); + if (fd_cache_invalidate (fname)) + return INVALID_FP; oflag = O_WRONLY | O_CREAT | O_TRUNC; } else @@ -318,7 +376,7 @@ /* try to reuse a slot */ for (cc = close_cache; cc; cc = cc->next) { - if (cc->fp == INVALID_FP && !strcmp (cc->fname, fname)) + if (cc->fp == INVALID_FP && !fd_cache_strcmp (cc->fname, fname)) { cc->fp = fp; if (DBG_IOBUF) @@ -347,7 +405,7 @@ assert (fname); for (cc = close_cache; cc; cc = cc->next) { - if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname)) + if (cc->fp != INVALID_FP && !fd_cache_strcmp (cc->fname, fname)) { fp_or_fd_t fp = cc->fp; cc->fp = INVALID_FP; @@ -1449,7 +1507,8 @@ if (!a && !intval && ptrval) { #ifndef FILE_FILTER_USES_STDIO - fd_cache_invalidate (ptrval); + if (fd_cache_invalidate (ptrval)) + return -1; #endif return 0; } @@ -1477,7 +1536,25 @@ } #endif } + else if (cmd == 4) + { + /* Do a fsync on the open fd and return any errors to the caller + of iobuf_ioctl. Note that we work on a file name here. */ + if (DBG_IOBUF) + log_debug ("iobuf-*.*: ioctl `%s' fsync\n", + ptrval? (const char*)ptrval:""); + if (!a && !intval && ptrval) + { +#ifndef FILE_FILTER_USES_STDIO + return fd_cache_synchronize (ptrval); +#else + return 0; +#endif + } + } + + return -1; } @@ -2310,7 +2387,6 @@ file_filter_ctx_t *b = a->filter_ov; return b->fname; } - return NULL; } Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-04-01 10:51:53 UTC (rev 4972) +++ trunk/configure.ac 2009-04-01 13:23:27 UTC (rev 4973) @@ -1062,7 +1062,7 @@ AC_CHECK_FUNCS([gettimeofday getrusage getrlimit setrlimit clock_gettime]) AC_CHECK_FUNCS([atexit raise getpagesize strftime nl_langinfo setlocale]) AC_CHECK_FUNCS([waitpid wait4 sigaction sigprocmask pipe stat getaddrinfo]) -AC_CHECK_FUNCS([ttyname rand ftello]) +AC_CHECK_FUNCS([ttyname rand ftello fsync]) AC_CHECK_TYPES([struct sigaction, sigset_t],,,[#include ]) Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2009-04-01 10:51:53 UTC (rev 4972) +++ trunk/g10/gpg.c 2009-04-01 13:23:27 UTC (rev 4973) @@ -3562,7 +3562,7 @@ append_to_strlist( &sl, "save" ); username = make_username( fname ); - keyedit_menu(fname, locusr, sl, 0, 0 ); + keyedit_menu (username, locusr, sl, 0, 0 ); xfree(username); free_strlist(sl); break; Modified: trunk/g10/keyring.c =================================================================== --- trunk/g10/keyring.c 2009-04-01 10:51:53 UTC (rev 4972) +++ trunk/g10/keyring.c 2009-04-01 13:23:27 UTC (rev 4973) @@ -1,5 +1,5 @@ /* keyring.c - keyring file handling - * Copyright (C) 2001, 2004 Free Software Foundation, Inc. + * Copyright (C) 2001, 2004, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1219,10 +1219,23 @@ rename_tmp_file (const char *bakfname, const char *tmpfname, const char *fname, int secret ) { - int rc=0; + int rc = 0; - /* invalidate close caches*/ - iobuf_ioctl (NULL, 2, 0, (char*)tmpfname ); + /* It's a secret keyring, so let's force a fsync just to be safe on + filesystems that may not sync data and metadata together + (e.g. ext4). */ + if (secret && iobuf_ioctl (NULL, 4, 0, (char*)tmpfname)) + { + rc = gpg_error_from_syserror (); + goto fail; + } + + /* Invalidate close caches. */ + if (iobuf_ioctl (NULL, 2, 0, (char*)tmpfname )) + { + rc = gpg_error_from_syserror (); + goto fail; + } iobuf_ioctl (NULL, 2, 0, (char*)bakfname ); iobuf_ioctl (NULL, 2, 0, (char*)fname ); @@ -1253,15 +1266,7 @@ log_error (_("renaming `%s' to `%s' failed: %s\n"), tmpfname, fname, strerror(errno) ); register_secured_file (fname); - if (secret) - { - log_info(_("WARNING: 2 files with confidential" - " information exists.\n")); - log_info(_("%s is the unchanged one\n"), fname ); - log_info(_("%s is the new one\n"), tmpfname ); - log_info(_("Please fix this possible security flaw\n")); - } - return rc; + goto fail; } /* Now make sure the file has the same permissions as the original */ @@ -1272,17 +1277,27 @@ statbuf.st_mode=S_IRUSR | S_IWUSR; - if(((secret && !opt.preserve_permissions) || - (stat(bakfname,&statbuf)==0)) && - (chmod(fname,statbuf.st_mode)==0)) + if (((secret && !opt.preserve_permissions) + || !stat (bakfname,&statbuf)) + && !chmod (fname,statbuf.st_mode)) ; else - log_error("WARNING: unable to restore permissions to `%s': %s", - fname,strerror(errno)); + log_error ("WARNING: unable to restore permissions to `%s': %s", + fname, strerror(errno)); } #endif return 0; + + fail: + if (secret) + { + log_info(_("WARNING: 2 files with confidential information exists.\n")); + log_info(_("%s is the unchanged one\n"), fname ); + log_info(_("%s is the new one\n"), tmpfname ); + log_info(_("Please fix this possible security flaw\n")); + } + return rc; } From cvs at cvs.gnupg.org Wed Apr 1 16:38:22 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 01 Apr 2009 16:38:22 +0200 Subject: [svn] GnuPG - r4974 - trunk/scd Message-ID: Author: wk Date: 2009-04-01 16:38:22 +0200 (Wed, 01 Apr 2009) New Revision: 4974 Modified: trunk/scd/ChangeLog trunk/scd/app-openpgp.c Log: Prepare for OpenPGP cards with extended length support. Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2009-04-01 13:23:27 UTC (rev 4973) +++ trunk/scd/ChangeLog 2009-04-01 14:38:22 UTC (rev 4974) @@ -1,3 +1,8 @@ +2009-04-01 Werner Koch + + * app-openpgp.c (do_setattr, do_writekey): Prepare for extended + length cards. + 2009-03-31 Werner Koch * command.c (percent_plus_unescape): Remove. Modified: trunk/scd/app-openpgp.c =================================================================== --- trunk/scd/app-openpgp.c 2009-04-01 13:23:27 UTC (rev 4973) +++ trunk/scd/app-openpgp.c 2009-04-01 14:38:22 UTC (rev 4974) @@ -1772,9 +1772,11 @@ will reread the data from the card and thus get synced in case of errors (e.g. data truncated by the card). */ flush_cache_item (app, table[idx].tag); - /* For command chaining we use a value of 254 for this card. */ - if (app->app_local->cardcap.cmd_chaining && valuelen > 254) - exmode = -254; + + if (app->app_local->cardcap.ext_lc_le && valuelen > 254) + exmode = 1; /* Use extended length w/o a limit. */ + else if (app->app_local->cardcap.cmd_chaining && valuelen > 254) + exmode = -254; /* Command chaining with max. 254 bytes. */ else exmode = 0; rc = iso7816_put_data (app->slot, exmode, table[idx].tag, value, valuelen); @@ -2432,7 +2434,9 @@ goto leave; /* Store the key. */ - if (app->app_local->cardcap.cmd_chaining && template_len > 254) + if (app->app_local->cardcap.ext_lc_le && template_len > 254) + exmode = 1; /* Use extended length w/o a limit. */ + else if (app->app_local->cardcap.cmd_chaining && template_len > 254) exmode = -254; else exmode = 0; From cvs at cvs.gnupg.org Thu Apr 2 05:50:50 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Thu, 02 Apr 2009 05:50:50 +0200 Subject: [svn] GnuPG - r4975 - branches/STABLE-BRANCH-1-4/keyserver Message-ID: Author: dshaw Date: 2009-04-02 05:50:50 +0200 (Thu, 02 Apr 2009) New Revision: 4975 Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c Log: * gpgkeys_hkp.c (main): Switch default port for SSLized HKP to 443 (i.e. the regular https port). Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-04-01 14:38:22 UTC (rev 4974) +++ branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-04-02 03:50:50 UTC (rev 4975) @@ -1,3 +1,8 @@ +2009-04-01 David Shaw + + * gpgkeys_hkp.c (main): Switch default port for SSLized HKP to + 443 (i.e. the regular https port). + 2009-02-03 David Shaw * gpgkeys_hkp.c (send_key, get_key, get_name, search_key, main): Modified: branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-04-01 14:38:22 UTC (rev 4974) +++ branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-04-02 03:50:50 UTC (rev 4975) @@ -633,7 +633,7 @@ if(ascii_strcasecmp(opt->scheme,"hkps")==0) { proto="https://"; - port="11372"; + port="443"; } else { From cvs at cvs.gnupg.org Thu Apr 2 09:20:36 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 02 Apr 2009 09:20:36 +0200 Subject: [svn] GnuPG - r4976 - trunk/sm Message-ID: Author: wk Date: 2009-04-02 09:20:35 +0200 (Thu, 02 Apr 2009) New Revision: 4976 Modified: trunk/sm/ChangeLog trunk/sm/keylist.c Log: Print the card's S/N in a secret key listing. Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2009-04-02 03:50:50 UTC (rev 4975) +++ trunk/sm/ChangeLog 2009-04-02 07:20:35 UTC (rev 4976) @@ -1,3 +1,7 @@ +2009-04-02 Werner Koch + + * keylist.c (list_cert_std): Print card serial number. + 2009-04-01 Werner Koch * export.c (popen_protect_tool): Add command line option Modified: trunk/sm/keylist.c =================================================================== --- trunk/sm/keylist.c 2009-04-02 03:50:50 UTC (rev 4975) +++ trunk/sm/keylist.c 2009-04-02 07:20:35 UTC (rev 4976) @@ -1039,7 +1039,6 @@ const char *oid; const unsigned char *cert_der = NULL; - (void)have_secret; es_fprintf (fp, " ID: 0x%08lX\n", gpgsm_get_short_fingerprint (cert, NULL)); @@ -1215,7 +1214,16 @@ es_fprintf (fp, " fingerprint: %s\n", dn?dn:"error"); xfree (dn); + if (have_secret) + { + char *cardsn; + p = gpgsm_get_keygrip_hexstring (cert); + if (!gpgsm_agent_keyinfo (ctrl, p, &cardsn) && cardsn) + es_fprintf (fp, " card s/n: %s\n", cardsn); + xfree (cardsn); + xfree (p); + } if (with_validation) { From cvs at cvs.gnupg.org Thu Apr 2 12:25:57 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 02 Apr 2009 12:25:57 +0200 Subject: [svn] gcry - r1393 - branches/LIBGCRYPT-1-4-BRANCH/doc Message-ID: Author: wk Date: 2009-04-02 12:25:57 +0200 (Thu, 02 Apr 2009) New Revision: 1393 Modified: branches/LIBGCRYPT-1-4-BRANCH/doc/ChangeLog branches/LIBGCRYPT-1-4-BRANCH/doc/gcrypt.texi Log: Minor doc fix. Modified: branches/LIBGCRYPT-1-4-BRANCH/doc/ChangeLog =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/doc/ChangeLog 2009-02-22 21:19:31 UTC (rev 1392) +++ branches/LIBGCRYPT-1-4-BRANCH/doc/ChangeLog 2009-04-02 10:25:57 UTC (rev 1393) @@ -1,3 +1,7 @@ +2009-04-02 Werner Koch + + * gcrypt.texi (Self-Tests): Fix name of register functions. + 2008-12-10 Werner Koch * gcrypt.texi (Cryptographic Functions): Explain the domain Modified: branches/LIBGCRYPT-1-4-BRANCH/doc/gcrypt.texi =================================================================== --- branches/LIBGCRYPT-1-4-BRANCH/doc/gcrypt.texi 2009-02-22 21:19:31 UTC (rev 1392) +++ branches/LIBGCRYPT-1-4-BRANCH/doc/gcrypt.texi 2009-04-02 10:25:57 UTC (rev 1393) @@ -5388,9 +5388,9 @@ Loading of extra modules into libgcrypt is disabled in FIPS mode and thus no tests are -implemented. (@code{cipher/@/cipher.c:@/gcry_cipher_register}, - at code{cipher/@/md.c:@/gcry_md_register}, - at code{cipher/@/md.c:@/gcry_pk_register}) +implemented. (@code{cipher/@/cipher.c:@/_gcry_cipher_register}, + at code{cipher/@/md.c:@/_gcry_md_register}, + at code{cipher/@/pubkey.c:@/_gcry_pk_register}) @subsection Manual Key Entry Tests From cvs at cvs.gnupg.org Fri Apr 3 05:33:57 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Fri, 03 Apr 2009 05:33:57 +0200 Subject: [svn] GnuPG - r4977 - branches/STABLE-BRANCH-1-4/util Message-ID: Author: dshaw Date: 2009-04-03 05:33:57 +0200 (Fri, 03 Apr 2009) New Revision: 4977 Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog branches/STABLE-BRANCH-1-4/util/Makefile.am branches/STABLE-BRANCH-1-4/util/srv.c Log: * Makefile.am: Make srv.c part of libcompat instead of libutil. * srv.c (getsrv): Raise maximum packet size to 2048, as PACKETSZ is too small these days. Use libc malloc and free as we're part of libcompat now which may not be linked to memory.c. Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-04-02 07:20:35 UTC (rev 4976) +++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-04-03 03:33:57 UTC (rev 4977) @@ -1,3 +1,11 @@ +2009-04-02 David Shaw + + * Makefile.am: Make srv.c part of libcompat instead of libutil. + + * srv.c (getsrv): Raise maximum packet size to 2048, as PACKETSZ + is too small these days. Use libc malloc and free as we're part + of libcompat now which may not be linked to memory.c. + 2009-03-20 David Shaw * iobuf.c (fd_cache_synchronize): New. fsync() a file in cache. Modified: branches/STABLE-BRANCH-1-4/util/Makefile.am =================================================================== --- branches/STABLE-BRANCH-1-4/util/Makefile.am 2009-04-02 07:20:35 UTC (rev 4976) +++ branches/STABLE-BRANCH-1-4/util/Makefile.am 2009-04-03 03:33:57 UTC (rev 4977) @@ -44,10 +44,6 @@ libutil_a_SOURCES+=regex.c endif -if USE_DNS_SRV -libutil_a_SOURCES+=srv.c srv.h -endif - # The internal regex code #includes these. EXTRA_libutil_a_SOURCES = regcomp.c regexec.c regex_internal.c \ regex_internal.h @@ -64,6 +60,10 @@ libcompat_a_DEPENDENCIES = @LIBOBJS@ libcompat_a_LIBADD = @LIBOBJS@ +if USE_DNS_SRV +libcompat_a_SOURCES+=srv.c +endif + http-test: http.c $(CC) -DHAVE_CONFIG_H $(CFLAGS) -I. $(INCLUDES) $(LDFLAGS) -g -Wall \ -DTEST -o http-test http.c libutil.a @LIBINTL@ @DNSLIBS@ @CAPLIBS@ Modified: branches/STABLE-BRANCH-1-4/util/srv.c =================================================================== --- branches/STABLE-BRANCH-1-4/util/srv.c 2009-04-02 07:20:35 UTC (rev 4976) +++ branches/STABLE-BRANCH-1-4/util/srv.c 2009-04-03 03:33:57 UTC (rev 4977) @@ -1,5 +1,5 @@ /* srv.c - DNS SRV code - * Copyright (C) 2003, 2005, 2006, 2007 Free Software Foundation, Inc. + * Copyright (C) 2003, 2005, 2006, 2007, 2009 Free Software Foundation, Inc. * * This file is part of GNUPG. * @@ -31,8 +31,6 @@ #include #include #include -#include "memory.h" -#include "types.h" #include "srv.h" /* Not every installation has gotten around to supporting SRVs @@ -56,15 +54,15 @@ int getsrv(const char *name,struct srventry **list) { - unsigned char answer[PACKETSZ]; + unsigned char answer[2048]; int r,srvcount=0; unsigned char *pt,*emsg; u16 count,dlen; *list=NULL; - r=res_query(name,C_IN,T_SRV,answer,PACKETSZ); - if(rPACKETSZ) + r=res_query(name,C_IN,T_SRV,answer,2048); + if(r2048) return -1; if((((HEADER *)answer)->rcode)==NOERROR && @@ -88,7 +86,11 @@ struct srventry *srv=NULL; u16 type,class; - *list=xrealloc(*list,(srvcount+1)*sizeof(struct srventry)); + srv=realloc(*list,(srvcount+1)*sizeof(struct srventry)); + if(!srv) + goto fail; + + *list=srv; memset(&(*list)[srvcount],0,sizeof(struct srventry)); srv=&(*list)[srvcount]; srvcount++; @@ -215,12 +217,12 @@ return srvcount; noanswer: - xfree(*list); + free(*list); *list=NULL; return 0; fail: - xfree(*list); + free(*list); *list=NULL; return -1; } @@ -243,7 +245,7 @@ printf("\n"); } - xfree(srv); + free(srv); return 0; } From cvs at cvs.gnupg.org Fri Apr 3 05:38:59 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Fri, 03 Apr 2009 05:38:59 +0200 Subject: [svn] GnuPG - r4978 - branches/STABLE-BRANCH-1-4/util Message-ID: Author: dshaw Date: 2009-04-03 05:38:59 +0200 (Fri, 03 Apr 2009) New Revision: 4978 Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog branches/STABLE-BRANCH-1-4/util/http.c Log: * http.c (connect_server): free (rather than xfree) the result of getsrv(). Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-04-03 03:33:57 UTC (rev 4977) +++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-04-03 03:38:59 UTC (rev 4978) @@ -1,5 +1,8 @@ 2009-04-02 David Shaw + * http.c (connect_server): free (rather than xfree) the result of + getsrv(). + * Makefile.am: Make srv.c part of libcompat instead of libutil. * srv.c (getsrv): Raise maximum packet size to 2048, as PACKETSZ Modified: branches/STABLE-BRANCH-1-4/util/http.c =================================================================== --- branches/STABLE-BRANCH-1-4/util/http.c 2009-04-03 03:33:57 UTC (rev 4977) +++ branches/STABLE-BRANCH-1-4/util/http.c 2009-04-03 03:38:59 UTC (rev 4978) @@ -856,7 +856,9 @@ { /* Either we're not using SRV, or the SRV lookup failed. Make up a fake SRV record. */ - srvlist=xmalloc_clear(sizeof(struct srventry)); + srvlist=calloc(1,sizeof(struct srventry)); + if(!srvlist) + return -1; srvlist->port=port; strncpy(srvlist->target,server,MAXDNAME); srvlist->target[MAXDNAME-1]='\0'; @@ -959,7 +961,7 @@ } #endif /* !HAVE_GETADDRINFO */ - xfree(srvlist); + free(srvlist); if(!connected) { From cvs at cvs.gnupg.org Fri Apr 3 05:59:07 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Fri, 03 Apr 2009 05:59:07 +0200 Subject: [svn] GnuPG - r4979 - in branches/STABLE-BRANCH-1-4: include keyserver util Message-ID: Author: dshaw Date: 2009-04-03 05:59:07 +0200 (Fri, 03 Apr 2009) New Revision: 4979 Modified: branches/STABLE-BRANCH-1-4/include/ChangeLog branches/STABLE-BRANCH-1-4/include/http.h branches/STABLE-BRANCH-1-4/keyserver/ChangeLog branches/STABLE-BRANCH-1-4/keyserver/curl-shim.c branches/STABLE-BRANCH-1-4/keyserver/curl-shim.h branches/STABLE-BRANCH-1-4/util/ChangeLog branches/STABLE-BRANCH-1-4/util/http.c Log: * curl-shim.h, curl-shim.c (curl_easy_setopt, curl_easy_perform): Add a CURLOPT_SRVTAG_GPG_HACK (passed through the the http engine). * http.h: Allow passing srvtag to http_open and http_open_document. * http.c (http_open, http_open_document): Allow passing srvtag to http_open and http_open_document. Modified: branches/STABLE-BRANCH-1-4/include/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/include/ChangeLog 2009-04-03 03:38:59 UTC (rev 4978) +++ branches/STABLE-BRANCH-1-4/include/ChangeLog 2009-04-03 03:59:07 UTC (rev 4979) @@ -1,3 +1,8 @@ +2009-04-02 David Shaw + + * http.h: Allow passing srvtag to http_open and + http_open_document. + 2008-04-17 David Shaw * cipher.h: Add the 192-bit variant of Camellia. Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-04-03 03:38:59 UTC (rev 4978) +++ branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-04-03 03:59:07 UTC (rev 4979) @@ -1,3 +1,9 @@ +2009-04-02 David Shaw + + * curl-shim.h, curl-shim.c (curl_easy_setopt, curl_easy_perform): + Add a CURLOPT_SRVTAG_GPG_HACK (passed through the the http + engine). + 2009-04-01 David Shaw * gpgkeys_hkp.c (main): Switch default port for SSLized HKP to Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-04-03 03:38:59 UTC (rev 4978) +++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-04-03 03:59:07 UTC (rev 4979) @@ -2,6 +2,8 @@ * http.c (connect_server): free (rather than xfree) the result of getsrv(). + (http_open, http_open_document): Allow passing srvtag to http_open + and http_open_document. * Makefile.am: Make srv.c part of libcompat instead of libutil. Modified: branches/STABLE-BRANCH-1-4/include/http.h =================================================================== --- branches/STABLE-BRANCH-1-4/include/http.h 2009-04-03 03:38:59 UTC (rev 4978) +++ branches/STABLE-BRANCH-1-4/include/http.h 2009-04-03 03:59:07 UTC (rev 4979) @@ -1,6 +1,6 @@ /* http.h - HTTP protocol handler - * Copyright (C) 1999, 2000, 2001, 2003, 2004, - * 2005 Free Software Foundation, Inc. + * Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, + * 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -54,8 +54,7 @@ /* put flag values into an enum, so that gdb can display them */ enum { - HTTP_FLAG_NO_SHUTDOWN = 1, - HTTP_FLAG_TRY_SRV = 2 + HTTP_FLAG_NO_SHUTDOWN = 1 }; struct http_context { @@ -75,11 +74,13 @@ typedef struct http_context *HTTP_HD; int http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url, - char *auth, unsigned int flags, const char *proxy ); + char *auth, unsigned int flags, const char *proxy, + const char *srvtag ); void http_start_data( HTTP_HD hd ); int http_wait_response( HTTP_HD hd, unsigned int *ret_status ); void http_close( HTTP_HD hd ); int http_open_document( HTTP_HD hd, const char *document, char *auth, - unsigned int flags, const char *proxy ); + unsigned int flags, const char *proxy, + const char *srvtag ); #endif /*G10_HTTP_H*/ Modified: branches/STABLE-BRANCH-1-4/keyserver/curl-shim.c =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/curl-shim.c 2009-04-03 03:38:59 UTC (rev 4978) +++ branches/STABLE-BRANCH-1-4/keyserver/curl-shim.c 2009-04-03 03:59:07 UTC (rev 4979) @@ -1,7 +1,7 @@ /* curl-shim.c - Implement a small subset of the curl API in terms of * the iobuf HTTP API * - * Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -134,6 +134,9 @@ case CURLOPT_POSTFIELDS: curl->postfields=va_arg(ap,char *); break; + case CURLOPT_SRVTAG_GPG_HACK: + curl->srvtag=va_arg(ap,char *); + break; case CURLOPT_FAILONERROR: curl->flags.failonerror=va_arg(ap,long)?1:0; break; @@ -182,7 +185,8 @@ if(curl->flags.post) { - rc=http_open(&curl->hd,HTTP_REQ_POST,curl->url,curl->auth,0,proxy); + rc=http_open(&curl->hd,HTTP_REQ_POST,curl->url,curl->auth,0,proxy, + curl->srvtag); if(rc==0) { char content_len[50]; @@ -203,7 +207,8 @@ } else { - rc=http_open(&curl->hd,HTTP_REQ_GET,curl->url,curl->auth,0,proxy); + rc=http_open(&curl->hd,HTTP_REQ_GET,curl->url,curl->auth,0,proxy, + curl->srvtag); if(rc==0) { rc=http_wait_response(&curl->hd,&curl->status); Modified: branches/STABLE-BRANCH-1-4/keyserver/curl-shim.h =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/curl-shim.h 2009-04-03 03:38:59 UTC (rev 4978) +++ branches/STABLE-BRANCH-1-4/keyserver/curl-shim.h 2009-04-03 03:59:07 UTC (rev 4979) @@ -1,5 +1,5 @@ /* curl-shim.h - * Copyright (C) 2005, 2006, 2007, 2008 Free Software Foundation, Inc. + * Copyright (C) 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. * * This file is part of GNUPG. * @@ -48,7 +48,8 @@ CURLOPT_CAINFO, CURLOPT_POST, CURLOPT_POSTFIELDS, - CURLOPT_FAILONERROR + CURLOPT_FAILONERROR, + CURLOPT_SRVTAG_GPG_HACK } CURLoption; typedef size_t (*write_func)(char *buffer,size_t size, @@ -63,6 +64,7 @@ write_func writer; void *file; char *postfields; + char *srvtag; unsigned int status; FILE *errors; struct Modified: branches/STABLE-BRANCH-1-4/util/http.c =================================================================== --- branches/STABLE-BRANCH-1-4/util/http.c 2009-04-03 03:38:59 UTC (rev 4978) +++ branches/STABLE-BRANCH-1-4/util/http.c 2009-04-03 03:59:07 UTC (rev 4979) @@ -1,6 +1,6 @@ /* http.c - HTTP protocol handler - * Copyright (C) 1999, 2001, 2002, 2003, 2004, - * 2005, 2009 Free Software Foundation, Inc. + * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, + * 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -148,7 +148,8 @@ int http_open( HTTP_HD hd, HTTP_REQ_TYPE reqtype, const char *url, - char *auth, unsigned int flags, const char *proxy ) + char *auth, unsigned int flags, const char *proxy, + const char *srvtag ) { int rc; @@ -232,11 +233,11 @@ int http_open_document( HTTP_HD hd, const char *document, char *auth, - unsigned int flags, const char *proxy ) + unsigned int flags, const char *proxy, const char *srvtag ) { int rc; - rc = http_open(hd, HTTP_REQ_GET, document, auth, flags, proxy ); + rc = http_open(hd, HTTP_REQ_GET, document, auth, flags, proxy, srvtag ); if( rc ) return rc; @@ -836,7 +837,7 @@ #ifdef USE_DNS_SRV /* Do the SRV thing */ - if(flags&HTTP_FLAG_TRY_SRV && srvtag) + if(srvtag) { /* We're using SRV, so append the tags */ if(1+strlen(srvtag)+6+strlen(server)+1<=MAXDNAME) From cvs at cvs.gnupg.org Fri Apr 3 10:36:01 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 03 Apr 2009 10:36:01 +0200 Subject: [svn] assuan - r295 - in trunk: doc src Message-ID: Author: wk Date: 2009-04-03 10:36:01 +0200 (Fri, 03 Apr 2009) New Revision: 295 Modified: trunk/doc/assuan.texi trunk/src/ChangeLog trunk/src/assuan-handler.c Log: Doc fixes. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-02-24 15:24:58 UTC (rev 294) +++ trunk/src/ChangeLog 2009-04-03 08:36:01 UTC (rev 295) @@ -1,3 +1,7 @@ +2009-04-03 Werner Koch + + * assuan-handler.c (std_cmd_table): Remove second OPTION entry. + 2009-02-24 Werner Koch * assuan-buffer.c (assuan_send_data): Add hack to optionally send Modified: trunk/doc/assuan.texi =================================================================== --- trunk/doc/assuan.texi 2009-02-24 15:24:58 UTC (rev 294) +++ trunk/doc/assuan.texi 2009-04-03 08:36:01 UTC (rev 295) @@ -364,6 +364,9 @@ This command is reserved for future extensions. Not yet specified as we don't implement it in the first phase. See my mail to gpa-dev on 2001-10-25 about the rationale for measurements against local attacks. + + at item NOP +No operation. Returns OK without any action. @end table Modified: trunk/src/assuan-handler.c =================================================================== --- trunk/src/assuan-handler.c 2009-02-24 15:24:58 UTC (rev 294) +++ trunk/src/assuan-handler.c 2009-04-03 08:36:01 UTC (rev 295) @@ -253,7 +253,6 @@ { "INPUT", std_handler_input, 0 }, { "OUTPUT", std_handler_output, 0 }, - { "OPTION", std_handler_option, 1 }, { NULL, NULL, 0 } }; From cvs at cvs.gnupg.org Fri Apr 3 11:26:08 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 03 Apr 2009 11:26:08 +0200 Subject: [svn] dirmngr - r312 - trunk/src Message-ID: Author: wk Date: 2009-04-03 11:26:08 +0200 (Fri, 03 Apr 2009) New Revision: 312 Modified: trunk/src/ChangeLog trunk/src/dirmngr.h trunk/src/ldapserver.h trunk/src/server.c Log: Fix segv with "dirmngr --fetch-url". Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2008-10-30 10:21:19 UTC (rev 311) +++ trunk/src/ChangeLog 2009-04-03 09:26:08 UTC (rev 312) @@ -1,6 +1,12 @@ +2009-04-03 Werner Koch + + * dirmngr.h (struct server_local_s): Move back to ... + * server.c (struct server_local_s): ... here. + (get_ldapservers_from_ctrl): New. + * ldapserver.h (ldapserver_iter_begin): Use it. + 2008-10-29 Marcus Brinkmann - * estream.c (es_getline): Add explicit cast to silence gcc -W warning. * crlcache.c (finish_sig_check): Likewise. @@ -327,7 +333,7 @@ 2007-08-13 Werner Koch * dirmngr.c (handle_connections): Use a timeout in the accept - fucntion. Block signals while creating a new thread. */ + function. Block signals while creating a new thread. (shutdown_pending): Needs to be volatile as also accessed bt the service function. (w32_service_control): Do not use the regular log fucntions here. Modified: trunk/src/dirmngr.h =================================================================== --- trunk/src/dirmngr.h 2008-10-30 10:21:19 UTC (rev 311) +++ trunk/src/dirmngr.h 2009-04-03 09:26:08 UTC (rev 312) @@ -143,18 +143,10 @@ }; typedef struct cert_ref_s *cert_ref_t; +/* Forward references; access only through server.c. */ +struct server_local_s; -/* Control structure per connection. */ -struct server_local_s -{ - /* Data used to associate an Assuan context with local server data */ - assuan_context_t assuan_ctx; - - /* Per-session LDAP serfver. */ - ldap_server_t ldapservers; -}; - - +/* Connection control structure. */ struct server_control_s { int refcount; /* Count additional references to this object. */ @@ -178,6 +170,7 @@ void dirmngr_init_default_ctrl (ctrl_t ctrl); /*-- server.c --*/ +ldap_server_t get_ldapservers_from_ctrl (ctrl_t ctrl); ksba_cert_t get_cert_local (ctrl_t ctrl, const char *issuer); ksba_cert_t get_issuing_cert_local (ctrl_t ctrl, const char *issuer); ksba_cert_t get_cert_local_ski (ctrl_t ctrl, Modified: trunk/src/ldapserver.h =================================================================== --- trunk/src/ldapserver.h 2008-10-30 10:21:19 UTC (rev 311) +++ trunk/src/ldapserver.h 2009-04-03 09:26:08 UTC (rev 312) @@ -81,7 +81,7 @@ { iter->ctrl = ctrl; iter->group = LDAPSERVER_SESSION; - iter->server = ctrl->server_local->ldapservers; + iter->server = get_ldapservers_from_ctrl (ctrl); while (iter->server == NULL && ! ldapserver_iter_end_p (iter)) ldapserver_iter_next (iter); Modified: trunk/src/server.c =================================================================== --- trunk/src/server.c 2008-10-30 10:21:19 UTC (rev 311) +++ trunk/src/server.c 2009-04-03 09:26:08 UTC (rev 312) @@ -49,6 +49,32 @@ gpg_error (GPG_ERR_ASS_PARAMETER), (t)) + +/* Control structure per connection. */ +struct server_local_s +{ + /* Data used to associate an Assuan context with local server data */ + assuan_context_t assuan_ctx; + + /* Per-session LDAP serfver. */ + ldap_server_t ldapservers; +}; + + + + +/* Accessor for the local ldapservers variable. */ +ldap_server_t +get_ldapservers_from_ctrl (ctrl_t ctrl) +{ + if (ctrl && ctrl->server_local) + return ctrl->server_local->ldapservers; + else + return NULL; +} + + + /* Copy the % and + escaped string S into the buffer D and replace the escape sequences. Note, that it is sufficient to allocate the target string D as long as the source string S, i.e.: strlen(s)+1. From cvs at cvs.gnupg.org Fri Apr 3 12:34:23 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 03 Apr 2009 12:34:23 +0200 Subject: [svn] GnuPG - r4980 - trunk/g10 Message-ID: Author: wk Date: 2009-04-03 12:34:22 +0200 (Fri, 03 Apr 2009) New Revision: 4980 Modified: trunk/g10/ChangeLog trunk/g10/gpg.h trunk/g10/gpgv.c trunk/g10/keydb.c trunk/g10/keyring.c trunk/g10/keyring.h Log: Make gpgv error message about a missing keyring more useful. This fixes Debian#494040. Also implement readonly semantic for extra safety. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2009-04-03 03:59:07 UTC (rev 4979) +++ trunk/g10/ChangeLog 2009-04-03 10:34:22 UTC (rev 4980) @@ -1,3 +1,16 @@ +2009-04-03 Werner Koch + + * gpgv.c (main): Open keyrings readonly. + * keydb.c (keydb_add_resource): Add readonly flag bit. + (keydb_rebuild_caches): Don't act on readonly resources. + + * keyring.c (keyring_register_filename): Add arg READONLY. + (struct keyring_name): Add field READONLY. + (keyring_is_writable): Implement readonly feature. + (keyring_update_keyblock): Return GPG_ERR_EACCES for readonly + keyrings. + (keyring_insert_keyblock, keyring_delete_keyblock): + 2009-04-01 Werner Koch * gpg.c (main): Properly handle UTF8 usernames with --sign-key and Modified: trunk/g10/gpg.h =================================================================== --- trunk/g10/gpg.h 2009-04-03 03:59:07 UTC (rev 4979) +++ trunk/g10/gpg.h 2009-04-03 10:34:22 UTC (rev 4980) @@ -75,7 +75,7 @@ #define g10_errstr(a) gpg_strerror ((a)) -/* Mapping of the old erro codes to the gpg-error ones. Fixme: This +/* Mapping of the old error codes to the gpg-error ones. Fixme: This is just a temporary solution: We need to do all these gpg_error() calls in the code. */ #define G10ERR_BAD_KEY GPG_ERR_BAD_KEY Modified: trunk/g10/gpgv.c =================================================================== --- trunk/g10/gpgv.c 2009-04-03 03:59:07 UTC (rev 4979) +++ trunk/g10/gpgv.c 2009-04-03 10:34:22 UTC (rev 4980) @@ -193,12 +193,13 @@ if (opt.verbose > 1) set_packet_list_mode(1); - - if (!nrings) /* no keyring given: use default one */ - keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 0, 0); + + /* Note: We open all keyrings in read-only mode (flag value: 8). */ + if (!nrings) /* No keyring given: use default one. */ + keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 8, 0); for (sl = nrings; sl; sl = sl->next) - keydb_add_resource (sl->d, 0, 0 ); - + keydb_add_resource (sl->d, 8, 0 ); + FREE_STRLIST (nrings); if ( (rc = verify_signatures( argc, argv ) )) Modified: trunk/g10/keydb.c =================================================================== --- trunk/g10/keydb.c 2009-04-03 03:59:07 UTC (rev 4979) +++ trunk/g10/keydb.c 2009-04-03 10:34:22 UTC (rev 4980) @@ -1,6 +1,6 @@ /* keydb.c - key database dispatcher * Copyright (C) 2001, 2002, 2003, 2004, 2005, - * 2008 Free Software Foundation, Inc. + * 2008, 2009 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -207,9 +207,10 @@ * created if it does not exist. * Note: this function may be called before secure memory is * available. - * Flag 1 == force - * Flag 2 == mark resource as primary - * Flag 4 == This is a default resources + * Flag 1 - Force. + * Flag 2 - Mark resource as primary. + * Flag 4 - This is a default resources. + * Flag 8 - Open as read-only. */ int keydb_add_resource (const char *url, int flags, int secret) @@ -217,11 +218,15 @@ static int any_secret, any_public; const char *resname = url; char *filename = NULL; - int force=(flags&1); + int force = (flags&1); + int readonly = !!(flags&8); int rc = 0; KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; void *token; + if (readonly) + force = 0; + /* Do we have an URL? * gnupg-ring:filename := this is a plain keyring * filename := See what is is, but create as plain keyring. @@ -249,10 +254,10 @@ else filename = xstrdup (resname); - if (!force) + if (!force && !readonly) force = secret? !any_secret : !any_public; - /* see whether we can determine the filetype */ + /* See whether we can determine the filetype. */ if (rt == KEYDB_RESOURCE_TYPE_NONE) { FILE *fp = fopen( filename, "rb" ); @@ -284,7 +289,7 @@ if (rc) goto leave; - if(keyring_register_filename (filename, secret, &token)) + if(keyring_register_filename (filename, secret, readonly, &token)) { if (used_resources >= MAX_KEYDB_RESOURCES) rc = G10ERR_RESOURCE_LIMIT; @@ -702,6 +707,8 @@ { if (all_resources[i].secret) continue; + if (!keyring_is_writable (all_resources[i].token)) + continue; switch (all_resources[i].type) { case KEYDB_RESOURCE_TYPE_NONE: /* ignore */ Modified: trunk/g10/keyring.c =================================================================== --- trunk/g10/keyring.c 2009-04-03 03:59:07 UTC (rev 4979) +++ trunk/g10/keyring.c 2009-04-03 10:34:22 UTC (rev 4980) @@ -50,9 +50,11 @@ typedef struct keyring_name *KR_NAME; -struct keyring_name { +struct keyring_name +{ struct keyring_name *next; int secret; + int readonly; DOTLOCK lockhd; int is_locked; int did_full_scan; @@ -199,7 +201,8 @@ * if a new keyring was registered. */ int -keyring_register_filename (const char *fname, int secret, void **ptr) +keyring_register_filename (const char *fname, int secret, int readonly, + void **ptr) { KR_NAME kr; @@ -210,8 +213,11 @@ { if (same_file_p (kr->fname, fname)) { + /* Already registered. */ + if (readonly) + kr->readonly = 1; *ptr=kr; - return 0; /* Already registered. */ + return 0; } } @@ -221,6 +227,7 @@ kr = xmalloc (sizeof *kr + strlen (fname)); strcpy (kr->fname, fname); kr->secret = !!secret; + kr->readonly = readonly; kr->lockhd = NULL; kr->is_locked = 0; kr->did_full_scan = 0; @@ -242,7 +249,7 @@ { KR_NAME r = token; - return r? !access (r->fname, W_OK) : 0; + return r? (r->readonly || !access (r->fname, W_OK)) : 0; } @@ -499,6 +506,9 @@ if (!hd->found.kr) return -1; /* no successful prior search */ + if (hd->found.kr->readonly) + return gpg_error (GPG_ERR_EACCES); + if (!hd->found.n_packets) { /* need to know the number of packets - do a dummy get_keyblock*/ rc = keyring_get_keyblock (hd, NULL); @@ -540,16 +550,24 @@ if (!hd) fname = NULL; else if (hd->found.kr) + { fname = hd->found.kr->fname; + if (hd->found.kr->readonly) + return gpg_error (GPG_ERR_EACCES); + } else if (hd->current.kr) + { fname = hd->current.kr->fname; + if (hd->current.kr->readonly) + return gpg_error (GPG_ERR_EACCES); + } else fname = hd->resource? hd->resource->fname:NULL; if (!fname) return G10ERR_GENERAL; - /* close this one otherwise we will lose the position for + /* Close this one otherwise we will lose the position for * a next search. Fixme: it would be better to adjust the position * after the write opertions. */ @@ -575,6 +593,9 @@ if (!hd->found.kr) return -1; /* no successful prior search */ + if (hd->found.kr->readonly) + return gpg_error (GPG_ERR_EACCES); + if (!hd->found.n_packets) { /* need to know the number of packets - do a dummy get_keyblock*/ rc = keyring_get_keyblock (hd, NULL); Modified: trunk/g10/keyring.h =================================================================== --- trunk/g10/keyring.h 2009-04-03 03:59:07 UTC (rev 4979) +++ trunk/g10/keyring.h 2009-04-03 10:34:22 UTC (rev 4980) @@ -23,7 +23,8 @@ typedef struct keyring_handle *KEYRING_HANDLE; -int keyring_register_filename (const char *fname, int secret, void **ptr); +int keyring_register_filename (const char *fname, int secret, int readonly, + void **ptr); int keyring_is_writable (void *token); KEYRING_HANDLE keyring_new (void *token, int secret); From cvs at cvs.gnupg.org Fri Apr 3 12:41:34 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 03 Apr 2009 12:41:34 +0200 Subject: [svn] GnuPG - r4981 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: wk Date: 2009-04-03 12:41:33 +0200 (Fri, 03 Apr 2009) New Revision: 4981 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/gpgv.c branches/STABLE-BRANCH-1-4/g10/keydb.c Log: Better error message for a missing keyring. Fixes Debian#494040. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-04-03 10:34:22 UTC (rev 4980) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2009-04-03 10:41:33 UTC (rev 4981) @@ -1,3 +1,8 @@ +2009-04-03 Werner Koch + + * gpgv.c (main): Pass readonly flag to keydb_add_resource. + * keydb.c (keydb_add_resource): Add arg READONLY. + 2009-03-20 David Shaw * keyring.c (rename_tmp_file): Force a fsync (via iobuf_ioctl) on Modified: branches/STABLE-BRANCH-1-4/g10/gpgv.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/gpgv.c 2009-04-03 10:34:22 UTC (rev 4980) +++ branches/STABLE-BRANCH-1-4/g10/gpgv.c 2009-04-03 10:41:33 UTC (rev 4981) @@ -178,9 +178,9 @@ set_packet_list_mode(1); if( !nrings ) /* no keyring given: use default one */ - keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 0, 0); + keydb_add_resource ("trustedkeys" EXTSEP_S "gpg", 8, 0); for(sl = nrings; sl; sl = sl->next ) - keydb_add_resource (sl->d, 0, 0 ); + keydb_add_resource (sl->d, 8, 0 ); FREE_STRLIST(nrings); Modified: branches/STABLE-BRANCH-1-4/g10/keydb.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/keydb.c 2009-04-03 10:34:22 UTC (rev 4980) +++ branches/STABLE-BRANCH-1-4/g10/keydb.c 2009-04-03 10:41:33 UTC (rev 4981) @@ -196,6 +196,7 @@ * Flag 1 == force * Flag 2 == mark resource as primary * Flag 4 == This is a default resources + * Flag 8 == Readonly */ int keydb_add_resource (const char *url, int flags, int secret) @@ -204,10 +205,14 @@ const char *resname = url; char *filename = NULL; int force=(flags&1); + int readonly=!!(flags&8); int rc = 0; KeydbResourceType rt = KEYDB_RESOURCE_TYPE_NONE; void *token; + if (readonly) + force = 0; + /* Do we have an URL? * gnupg-ring:filename := this is a plain keyring * filename := See what is is, but create as plain keyring. @@ -235,7 +240,7 @@ else filename = xstrdup (resname); - if (!force) + if (!force && !readonly) force = secret? !any_secret : !any_public; /* see whether we can determine the filetype */ From cvs at cvs.gnupg.org Fri Apr 3 17:05:37 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 03 Apr 2009 17:05:37 +0200 Subject: [svn] pinentry - r194 - in trunk: . qt4 Message-ID: Author: marcus Date: 2009-04-03 17:05:37 +0200 (Fri, 03 Apr 2009) New Revision: 194 Modified: trunk/ChangeLog trunk/qt4/main.cpp Log: 2009-04-03 Marcus Brinkmann * qt4/main.cpp (qt_cmd_handler): Cast window handle ID. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-03-19 09:48:11 UTC (rev 193) +++ trunk/ChangeLog 2009-04-03 15:05:37 UTC (rev 194) @@ -1,3 +1,7 @@ +2009-04-03 Marcus Brinkmann + + * qt4/main.cpp (qt_cmd_handler): Cast window handle ID. + 2009-03-19 Werner Koch * pinentry/pinentry.h (struct pinentry): Add field user_closed. @@ -281,7 +285,7 @@ 2005-01-21 Marcus Brinkmann * doc/pinentry.texi: Fix spelling errors. - Submitted by Ville Skytt?. + Submitted by Ville Skytt??. 2004-12-23 Werner Koch Modified: trunk/qt4/main.cpp =================================================================== --- trunk/qt4/main.cpp 2009-03-19 09:48:11 UTC (rev 193) +++ trunk/qt4/main.cpp 2009-04-03 15:05:37 UTC (rev 194) @@ -68,7 +68,7 @@ { /* FIXME: Add parent window ID to pinentry and GTK. */ if (pe->parent_wid) - parent = new ForeignWidget (pe->parent_wid); + parent = new ForeignWidget ((HWND) pe->parent_wid); PinEntryDialog pinentry (parent, 0, true); From cvs at cvs.gnupg.org Fri Apr 3 17:10:22 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 03 Apr 2009 17:10:22 +0200 Subject: [svn] pinentry - r195 - in trunk: . qt4 Message-ID: Author: marcus Date: 2009-04-03 17:10:22 +0200 (Fri, 03 Apr 2009) New Revision: 195 Modified: trunk/ChangeLog trunk/qt4/main.cpp trunk/qt4/pinentrydialog.cpp trunk/qt4/pinentrydialog.h trunk/qt4/pinentrydialog.moc trunk/qt4/qsecurelineedit.cpp trunk/qt4/qsecurelineedit.moc Log: 2009-04-02 Till Adam * qt4/qsecurelineedit.moc, qt4/main.cpp, qt4/pinentrydialog.moc, qt4/qsecurelineedit.cpp, qt4/pinentrydialog.cpp, qt4/pinentrydialog.h: Implement quality bar and grabbing. * qt4/pinentrydialog.cpp (PinEntryDialog): Enable word wrapping. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-03 15:05:37 UTC (rev 194) +++ trunk/ChangeLog 2009-04-03 15:10:22 UTC (rev 195) @@ -1,3 +1,11 @@ +2009-04-02 Till Adam + + * qt4/qsecurelineedit.moc, qt4/main.cpp, qt4/pinentrydialog.moc, + qt4/qsecurelineedit.cpp, qt4/pinentrydialog.cpp, + qt4/pinentrydialog.h: Implement quality bar and grabbing. + + * qt4/pinentrydialog.cpp (PinEntryDialog): Enable word wrapping. + 2009-04-03 Marcus Brinkmann * qt4/main.cpp (qt_cmd_handler): Cast window handle ID. Modified: trunk/qt4/main.cpp =================================================================== --- trunk/qt4/main.cpp 2009-04-03 15:05:37 UTC (rev 194) +++ trunk/qt4/main.cpp 2009-04-03 15:10:22 UTC (rev 195) @@ -1,4 +1,4 @@ -/* +/* main.cpp - A (not yet) secure Qt 4 dialog for PIN entry. Copyright (C) 2002, 2008 Klar?lvdalens Datakonsult AB (KDAB) @@ -8,17 +8,17 @@ 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 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. @@ -50,7 +50,7 @@ QWidget::destroy(); create( wid, false, false ); } - + ~ForeignWidget() { destroy( false, false ); @@ -70,8 +70,9 @@ if (pe->parent_wid) parent = new ForeignWidget ((HWND) pe->parent_wid); - PinEntryDialog pinentry (parent, 0, true); + PinEntryDialog pinentry (parent, 0, true, !!pe->quality_bar); + pinentry.setPinentryInfo (pe); pinentry.setPrompt (QString::fromUtf8 (pe->prompt)); pinentry.setDescription (QString::fromUtf8 (pe->description)); /* If we reuse the same dialog window. */ @@ -83,6 +84,10 @@ pinentry.setCancelText (QString::fromUtf8 (pe->cancel)); if (pe->error) pinentry.setError (QString::fromUtf8 (pe->error)); + if (pe->quality_bar) + pinentry.setQualityBar (QString::fromUtf8 (pe->quality_bar)); + if (pe->quality_bar_tt) + pinentry.setQualityBarTT (QString::fromUtf8 (pe->quality_bar_tt)); bool ret = pinentry.exec (); if (!ret) @@ -111,16 +116,16 @@ QString ok = QString::fromUtf8 (pe->ok ? pe->ok : "OK"); QString can = QString::fromUtf8 (pe->cancel ? pe->cancel : "Cancel"); bool ret; - + ret = QMessageBox::information (parent, "", desc, ok, can ); - + return !ret; } } pinentry_cmd_handler_t pinentry_cmd_handler = qt_cmd_handler; -int +int main (int argc, char *argv[]) { pinentry_init ("pinentry-qt4"); @@ -149,7 +154,7 @@ fprintf (stderr, "pinentry-qt4: can't fixup argument list: %s\n", strerror (errno)); exit (EXIT_FAILURE); - + } for (done=0,p=*new_argv,i=0; i < argc; i++) if (!done && !strcmp (argv[i], "--display")) @@ -168,8 +173,8 @@ i = argc; new QApplication (i, new_argv); } - + /* Consumes all arguments. */ if (pinentry_parse_opts (argc, argv)) { Modified: trunk/qt4/pinentrydialog.cpp =================================================================== --- trunk/qt4/pinentrydialog.cpp 2009-04-03 15:05:37 UTC (rev 194) +++ trunk/qt4/pinentrydialog.cpp 2009-04-03 15:10:22 UTC (rev 195) @@ -1,27 +1,28 @@ -/* +/* pinentrydialog.cpp - A (not yet) secure Qt 4 dialog for PIN entry. Copyright (C) 2002, 2008 Klar?lvdalens Datakonsult AB (KDAB) Copyright 2007 Ingo Kl??cker Written by Steffen Hansen . - + 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. */ #include "pinentrydialog.h" +#include #include "qsecurelineedit.h" @@ -32,7 +33,8 @@ #include #include -PinEntryDialog::PinEntryDialog( QWidget* parent, const char* name, bool modal ) +PinEntryDialog::PinEntryDialog( QWidget* parent, const char* name, bool modal, + bool enable_quality_bar ) : QDialog( parent ), _grabbed( false ) { if ( modal ) { @@ -52,22 +54,38 @@ upperLayout->addLayout( labelLayout ); _error = new QLabel( this ); + _error->setWordWrap(true); labelLayout->addWidget( _error ); _desc = new QLabel( this ); + _desc->setWordWrap(true); labelLayout->addWidget( _desc ); - QBoxLayout* l = new QHBoxLayout(); - top->addLayout( l ); + QGridLayout* grid = new QGridLayout; + top->addLayout( grid ); + _prompt = new QLabel( this ); - l->addWidget( _prompt ); + grid->addWidget( _prompt, 0, 0 ); _edit = new QSecureLineEdit( this ); _edit->setMaxLength( 256 ); - l->addWidget( _edit ); + grid->addWidget( _edit, 0, 1 ); - l = new QHBoxLayout(); - top->addLayout( l ); + if (enable_quality_bar) + { + _quality_bar_label = new QLabel( this ); + _quality_bar_label->setAlignment( Qt::AlignRight | Qt::AlignVCenter ); + grid->addWidget ( _quality_bar_label, 1, 0 ); + _quality_bar = new QProgressBar( this ); + _quality_bar->setAlignment( Qt::AlignCenter ); + grid->addWidget( _quality_bar, 1, 1 ); + _have_quality_bar = true; + } + else + _have_quality_bar = false; + QBoxLayout* l = new QHBoxLayout(); + top->addLayout( l ); + _ok = new QPushButton( tr("OK"), this ); _cancel = new QPushButton( tr("Cancel"), this ); @@ -81,7 +99,8 @@ this, SIGNAL( accepted() ) ); connect( _cancel, SIGNAL( clicked() ), this, SIGNAL( rejected() ) ); - + connect( _edit, SIGNAL( textChanged(secqstring) ), + this, SLOT( updateQuality(secqstring) ) ); connect (this, SIGNAL (accepted ()), this, SLOT (accept ())); connect (this, SIGNAL (rejected ()), @@ -90,25 +109,15 @@ _edit->setFocus(); } -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; - } -} - void PinEntryDialog::hideEvent( QHideEvent* ev ) { - _edit->releaseKeyboard(); + if ( !_pinentry_info || _pinentry_info->grab ) + _edit->releaseKeyboard(); _grabbed = false; QDialog::hideEvent( ev ); } -void PinEntryDialog::keyPressEvent( QKeyEvent* e ) +void PinEntryDialog::keyPressEvent( QKeyEvent* e ) { if ( e->modifiers() == Qt::NoModifier && e->key() == Qt::Key_Escape ) { emit rejected(); @@ -117,45 +126,45 @@ QDialog::keyPressEvent( e ); } -void PinEntryDialog::setDescription( const QString& txt ) +void PinEntryDialog::setDescription( const QString& txt ) { _desc->setText( txt ); _icon->setPixmap( QMessageBox::standardIcon( QMessageBox::Information ) ); setError( QString::null ); } -QString PinEntryDialog::description() const +QString PinEntryDialog::description() const { return _desc->text(); } -void PinEntryDialog::setError( const QString& txt ) +void PinEntryDialog::setError( const QString& txt ) { if( !txt.isNull() )_icon->setPixmap( QMessageBox::standardIcon( QMessageBox::Critical ) ); _error->setText( txt ); } -QString PinEntryDialog::error() const +QString PinEntryDialog::error() const { return _error->text(); } -void PinEntryDialog::setPin( const secqstring & txt ) +void PinEntryDialog::setPin( const secqstring & txt ) { _edit->setText( txt ); } -secqstring PinEntryDialog::pin() const +secqstring PinEntryDialog::pin() const { return _edit->text(); } -void PinEntryDialog::setPrompt( const QString& txt ) +void PinEntryDialog::setPrompt( const QString& txt ) { _prompt->setText( txt ); } -QString PinEntryDialog::prompt() const +QString PinEntryDialog::prompt() const { return _prompt->text(); } @@ -170,4 +179,68 @@ _cancel->setText( txt ); } +void PinEntryDialog::setQualityBar( const QString& txt ) +{ + if (_have_quality_bar) + _quality_bar_label->setText( txt ); +} + +void PinEntryDialog::setQualityBarTT( const QString& txt ) +{ + if (_have_quality_bar) + _quality_bar->setToolTip( txt ); +} + +void PinEntryDialog::updateQuality(const secqstring & txt ) +{ + int length; + int percent; + QPalette pal; + + if (!_have_quality_bar || !_pinentry_info) + return; + secstring pinStr = toUtf8(txt); + const char* pin = pinStr.c_str(); + // The Qt3 version called ::secmem_free (pin) here, but from other usage of secstring, + // it seems like this is not needed anymore - 16 Mar. 2009 13:15 -- Jesper K. Pedersen + length = strlen (pin); + percent = length? pinentry_inq_quality (_pinentry_info, pin, length) : 0; + if (!length) + { + _quality_bar->reset (); + } + else + { + pal = _quality_bar->palette (); + if (percent < 0) + { + pal.setColor (QPalette::Highlight, QColor("red")); + percent = -percent; + } + else + { + pal.setColor (QPalette::Highlight, QColor("green")); + } + _quality_bar->setPalette (pal); + _quality_bar->setValue (percent); + } +} + +void PinEntryDialog::setPinentryInfo(pinentry_t peinfo) +{ + _pinentry_info = peinfo; +} + +void PinEntryDialog::paintEvent( QPaintEvent* event ) +{ + // Grab keyboard. It might be a little weird to do it here, but it works! + // Previously this code was in showEvent, but that did not work in Qt4. + QDialog::paintEvent( event ); + if ( !_grabbed && ( !_pinentry_info || _pinentry_info->grab ) ) { + _edit->grabKeyboard(); + _grabbed = true; + } + +} + #include "pinentrydialog.moc" Modified: trunk/qt4/pinentrydialog.h =================================================================== --- trunk/qt4/pinentrydialog.h 2009-04-03 15:05:37 UTC (rev 194) +++ trunk/qt4/pinentrydialog.h 2009-04-03 15:10:22 UTC (rev 195) @@ -1,21 +1,21 @@ -/* +/* pinentrydialog.h - A (not yet) secure Qt 4 dialog for PIN entry. Copyright (C) 2002, 2008 Klar?lvdalens Datakonsult AB (KDAB) Copyright 2007 Ingo Kl??cker Written by Steffen Hansen . - + 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. @@ -24,9 +24,11 @@ #ifndef __PINENTRYDIALOG_H__ #define __PINENTRYDIALOG_H__ +#include #include #include "secstring.h" +#include "pinentry.h" class QLabel; class QPushButton; @@ -44,7 +46,7 @@ Q_PROPERTY( QString prompt READ prompt WRITE setPrompt ) public: friend class PinEntryController; // TODO: remove when assuan lets me use Qt eventloop. - explicit PinEntryDialog( QWidget* parent = 0, const char* name = 0, bool modal = false ); + explicit PinEntryDialog( QWidget* parent = 0, const char* name = 0, bool modal = false, bool enable_quality_bar = false ); void setDescription( const QString& ); QString description() const; @@ -57,10 +59,18 @@ void setPrompt( const QString& ); QString prompt() const; - + void setOkText( const QString& ); void setCancelText( const QString& ); + void setQualityBar( const QString& ); + void setQualityBarTT( const QString& ); + + void setPinentryInfo (pinentry_t); + +public slots: + void updateQuality(const secqstring&); + signals: void accepted(); void rejected(); @@ -68,17 +78,21 @@ protected: /* reimp */ void keyPressEvent( QKeyEvent *e ); /* reimp */ void hideEvent( QHideEvent* ); - /* reimp */ void showEvent( QShowEvent* ); + /* reimp */ void paintEvent( QPaintEvent* event ); private: QLabel* _icon; QLabel* _desc; QLabel* _error; QLabel* _prompt; + QLabel* _quality_bar_label; + QProgressBar* _quality_bar; QSecureLineEdit* _edit; QPushButton* _ok; - QPushButton* _cancel; + QPushButton* _cancel; bool _grabbed; + bool _have_quality_bar; + pinentry_t _pinentry_info; }; #endif // __PINENTRYDIALOG_H__ Modified: trunk/qt4/pinentrydialog.moc =================================================================== --- trunk/qt4/pinentrydialog.moc 2009-04-03 15:05:37 UTC (rev 194) +++ trunk/qt4/pinentrydialog.moc 2009-04-03 15:10:22 UTC (rev 195) @@ -1,7 +1,7 @@ /**************************************************************************** ** Meta object code from reading C++ file 'pinentrydialog.h' ** -** Created: Mon Oct 20 09:30:12 2008 +** Created: Mon Mar 16 13:03:03 2009 ** by: The Qt Meta Object Compiler version 59 (Qt 4.4.1) ** ** WARNING! All changes made in this file will be lost! @@ -23,27 +23,31 @@ 1, // revision 0, // classname 0, 0, // classinfo - 2, 10, // methods - 4, 20, // properties + 3, 10, // methods + 4, 25, // properties 0, 0, // enums/sets // signals: signature, parameters, type, tag, flags 16, 15, 15, 15, 0x05, 27, 15, 15, 15, 0x05, + // slots: signature, parameters, type, tag, flags + 38, 15, 15, 15, 0x0a, + // properties: name, type, flags - 46, 38, 0x0a095103, - 58, 38, 0x0a095103, - 75, 64, 0x0009510b, - 79, 38, 0x0a095103, + 72, 64, 0x0a095103, + 84, 64, 0x0a095103, + 101, 90, 0x0009510b, + 105, 64, 0x0a095103, 0 // eod }; static const char qt_meta_stringdata_PinEntryDialog[] = { "PinEntryDialog\0\0accepted()\0rejected()\0" - "QString\0description\0error\0secqstring\0" - "pin\0prompt\0" + "updateQuality(secqstring)\0QString\0" + "description\0error\0secqstring\0pin\0" + "prompt\0" }; const QMetaObject PinEntryDialog::staticMetaObject = { @@ -73,8 +77,9 @@ switch (_id) { case 0: accepted(); break; case 1: rejected(); break; + case 2: updateQuality((*reinterpret_cast< const secqstring(*)>(_a[1]))); break; } - _id -= 2; + _id -= 3; } #ifndef QT_NO_PROPERTIES else if (_c == QMetaObject::ReadProperty) { Modified: trunk/qt4/qsecurelineedit.cpp =================================================================== --- trunk/qt4/qsecurelineedit.cpp 2009-04-03 15:05:37 UTC (rev 194) +++ trunk/qt4/qsecurelineedit.cpp 2009-04-03 15:10:22 UTC (rev 195) @@ -1,20 +1,20 @@ -/* +/* 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. @@ -2165,7 +2165,7 @@ // Focus in if currently in navigation focus on the widget // Only focus in on preedits, to allow input methods to // commit text as they focus out without interfering with focus - if (QApplication::keypadNavigationEnabled() && + if (QApplication::keypadNavigationEnabled() && hasFocus() && !hasEditFocus() && !e->preeditString().isEmpty()) { setEditFocus(true); Modified: trunk/qt4/qsecurelineedit.moc =================================================================== --- trunk/qt4/qsecurelineedit.moc 2009-04-03 15:05:37 UTC (rev 194) +++ trunk/qt4/qsecurelineedit.moc 2009-04-03 15:10:22 UTC (rev 195) @@ -1,7 +1,7 @@ /**************************************************************************** ** Meta object code from reading C++ file 'qsecurelineedit.h' ** -** Created: Mon Oct 20 09:29:54 2008 +** Created: Mon Mar 16 13:03:26 2009 ** by: The Qt Meta Object Compiler version 59 (Qt 4.4.1) ** ** WARNING! All changes made in this file will be lost! From cvs at cvs.gnupg.org Fri Apr 3 17:19:33 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 03 Apr 2009 17:19:33 +0200 Subject: [svn] pinentry - r196 - trunk Message-ID: Author: marcus Date: 2009-04-03 17:19:33 +0200 (Fri, 03 Apr 2009) New Revision: 196 Modified: trunk/ChangeLog trunk/configure.ac Log: 2009-04-03 Marcus Brinkmann * configure.ac: Incorporate revision number in version string. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-03 15:10:22 UTC (rev 195) +++ trunk/ChangeLog 2009-04-03 15:19:33 UTC (rev 196) @@ -1,3 +1,7 @@ +2009-04-03 Marcus Brinkmann + + * configure.ac: Incorporate revision number in version string. + 2009-04-02 Till Adam * qt4/qsecurelineedit.moc, qt4/main.cpp, qt4/pinentrydialog.moc, Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-04-03 15:10:22 UTC (rev 195) +++ trunk/configure.ac 2009-04-03 15:19:33 UTC (rev 196) @@ -22,9 +22,37 @@ AC_PREREQ(2.57) min_automake_version="1.7.6" +# Version number: Remember to change it immediately *after* a release. +# Make sure to run "svn up" and "./autogen.sh --force" +# before a "make dist". See below for the LT versions. +# +# The SVN version is usually the next intended release version with +# the string "-svnNNN" appended. The reason for this is that tests for a +# specific feature can already be done under the assumption that the +# SVN version is the most recent one in a branch. To disable the SVN +# version for the real release, set the my_issvn macro to no. +m4_define(my_version, [1.1.9]) +m4_define(my_issvn, [yes]) + +# Version number: Remember to change it immediately *after* a release. +# Make sure to run "svn up" and "./autogen.sh --force" +# before a "make dist". See below for the LT versions. +# +# The SVN version is usually the next intended release version with +# the string "-svnNNN" appended. The reason for this is that tests for a +# specific feature can already be done under the assumption that the +# SVN version is the most recent one in a branch. To disable the SVN +# version for the real release, set the my_issvn macro to no. +m4_define(my_version, [0.7.6]) +m4_define(my_issvn, [yes]) + +m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ + || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) # Remember to remove the "-cvs" suffix *before* a release and to bump the # version number immediately *after* a release and to re-append the suffix. -AC_INIT(pinentry, 0.7.6-cvs, [gnupg-devel at gnupg.org]) +AC_INIT(pinentry, + [my_version[]m4_if(my_issvn,[yes],[-svn[]svn_revision])], + [gnupg-devel at gnupg.org]) AM_CONFIG_HEADER(config.h) AC_CONFIG_SRCDIR(pinentry/pinentry.h) AM_INIT_AUTOMAKE($PACKAGE_NAME, $PACKAGE_VERSION) From cvs at cvs.gnupg.org Fri Apr 3 17:21:36 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 03 Apr 2009 17:21:36 +0200 Subject: [svn] pinentry - r197 - trunk Message-ID: Author: marcus Date: 2009-04-03 17:21:35 +0200 (Fri, 03 Apr 2009) New Revision: 197 Modified: trunk/configure.ac Log: Fix cut&paste error, doh! Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-04-03 15:19:33 UTC (rev 196) +++ trunk/configure.ac 2009-04-03 15:21:35 UTC (rev 197) @@ -31,18 +31,6 @@ # specific feature can already be done under the assumption that the # SVN version is the most recent one in a branch. To disable the SVN # version for the real release, set the my_issvn macro to no. -m4_define(my_version, [1.1.9]) -m4_define(my_issvn, [yes]) - -# Version number: Remember to change it immediately *after* a release. -# Make sure to run "svn up" and "./autogen.sh --force" -# before a "make dist". See below for the LT versions. -# -# The SVN version is usually the next intended release version with -# the string "-svnNNN" appended. The reason for this is that tests for a -# specific feature can already be done under the assumption that the -# SVN version is the most recent one in a branch. To disable the SVN -# version for the real release, set the my_issvn macro to no. m4_define(my_version, [0.7.6]) m4_define(my_issvn, [yes]) From cvs at cvs.gnupg.org Fri Apr 3 17:35:41 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 03 Apr 2009 17:35:41 +0200 Subject: [svn] pinentry - r198 - in trunk: . qt4 Message-ID: Author: marcus Date: 2009-04-03 17:35:41 +0200 (Fri, 03 Apr 2009) New Revision: 198 Modified: trunk/ChangeLog trunk/qt4/Makefile.am Log: 2009-04-03 Marcus Brinkmann * qt4/Makefile.am (pinentry_qt4_SOURCES): Add pinentrydialog.moc and qsecurelineedit.moc. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-03 15:21:35 UTC (rev 197) +++ trunk/ChangeLog 2009-04-03 15:35:41 UTC (rev 198) @@ -1,5 +1,8 @@ 2009-04-03 Marcus Brinkmann + * qt4/Makefile.am (pinentry_qt4_SOURCES): Add pinentrydialog.moc + and qsecurelineedit.moc. + * configure.ac: Incorporate revision number in version string. 2009-04-02 Till Adam Modified: trunk/qt4/Makefile.am =================================================================== --- trunk/qt4/Makefile.am 2009-04-03 15:21:35 UTC (rev 197) +++ trunk/qt4/Makefile.am 2009-04-03 15:35:41 UTC (rev 198) @@ -39,4 +39,5 @@ $(top_builddir)/secmem/libsecmem.a $(LIBCAP) pinentry_qt4_SOURCES = pinentrydialog.h pinentrydialog.cpp \ - main.cpp secstring.h secstring.cpp qsecurelineedit.h qsecurelineedit.cpp + main.cpp secstring.h secstring.cpp qsecurelineedit.h \ + qsecurelineedit.cpp pinentrydialog.moc qsecurelineedit.moc From cvs at cvs.gnupg.org Fri Apr 3 17:37:16 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 03 Apr 2009 17:37:16 +0200 Subject: [svn] pinentry - r199 - in trunk: . secmem Message-ID: Author: marcus Date: 2009-04-03 17:37:16 +0200 (Fri, 03 Apr 2009) New Revision: 199 Modified: trunk/ChangeLog trunk/secmem/Makefile.am Log: 2009-04-03 Marcus Brinkmann * secmem/Makefile.am (libsecmem_a_SOURCES): Add secmem++.h. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-03 15:35:41 UTC (rev 198) +++ trunk/ChangeLog 2009-04-03 15:37:16 UTC (rev 199) @@ -1,5 +1,6 @@ 2009-04-03 Marcus Brinkmann + * secmem/Makefile.am (libsecmem_a_SOURCES): Add secmem++.h. * qt4/Makefile.am (pinentry_qt4_SOURCES): Add pinentrydialog.moc and qsecurelineedit.moc. Modified: trunk/secmem/Makefile.am =================================================================== --- trunk/secmem/Makefile.am 2009-04-03 15:35:41 UTC (rev 198) +++ trunk/secmem/Makefile.am 2009-04-03 15:37:16 UTC (rev 199) @@ -28,4 +28,5 @@ secmem-util.h \ util.h \ secmem.c \ - util.c + util.c \ + secmem++.h From cvs at cvs.gnupg.org Fri Apr 3 17:42:49 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 03 Apr 2009 17:42:49 +0200 Subject: [svn] pinentry - r200 - in trunk: . qt4 Message-ID: Author: marcus Date: 2009-04-03 17:42:49 +0200 (Fri, 03 Apr 2009) New Revision: 200 Modified: trunk/ChangeLog trunk/qt4/Makefile.am Log: 2009-04-03 Marcus Brinkmann * qt4/Makefile.am (pinentry_qt4_SOURCES): Add qsecurelineedit_p.h. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-03 15:37:16 UTC (rev 199) +++ trunk/ChangeLog 2009-04-03 15:42:49 UTC (rev 200) @@ -1,8 +1,10 @@ 2009-04-03 Marcus Brinkmann + * qt4/Makefile.am (pinentry_qt4_SOURCES): Add qsecurelineedit_p.h. + * secmem/Makefile.am (libsecmem_a_SOURCES): Add secmem++.h. * qt4/Makefile.am (pinentry_qt4_SOURCES): Add pinentrydialog.moc - and qsecurelineedit.moc. + and qsecurelineedit. * configure.ac: Incorporate revision number in version string. Modified: trunk/qt4/Makefile.am =================================================================== --- trunk/qt4/Makefile.am 2009-04-03 15:37:16 UTC (rev 199) +++ trunk/qt4/Makefile.am 2009-04-03 15:42:49 UTC (rev 200) @@ -40,4 +40,5 @@ pinentry_qt4_SOURCES = pinentrydialog.h pinentrydialog.cpp \ main.cpp secstring.h secstring.cpp qsecurelineedit.h \ - qsecurelineedit.cpp pinentrydialog.moc qsecurelineedit.moc + qsecurelineedit.cpp pinentrydialog.moc qsecurelineedit.moc \ + qsecurelineedit_p.h From cvs at cvs.gnupg.org Mon Apr 6 05:18:07 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Mon, 06 Apr 2009 05:18:07 +0200 Subject: [svn] GnuPG - r4982 - in branches/STABLE-BRANCH-1-4: include util Message-ID: Author: dshaw Date: 2009-04-06 05:18:07 +0200 (Mon, 06 Apr 2009) New Revision: 4982 Added: branches/STABLE-BRANCH-1-4/include/srv.h Removed: branches/STABLE-BRANCH-1-4/util/srv.h Modified: branches/STABLE-BRANCH-1-4/include/ChangeLog branches/STABLE-BRANCH-1-4/util/ChangeLog branches/STABLE-BRANCH-1-4/util/http.c Log: * srv.h: Move to include/srv.h. * http.c (send_request): Pass in srvtag... (http_open): ...from here. Modified: branches/STABLE-BRANCH-1-4/include/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/include/ChangeLog 2009-04-03 10:41:33 UTC (rev 4981) +++ branches/STABLE-BRANCH-1-4/include/ChangeLog 2009-04-06 03:18:07 UTC (rev 4982) @@ -1,3 +1,7 @@ +2009-04-05 David Shaw + + * srv.h: Move from util/srv.h. + 2009-04-02 David Shaw * http.h: Allow passing srvtag to http_open and Copied: branches/STABLE-BRANCH-1-4/include/srv.h (from rev 4949, branches/STABLE-BRANCH-1-4/util/srv.h) =================================================================== --- branches/STABLE-BRANCH-1-4/include/srv.h (rev 0) +++ branches/STABLE-BRANCH-1-4/include/srv.h 2009-04-06 03:18:07 UTC (rev 4982) @@ -0,0 +1,49 @@ +/* srv.h + * Copyright (C) 2003, 2004 Free Software Foundation, Inc. + * + * This file is part of GNUPG. + * + * GNUPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GNUPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + +#ifndef _SRV_H_ +#define _SRV_H_ + +#ifdef USE_DNS_SRV +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif /* !_WIN32 */ +#endif /* USE_DNS_SRV */ +#include "types.h" + +#ifndef MAXDNAME +#define MAXDNAME 1025 +#endif + +struct srventry +{ + u16 priority; + u16 weight; + u16 port; + int run_count; + char target[MAXDNAME]; +}; + +int getsrv(const char *name,struct srventry **list); + +#endif /* !_SRV_H_ */ Modified: branches/STABLE-BRANCH-1-4/util/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-04-03 10:41:33 UTC (rev 4981) +++ branches/STABLE-BRANCH-1-4/util/ChangeLog 2009-04-06 03:18:07 UTC (rev 4982) @@ -1,3 +1,10 @@ +2009-04-05 David Shaw + + * srv.h: Move to include/srv.h. + + * http.c (send_request): Pass in srvtag... + (http_open): ...from here. + 2009-04-02 David Shaw * http.c (connect_server): free (rather than xfree) the result of Modified: branches/STABLE-BRANCH-1-4/util/http.c =================================================================== --- branches/STABLE-BRANCH-1-4/util/http.c 2009-04-03 10:41:33 UTC (rev 4981) +++ branches/STABLE-BRANCH-1-4/util/http.c 2009-04-06 03:18:07 UTC (rev 4982) @@ -68,7 +68,8 @@ static int insert_escapes( byte *buffer, const byte *string, const byte *special ); static URI_TUPLE parse_tuple( byte *string ); -static int send_request( HTTP_HD hd, const char *auth, const char *proxy ); +static int send_request( HTTP_HD hd, const char *auth, const char *proxy, + const char *srvtag); static byte *build_rel_path( PARSED_URI uri ); static int parse_response( HTTP_HD hd ); @@ -165,7 +166,7 @@ rc = parse_uri( &hd->uri, url ); if( !rc ) { - rc = send_request( hd, auth, proxy ); + rc = send_request( hd, auth, proxy, srvtag ); if( !rc ) { hd->fp_write = iobuf_sockopen( hd->sock , "w" ); if( hd->fp_write ) @@ -519,7 +520,8 @@ * Returns 0 if the request was successful */ static int -send_request( HTTP_HD hd, const char *auth, const char *proxy ) +send_request( HTTP_HD hd, const char *auth, const char *proxy, + const char *srvtag ) { const byte *server; byte *request, *p; @@ -556,7 +558,7 @@ release_parsed_uri( uri ); } else - hd->sock = connect_server( server, port, hd->flags, hd->uri->scheme ); + hd->sock = connect_server( server, port, hd->flags, srvtag ); if(auth || hd->uri->auth) { Deleted: branches/STABLE-BRANCH-1-4/util/srv.h From cvs at cvs.gnupg.org Mon Apr 6 05:18:30 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Mon, 06 Apr 2009 05:18:30 +0200 Subject: [svn] GnuPG - r4983 - branches/STABLE-BRANCH-1-4/include Message-ID: Author: dshaw Date: 2009-04-06 05:18:30 +0200 (Mon, 06 Apr 2009) New Revision: 4983 Modified: branches/STABLE-BRANCH-1-4/include/distfiles Log: Distribute srv.h Modified: branches/STABLE-BRANCH-1-4/include/distfiles =================================================================== --- branches/STABLE-BRANCH-1-4/include/distfiles 2009-04-06 03:18:07 UTC (rev 4982) +++ branches/STABLE-BRANCH-1-4/include/distfiles 2009-04-06 03:18:30 UTC (rev 4983) @@ -14,5 +14,6 @@ dynload.h assuan.h compat.h +srv.h ChangeLog From cvs at cvs.gnupg.org Mon Apr 6 14:04:59 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 06 Apr 2009 14:04:59 +0200 Subject: [svn] pinentry - r201 - trunk Message-ID: Author: marcus Date: 2009-04-06 14:04:58 +0200 (Mon, 06 Apr 2009) New Revision: 201 Modified: trunk/ChangeLog trunk/configure.ac Log: 2009-04-06 Marcus Brinkmann * configure.ac: Portability fixes. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-03 15:42:49 UTC (rev 200) +++ trunk/ChangeLog 2009-04-06 12:04:58 UTC (rev 201) @@ -1,3 +1,7 @@ +2009-04-06 Marcus Brinkmann + + * configure.ac: Portability fixes. + 2009-04-03 Marcus Brinkmann * qt4/Makefile.am (pinentry_qt4_SOURCES): Add qsecurelineedit_p.h. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2009-04-03 15:42:49 UTC (rev 200) +++ trunk/configure.ac 2009-04-06 12:04:58 UTC (rev 201) @@ -34,8 +34,8 @@ m4_define(my_version, [0.7.6]) m4_define(my_issvn, [yes]) -m4_define([svn_revision], m4_esyscmd([echo -n $( (svn info 2>/dev/null \ - || echo 'Revision: 0')|sed -n '/^Revision:/ {s/[^0-9]//gp;q;}')])) +m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \ + | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)])) # Remember to remove the "-cvs" suffix *before* a release and to bump the # version number immediately *after* a release and to re-append the suffix. AC_INIT(pinentry, From cvs at cvs.gnupg.org Wed Apr 8 20:53:58 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 08 Apr 2009 20:53:58 +0200 Subject: [svn] gpgme - r1362 - in trunk: . assuan src Message-ID: Author: marcus Date: 2009-04-08 20:53:57 +0200 (Wed, 08 Apr 2009) New Revision: 1362 Modified: trunk/TODO trunk/assuan/ChangeLog trunk/assuan/assuan-buffer.c trunk/assuan/assuan-client.c trunk/assuan/assuan-handler.c trunk/assuan/assuan-inquire.c trunk/assuan/assuan-socket.c trunk/assuan/assuan.h trunk/src/ChangeLog trunk/src/engine-assuan.c trunk/src/version.c trunk/src/w32-glib-io.c trunk/src/w32-io.c trunk/src/w32-qt-io.cpp Log: assuan/ 2009-04-08 Marcus Brinkmann * assuan.h (_gpgme_io_socket): New prototype. (_ASSUAN_CUSTOM_IO, _assuan_custom_close, _assuan_custom_read) (_assuan_custom_write, _assuan_custom_pipe, _assuan_custom_socket) (_assuan_custom_connect): New macros. * assuan-socket.c (_assuan_close, _assuan_sock_new) (_assuan_sock_connect) [_ASSUAN_CUSTOM_IO]: Use custom I/O function. * assuan-buffer.c (assuan_read_line): Do not handle EAGAIN anymore. * assuan-client.c (_assuan_read_from_server): Likewise. * assuan-handler.c (process_next): Likewise * assuan-inquire.c (assuan_inquire): Likewise. src/ 2009-04-08 Marcus Brinkmann * w32-glib-io.c (giochannel_table): New members used, fd, socket. (find_channel): Drop CREATE argument. (new_dummy_channel_from_fd, new_channel_from_fd) (new_channel_from_socket): New functions. (_gpgm_io_fd2str): Implement for sockets. (_gpgme_io_write, _gpgme_io_read): Translate EAGAIN errors correctly. (_gpgme_io_pipe): Fix for new channel bookkeeping. (_gpgme_io_close, _gpgme_io_dup): Likewise. (wsa2errno, _gpgme_io_socket, _gpgme_io_connect): New. * w32-io.c (MAX_READERS, MAX_WRITERS): Bump up to 40. (wsa2errno, _gpgme_io_socket, _gpgme_io_connect): New. * w32-qt-io.cpp (_gpgme_io_socket, _gpgme_io_connect): New stubs. * version.c [HAVE_W32_SYSTEM]: Include "windows.h. (do_subsystem_inits) [HAVE_W32_SYSTEM]: Call WSAStartup. * engine-assuan.c (llass_status_handler): Ignore EAGAIN errors. Modified: trunk/assuan/ChangeLog =================================================================== --- trunk/assuan/ChangeLog 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/assuan/ChangeLog 2009-04-08 18:53:57 UTC (rev 1362) @@ -1,3 +1,16 @@ +2009-04-08 Marcus Brinkmann + + * assuan.h (_gpgme_io_socket): New prototype. + (_ASSUAN_CUSTOM_IO, _assuan_custom_close, _assuan_custom_read) + (_assuan_custom_write, _assuan_custom_pipe, _assuan_custom_socket) + (_assuan_custom_connect): New macros. + * assuan-socket.c (_assuan_close, _assuan_sock_new) + (_assuan_sock_connect) [_ASSUAN_CUSTOM_IO]: Use custom I/O function. + * assuan-buffer.c (assuan_read_line): Do not handle EAGAIN anymore. + * assuan-client.c (_assuan_read_from_server): Likewise. + * assuan-handler.c (process_next): Likewise + * assuan-inquire.c (assuan_inquire): Likewise. + 2009-03-23 Marcus Brinkmann * assuan.h: Add prefix macros for _assuan_close and _assuan_usleep. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/src/ChangeLog 2009-04-08 18:53:57 UTC (rev 1362) @@ -1,3 +1,22 @@ +2009-04-08 Marcus Brinkmann + + * w32-glib-io.c (giochannel_table): New members used, fd, socket. + (find_channel): Drop CREATE argument. + (new_dummy_channel_from_fd, new_channel_from_fd) + (new_channel_from_socket): New functions. + (_gpgm_io_fd2str): Implement for sockets. + (_gpgme_io_write, _gpgme_io_read): Translate EAGAIN errors + correctly. + (_gpgme_io_pipe): Fix for new channel bookkeeping. + (_gpgme_io_close, _gpgme_io_dup): Likewise. + (wsa2errno, _gpgme_io_socket, _gpgme_io_connect): New. + * w32-io.c (MAX_READERS, MAX_WRITERS): Bump up to 40. + (wsa2errno, _gpgme_io_socket, _gpgme_io_connect): New. + * w32-qt-io.cpp (_gpgme_io_socket, _gpgme_io_connect): New stubs. + * version.c [HAVE_W32_SYSTEM]: Include "windows.h. + (do_subsystem_inits) [HAVE_W32_SYSTEM]: Call WSAStartup. + * engine-assuan.c (llass_status_handler): Ignore EAGAIN errors. + 2009-03-18 Werner Koch * gpgme.h.in (GPGME_KEYLIST_MODE_EPHEMERAL): New. Modified: trunk/TODO =================================================================== --- trunk/TODO 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/TODO 2009-04-08 18:53:57 UTC (rev 1362) @@ -1,5 +1,12 @@ Hey Emacs, this is -*- outline -*- mode! +* IMPORTANT +** When using descriptor passing, we need to set the fd to blocking before + issueing simple commands, because we are mixing synchronous + commands into potentially asynchronous operations. +** Might want to implement nonblock for w32 native backend! Right now, + we block reading the next line with assuan. + * Before release: ** Figure out if _gpgme_io_pipe should pre-create reader/writer and if we then can use !start_it in most invocations. Note that gpgme_io_dup Modified: trunk/assuan/assuan-buffer.c =================================================================== --- trunk/assuan/assuan-buffer.c 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/assuan/assuan-buffer.c 2009-04-08 18:53:57 UTC (rev 1362) @@ -245,11 +245,7 @@ if (!ctx) return _assuan_error (ASSUAN_Invalid_Value); - do - { - err = _assuan_read_line (ctx); - } - while (_assuan_error_is_eagain (err)); + err = _assuan_read_line (ctx); *line = ctx->inbound.line; *linelen = ctx->inbound.linelen; Modified: trunk/assuan/assuan-client.c =================================================================== --- trunk/assuan/assuan-client.c 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/assuan/assuan-client.c 2009-04-08 18:53:57 UTC (rev 1362) @@ -42,16 +42,12 @@ *off = 0; do { - do - { - rc = _assuan_read_line (ctx); - } - while (_assuan_error_is_eagain (rc)); + rc = _assuan_read_line (ctx); if (rc) return rc; line = ctx->inbound.line; linelen = ctx->inbound.linelen; - } + } while (*line == '#' || !linelen); if (linelen >= 1 Modified: trunk/assuan/assuan-handler.c =================================================================== --- trunk/assuan/assuan-handler.c 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/assuan/assuan-handler.c 2009-04-08 18:53:57 UTC (rev 1362) @@ -630,8 +630,6 @@ required to write full lines without blocking long after starting a partial line. */ rc = _assuan_read_line (ctx); - if (_assuan_error_is_eagain (rc)) - return 0; if (rc) return rc; if (*ctx->inbound.line == '#' || !ctx->inbound.linelen) Modified: trunk/assuan/assuan-inquire.c =================================================================== --- trunk/assuan/assuan-inquire.c 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/assuan/assuan-inquire.c 2009-04-08 18:53:57 UTC (rev 1362) @@ -169,9 +169,7 @@ { do { - do - rc = _assuan_read_line (ctx); - while (_assuan_error_is_eagain (rc)); + rc = _assuan_read_line (ctx); if (rc) goto leave; line = (unsigned char *) ctx->inbound.line; Modified: trunk/assuan/assuan-socket.c =================================================================== --- trunk/assuan/assuan-socket.c 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/assuan/assuan-socket.c 2009-04-08 18:53:57 UTC (rev 1362) @@ -145,7 +145,10 @@ int _assuan_close (assuan_fd_t fd) { -#if defined (HAVE_W32_SYSTEM) && !defined(_ASSUAN_IN_GPGME_BUILD_ASSUAN) +#ifdef _ASSUAN_CUSTOM_IO + return _assuan_custom_close (fd); +#else +#ifdef (HAVE_W32_SYSTEM) int rc = closesocket (HANDLE2SOCKET(fd)); if (rc) errno = _assuan_sock_wsa2errno (WSAGetLastError ()); @@ -160,6 +163,7 @@ #else return close (fd); #endif +#endif } @@ -173,13 +177,25 @@ assuan_fd_t res; if (domain == AF_UNIX || domain == AF_LOCAL) domain = AF_INET; + +#ifdef _ASSUAN_CUSTOM_IO + return _assuan_custom_socket (domain, type, proto); +#else res = SOCKET2HANDLE(socket (domain, type, proto)); if (res == ASSUAN_INVALID_FD) errno = _assuan_sock_wsa2errno (WSAGetLastError ()); return res; +#endif + #else + +#ifdef _ASSUAN_CUSTOM_IO + return _gpgme_io_socket (domain, type, proto); +#else return socket (domain, type, proto); #endif + +#endif } @@ -208,11 +224,18 @@ unaddr->sun_port = myaddr.sin_port; unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr; +#ifdef _ASSUAN_CUSTOM_IO + ret = _assuan_custom_connect (sockfd, + (struct sockaddr *)&myaddr, sizeof myaddr); +#else ret = connect (HANDLE2SOCKET(sockfd), (struct sockaddr *)&myaddr, sizeof myaddr); +#endif + if (!ret) { /* Send the nonce. */ + ret = _assuan_io_write (sockfd, nonce, 16); if (ret >= 0 && ret != 16) { @@ -220,6 +243,8 @@ ret = -1; } } + else + errno = _assuan_sock_wsa2errno (WSAGetLastError ()); return ret; } else @@ -231,8 +256,14 @@ return res; } #else + +#ifdef _ASSUAN_CUSTOM_IO + return _assuan_custom_connect (sockfd, addr, addrlen); +#else return connect (sockfd, addr, addrlen); #endif + +#endif } Modified: trunk/assuan/assuan.h =================================================================== --- trunk/assuan/assuan.h 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/assuan/assuan.h 2009-04-08 18:53:57 UTC (rev 1362) @@ -77,6 +77,7 @@ int _gpgme_io_write (int fd, const void *buffer, size_t count); int _gpgme_io_sendmsg (int sock, const struct msghdr *msg, int flags); int _gpgme_io_recvmsg (int sock, struct msghdr *msg, int flags); +int _gpgme_io_socket (int domain, int type, int proto); #define _assuan_funopen _gpgme_funopen @@ -90,6 +91,15 @@ #define sendmsg _gpgme_io_sendmsg #define recvmsg _gpgme_io_recvmsg #endif /*_ASSUAN_IN_GPGME_BUILD_ASSUAN*/ + +#define _ASSUAN_CUSTOM_IO 1 +#define _assuan_custom_close _gpgme_io_close +#define _assuan_custom_read _gpgme_io_read +#define _assuan_custom_write _gpgme_io_write +#define _assuan_custom_pipe _gpgme_io_pipe +#define _assuan_custom_socket _gpgme_io_socket +#define _assuan_custom_connect _gpgme_io_connect + /**** End GPGME specific modifications. ******/ Modified: trunk/src/engine-assuan.c =================================================================== --- trunk/src/engine-assuan.c 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/src/engine-assuan.c 2009-04-08 18:53:57 UTC (rev 1362) @@ -415,7 +415,18 @@ err = assuan_read_line (llass->assuan_ctx, &line, &linelen); if (err) { - TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass, + /* Reading a full line may not be possible when + communicating over a socket in nonblocking mode. In this + case, we are done for now. */ + if (gpg_err_code (err) == GPG_ERR_EAGAIN) + { + TRACE1 (DEBUG_CTX, "gpgme:llass_status_handler", llass, + "fd 0x%x: EAGAIN reading assuan line (ignored)", fd); + err = 0; + continue; + } + + TRACE2 (DEBUG_CTX, "gpgme:llass_status_handler", llass, "fd 0x%x: error reading assuan line: %s", fd, gpg_strerror (err)); } Modified: trunk/src/version.c =================================================================== --- trunk/src/version.c 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/src/version.c 2009-04-08 18:53:57 UTC (rev 1362) @@ -40,6 +40,10 @@ #include "assuan.h" #endif +#ifdef HAVE_W32_SYSTEM +#include "windows.h" +#endif + /* Bootstrap the subsystems needed for concurrent operation. This must be done once at startup. We can not guarantee this using a @@ -54,6 +58,14 @@ if (done) return; +#ifdef HAVE_W32_SYSTEM + { + WSADATA wsadat; + + WSAStartup (0x202, &wsadat); + } +#endif + _gpgme_sema_subsystem_init (); #ifdef HAVE_ASSUAN_H assuan_set_assuan_err_source (GPG_ERR_SOURCE_GPGME); Modified: trunk/src/w32-glib-io.c =================================================================== --- trunk/src/w32-glib-io.c 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/src/w32-glib-io.c 2009-04-08 18:53:57 UTC (rev 1362) @@ -80,6 +80,13 @@ static struct { + int used; + + /* If this is not -1, then it's a libc file descriptor. */ + int fd; + /* If fd is -1, this is the Windows socket handle. */ + int socket; + GIOChannel *chan; /* The boolean PRIMARY is true if this file descriptor caused the allocation of CHAN. Only then should CHAN be destroyed when this @@ -102,28 +109,104 @@ static GIOChannel * -find_channel (int fd, int create) +find_channel (int fd) { if (fd < 0 || fd >= MAX_SLAFD) return NULL; - if (create && !giochannel_table[fd].chan) + return giochannel_table[fd].chan; +} + + +/* Returns the FD or -1 on resource limit. */ +int +new_dummy_channel_from_fd (int cfd) +{ + int idx; + + for (idx = 0; idx < MAX_SLAFD; idx++) + if (! giochannel_table[idx].used) + break; + + if (idx == MAX_SLAFD) { - giochannel_table[fd].chan = g_io_channel_win32_new_fd (fd); - giochannel_table[fd].primary = 1; - g_io_channel_set_encoding (giochannel_table[fd].chan, NULL, NULL); - g_io_channel_set_buffered (giochannel_table[fd].chan, FALSE); + errno = EIO; + return -1; } - return giochannel_table[fd].chan; + giochannel_table[idx].used = 1; + giochannel_table[idx].chan = NULL; + giochannel_table[idx].fd = cfd; + giochannel_table[idx].socket = INVALID_SOCKET; + giochannel_table[idx].primary = 1; + + return idx; } +/* Returns the FD or -1 on resource limit. */ +int +new_channel_from_fd (int cfd) +{ + int idx; + + for (idx = 0; idx < MAX_SLAFD; idx++) + if (! giochannel_table[idx].used) + break; + + if (idx == MAX_SLAFD) + { + errno = EIO; + return -1; + } + + giochannel_table[idx].used = 1; + giochannel_table[idx].chan = g_io_channel_win32_new_fd (cfd); + giochannel_table[idx].fd = cfd; + giochannel_table[idx].socket = INVALID_SOCKET; + giochannel_table[idx].primary = 1; + + g_io_channel_set_encoding (giochannel_table[idx].chan, NULL, NULL); + g_io_channel_set_buffered (giochannel_table[idx].chan, FALSE); + + return idx; +} + + +/* Returns the FD or -1 on resource limit. */ +int +new_channel_from_socket (int sock) +{ + int idx; + + for (idx = 0; idx < MAX_SLAFD; idx++) + if (! giochannel_table[idx].used) + break; + + if (idx == MAX_SLAFD) + { + errno = EIO; + return -1; + } + + giochannel_table[idx].used = 1; + giochannel_table[idx].chan = g_io_channel_win32_new_socket (sock); + giochannel_table[idx].fd = -1; + giochannel_table[idx].socket = sock; + giochannel_table[idx].primary = 1; + + g_io_channel_set_encoding (giochannel_table[idx].chan, NULL, NULL); + g_io_channel_set_buffered (giochannel_table[idx].chan, FALSE); + + return idx; +} + + /* Compatibility interface. Obsolete. */ void * gpgme_get_giochannel (int fd) { - return find_channel (fd, 0); + return find_channel (fd); } @@ -131,7 +214,7 @@ void * gpgme_get_fdptr (int fd) { - return find_channel (fd, 0); + return find_channel (fd); } @@ -141,9 +224,17 @@ int _gpgme_io_fd2str (char *buf, int buflen, int fd) { + HANDLE hndl; + TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_fd2str", fd, "fd=%d", fd); - TRACE_SUC1 ("syshd=%p", _get_osfhandle (fd)); - return snprintf (buf, buflen, "%d", (int) _get_osfhandle (fd)); + if (giochannel_table[fd].fd != -1) + hndl = (HANDLE) _get_osfhandle (giochannel_table[fd].fd); + else + hndl = (HANDLE) giochannel_table[fd].socket; + + TRACE_SUC1 ("syshd=%p", hndl); + + return snprintf (buf, buflen, "%d", (int) hndl); } @@ -170,7 +261,7 @@ TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_read", fd, "buffer=%p, count=%u", buffer, count); - chan = find_channel (fd, 0); + chan = find_channel (fd); if (!chan) { TRACE_LOG ("no channel registered"); @@ -192,15 +283,21 @@ if (status == G_IO_STATUS_EOF) nread = 0; + else if (status == G_IO_STATUS_AGAIN) + { + nread = -1; + saved_errno = EAGAIN; + } else if (status != G_IO_STATUS_NORMAL) { TRACE_LOG1 ("status %d", status); nread = -1; saved_errno = EIO; } + + if (nread != 0 && nread != -1) + TRACE_LOGBUF (buffer, nread); - TRACE_LOGBUF (buffer, nread); - errno = saved_errno; return TRACE_SYSRES (nread); } @@ -213,11 +310,13 @@ gsize nwritten; GIOChannel *chan; GIOStatus status; + GError *err = NULL; + TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_write", fd, "buffer=%p, count=%u", buffer, count); TRACE_LOGBUF (buffer, count); - chan = find_channel (fd, 0); + chan = find_channel (fd); if (!chan) { TRACE_LOG ("fd %d: no channel registered"); @@ -226,10 +325,21 @@ } status = g_io_channel_write_chars (chan, (gchar *) buffer, count, - &nwritten, NULL); - if (status != G_IO_STATUS_NORMAL) + &nwritten, &err); + if (err) { + TRACE_LOG1 ("write error: %s", err->message); + g_error_free (err); + } + + if (status == G_IO_STATUS_AGAIN) + { nwritten = -1; + saved_errno = EAGAIN; + } + else if (status != G_IO_STATUS_NORMAL) + { + nwritten = -1; saved_errno = EIO; } errno = saved_errno; @@ -241,13 +351,14 @@ int _gpgme_io_pipe (int filedes[2], int inherit_idx) { - GIOChannel *chan; + int fds[2]; + TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_pipe", filedes, "inherit_idx=%i (GPGME uses it for %s)", inherit_idx, inherit_idx ? "reading" : "writing"); #define PIPEBUF_SIZE 4096 - if (_pipe (filedes, PIPEBUF_SIZE, O_NOINHERIT | O_BINARY) == -1) + if (_pipe (fds, PIPEBUF_SIZE, O_NOINHERIT | O_BINARY) == -1) return TRACE_SYSRES (-1); /* Make one end inheritable. */ @@ -255,13 +366,13 @@ { int new_read; - new_read = _dup (filedes[0]); - _close (filedes[0]); - filedes[0] = new_read; + new_read = _dup (fds[0]); + _close (fds[0]); + fds[0] = new_read; if (new_read < 0) { - _close (filedes[1]); + _close (fds[1]); return TRACE_SYSRES (-1); } } @@ -269,33 +380,48 @@ { int new_write; - new_write = _dup (filedes[1]); - _close (filedes[1]); - filedes[1] = new_write; + new_write = _dup (fds[1]); + _close (fds[1]); + fds[1] = new_write; if (new_write < 0) { - _close (filedes[0]); + _close (fds[0]); return TRACE_SYSRES (-1); } } - /* Now we have a pipe with the right end inheritable. The other end + /* For _gpgme_io_close. */ + filedes[inherit_idx] = new_dummy_channel_from_fd (fds[inherit_idx]); + if (filedes[inherit_idx] < 0) + { + int saved_errno = errno; + + _close (fds[0]); + _close (fds[1]); + errno = saved_errno; + return TRACE_SYSRES (-1); + } + + /* Now we have a pipe with the correct end inheritable. The other end should have a giochannel. */ - chan = find_channel (filedes[1 - inherit_idx], 1); - if (!chan) + filedes[1 - inherit_idx] = new_channel_from_fd (fds[1 - inherit_idx]); + if (filedes[1 - inherit_idx] < 0) { int saved_errno = errno; - _close (filedes[0]); - _close (filedes[1]); + + _gpgme_io_close (fds[inherit_idx]); + _close (fds[1 - inherit_idx]); errno = saved_errno; return TRACE_SYSRES (-1); } - + return TRACE_SUC5 ("read=0x%x/%p, write=0x%x/%p, channel=%p", - filedes[0], (HANDLE) _get_osfhandle (filedes[0]), - filedes[1], (HANDLE) _get_osfhandle (filedes[1]), - chan); + filedes[0], + (HANDLE) _get_osfhandle (giochannel_table[filedes[0]].fd), + filedes[1], + (HANDLE) _get_osfhandle (giochannel_table[filedes[1]].fd), + giochannel_table[1 - inherit_idx].chan); } @@ -310,6 +436,8 @@ return TRACE_SYSRES (-1); } + assert (giochannel_table[fd].used); + /* First call the notify handler. */ if (notify_table[fd].handler) { @@ -318,19 +446,26 @@ notify_table[fd].value = NULL; } - /* Then do the close. */ + /* Then do the close. */ if (giochannel_table[fd].chan) { if (giochannel_table[fd].primary) g_io_channel_shutdown (giochannel_table[fd].chan, 1, NULL); - else - _close (fd); - + g_io_channel_unref (giochannel_table[fd].chan); - giochannel_table[fd].chan = NULL; } else - _close (fd); + { + /* Dummy entry, just close. */ + assert (giochannel_table[fd].fd != -1); + _close (giochannel_table[fd].fd); + } + + giochannel_table[fd].used = 0; + giochannel_table[fd].fd = -1; + giochannel_table[fd].socket = INVALID_SOCKET; + giochannel_table[fd].chan = NULL; + giochannel_table[fd].primary = 0; TRACE_SUC (); return 0; @@ -365,16 +500,17 @@ TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_set_nonblocking", fd); - chan = find_channel (fd, 0); + chan = find_channel (fd); if (!chan) { errno = EIO; return TRACE_SYSRES (-1); } - status = g_io_channel_set_flags (chan, + status = g_io_channel_set_flags (chan, g_io_channel_get_flags (chan) | G_IO_FLAG_NONBLOCK, NULL); + if (status != G_IO_STATUS_NORMAL) { #if 0 @@ -549,7 +685,8 @@ HANDLE hd; /* Make it inheritable for the wrapper process. */ - if (!DuplicateHandle (GetCurrentProcess(), _get_osfhandle (fd_list[i].fd), + if (!DuplicateHandle (GetCurrentProcess(), + _get_osfhandle (giochannel_table[fd_list[i].fd].fd), pi.hProcess, &hd, 0, TRUE, DUPLICATE_SAME_ACCESS)) { TRACE_LOG1 ("DuplicateHandle failed: ec=%d", (int) GetLastError ()); @@ -694,7 +831,7 @@ continue; if ((fds[i].for_read || fds[i].for_write) - && !(chan = find_channel (fds[i].fd, 0))) + && !(chan = find_channel (fds[i].fd))) { TRACE_ADD1 (dbg_help, "[BAD0x%x ", fds[i].fd); TRACE_END (dbg_help, "]"); @@ -786,27 +923,147 @@ { int newfd; GIOChannel *chan; - - TRACE_BEG1 (DEBUG_SYSIO, "_gpgme_io_dup", fd, "dup (%d)", fd); - newfd = _dup (fd); - if (newfd == -1) - return TRACE_SYSRES (-1); - if (newfd < 0 || newfd >= MAX_SLAFD) + TRACE_BEG (DEBUG_SYSIO, "_gpgme_io_dup", fd); + + if (fd < 0 || fd >= MAX_SLAFD || !giochannel_table[fd].used) { - /* New FD won't fit into our table. */ - _close (newfd); - errno = EIO; + errno = EINVAL; return TRACE_SYSRES (-1); } - assert (giochannel_table[newfd].chan == NULL); - chan = find_channel (fd, 0); - assert (chan); - + for (newfd = 0; newfd < MAX_SLAFD; newfd++) + if (! giochannel_table[newfd].used) + break; + if (newfd == MAX_SLAFD) + { + errno = EIO; + return TRACE_SYSRES (-1); + } + + chan = giochannel_table[fd].chan; g_io_channel_ref (chan); + giochannel_table[newfd].used = 1; giochannel_table[newfd].chan = chan; + giochannel_table[newfd].fd = -1; + giochannel_table[newfd].socket = INVALID_SOCKET; giochannel_table[newfd].primary = 0; return TRACE_SYSRES (newfd); } + + + + + +static int +wsa2errno (int err) +{ + switch (err) + { + case WSAENOTSOCK: + return EINVAL; + case WSAEWOULDBLOCK: + return EAGAIN; + case ERROR_BROKEN_PIPE: + return EPIPE; + case WSANOTINITIALISED: + return ENOSYS; + default: + return EIO; + } +} + + +int +_gpgme_io_socket (int domain, int type, int proto) +{ + int res; + int fd; + + TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_socket", domain, + "type=%i, protp=%i", type, proto); + + res = socket (domain, type, proto); + if (res == INVALID_SOCKET) + { + errno = wsa2errno (WSAGetLastError ()); + return TRACE_SYSRES (-1); + } + + fd = new_channel_from_socket (res); + if (fd < 0) + { + int saved_errno = errno; + closesocket (res); + errno = saved_errno; + return TRACE_SYSRES (-1); + } + + TRACE_SUC2 ("fd=%i, socket=0x%x", fd, res); + + return fd; +} + + +int +_gpgme_io_connect (int fd, struct sockaddr *addr, int addrlen) +{ + GIOChannel *chan; + int sockfd; + int res; + GIOFlags flags; + GIOStatus status; + GError *err = NULL; + + TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_connect", fd, + "addr=%p, addrlen=%i", addr, addrlen); + + chan = find_channel (fd); + if (! chan) + { + errno = EINVAL; + return TRACE_SYSRES (-1); + } + + flags = g_io_channel_get_flags (chan); + if (flags & G_IO_FLAG_NONBLOCK) + { + status = g_io_channel_set_flags (chan, flags & ~G_IO_FLAG_NONBLOCK, &err); + if (err) + { + TRACE_LOG1 ("setting flags error: %s", err->message); + g_error_free (err); + err = NULL; + } + if (status != G_IO_STATUS_NORMAL) + { + errno = EIO; + return TRACE_SYSRES (-1); + } + } + + sockfd = giochannel_table[fd].socket; + if (sockfd == INVALID_SOCKET) + { + errno = EINVAL; + return TRACE_SYSRES (-1); + } + + TRACE_LOG1 ("connect sockfd=0x%x", sockfd); + res = connect (sockfd, addr, addrlen); + + /* FIXME: Error ignored here. */ + if (! (flags & G_IO_FLAG_NONBLOCK)) + g_io_channel_set_flags (chan, flags, NULL); + + if (res) + { + TRACE_LOG2 ("connect failed: %i %i", res, WSAGetLastError ()); + + errno = wsa2errno (WSAGetLastError ()); + return TRACE_SYSRES (-1); + } + + return TRACE_SUC (); +} Modified: trunk/src/w32-io.c =================================================================== --- trunk/src/w32-io.c 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/src/w32-io.c 2009-04-08 18:53:57 UTC (rev 1362) @@ -53,8 +53,8 @@ #define READBUF_SIZE 4096 #define WRITEBUF_SIZE 4096 #define PIPEBUF_SIZE 4096 -#define MAX_READERS 20 -#define MAX_WRITERS 20 +#define MAX_READERS 40 +#define MAX_WRITERS 40 static struct { @@ -1469,3 +1469,63 @@ { return NULL; } + + +static int +wsa2errno (int err) +{ + switch (err) + { + case WSAENOTSOCK: + return EINVAL; + case WSAEWOULDBLOCK: + return EAGAIN; + case ERROR_BROKEN_PIPE: + return EPIPE; + case WSANOTINITIALISED: + return ENOSYS; + default: + return EIO; + } +} + + +int +_gpgme_io_socket (int domain, int type, int proto) +{ + int res; + + TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_socket", domain, + "type=%i, protp=%i", type, proto); + + res = socket (domain, type, proto); + if (res == INVALID_SOCKET) + { + errno = wsa2errno (WSAGetLastError ()); + return TRACE_SYSRES (-1); + } + + TRACE_SUC1 ("socket=0x%x", res); + + return res; +} + + +int +_gpgme_io_connect (int fd, struct sockaddr *addr, int addrlen) +{ + int sockfd; + int res; + + TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_connect", fd, + "addr=%p, addrlen=%i", addr, addrlen); + + res = connect (sockfd, addr, addrlen); + if (!res) + { + errno = wsa2errno (WSAGetLastError ()); + return TRACE_SYSRES (-1); + } + + return TRACE_SUC (); +} Modified: trunk/src/w32-qt-io.cpp =================================================================== --- trunk/src/w32-qt-io.cpp 2009-03-23 22:23:25 UTC (rev 1361) +++ trunk/src/w32-qt-io.cpp 2009-04-08 18:53:57 UTC (rev 1362) @@ -674,3 +674,20 @@ return fd; } + +extern "C" +int +_gpgme_io_socket (int domain, int type, int proto) +{ + errno = EIO; + return -1; +} + + +extern "C" +int +_gpgme_io_connect (int fd, struct sockaddr *addr, int addrlen) +{ + errno = EIO; + return -1; +} From cvs at cvs.gnupg.org Thu Apr 9 15:42:29 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Thu, 09 Apr 2009 15:42:29 +0200 Subject: [svn] pinentry - r202 - in trunk: . qt4 Message-ID: Author: marcus Date: 2009-04-09 15:42:29 +0200 (Thu, 09 Apr 2009) New Revision: 202 Modified: trunk/ChangeLog trunk/qt4/qsecurelineedit.h Log: 2009-04-09 Marcus Brinkmann * qt4/qsecurelineedit.h (QSecureLineEdit): Don't export. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-06 12:04:58 UTC (rev 201) +++ trunk/ChangeLog 2009-04-09 13:42:29 UTC (rev 202) @@ -1,3 +1,7 @@ +2009-04-09 Marcus Brinkmann + + * qt4/qsecurelineedit.h (QSecureLineEdit): Don't export. + 2009-04-06 Marcus Brinkmann * configure.ac: Portability fixes. Modified: trunk/qt4/qsecurelineedit.h =================================================================== --- trunk/qt4/qsecurelineedit.h 2009-04-06 12:04:58 UTC (rev 201) +++ trunk/qt4/qsecurelineedit.h 2009-04-09 13:42:29 UTC (rev 202) @@ -90,7 +90,7 @@ class QAbstractSpinBox; class QDateTimeEdit; -class Q_GUI_EXPORT QSecureLineEdit : public QWidget +class QSecureLineEdit : public QWidget { Q_OBJECT From cvs at cvs.gnupg.org Tue Apr 14 21:27:15 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 14 Apr 2009 21:27:15 +0200 Subject: [svn] pinentry - r203 - in trunk: . gtk+-2 pinentry Message-ID: Author: marcus Date: 2009-04-14 21:27:15 +0200 (Tue, 14 Apr 2009) New Revision: 203 Modified: trunk/ChangeLog trunk/gtk+-2/pinentry-gtk-2.c trunk/pinentry/pinentry-curses.c trunk/pinentry/pinentry.c trunk/pinentry/pinentry.h Log: 2009-04-14 Marcus Brinkmann * pinentry/pinentry.h (struct pinentry): New member NOTOK. Rename member USER_CLOSED to CANCELED. * pinentry/pinentry.c: Add initializer for NOTOK. (register_commands): Add SETNOTOK. * pinentry/pinentry-curses.c (STRING_NOTOK): New macro. (dialog_pos_t): New value DIALOG_POS_NOTOK. (struct dialog): New members notok, notok_x, notok_y. (dialog_create): Implement NOTOK. (dialog_switch_pos): Likewise. (dialog_run): Likewise. * gtk+-2/pinentry-gtk-2.c: Rename confirm_yes to confirm_value. (confirm_value_t): New type. Use it for confirm_value. (window_closed): Remove. (confirm_button_clicked): Set confirm_value. (create_window): Implement NOTOK. (gtk_cmd_handler): Implement cancel behaviour a bit differently. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-09 13:42:29 UTC (rev 202) +++ trunk/ChangeLog 2009-04-14 19:27:15 UTC (rev 203) @@ -1,3 +1,22 @@ +2009-04-14 Marcus Brinkmann + + * pinentry/pinentry.h (struct pinentry): New member NOTOK. + Rename member USER_CLOSED to CANCELED. + * pinentry/pinentry.c: Add initializer for NOTOK. + (register_commands): Add SETNOTOK. + * pinentry/pinentry-curses.c (STRING_NOTOK): New macro. + (dialog_pos_t): New value DIALOG_POS_NOTOK. + (struct dialog): New members notok, notok_x, notok_y. + (dialog_create): Implement NOTOK. + (dialog_switch_pos): Likewise. + (dialog_run): Likewise. + * gtk+-2/pinentry-gtk-2.c: Rename confirm_yes to confirm_value. + (confirm_value_t): New type. Use it for confirm_value. + (window_closed): Remove. + (confirm_button_clicked): Set confirm_value. + (create_window): Implement NOTOK. + (gtk_cmd_handler): Implement cancel behaviour a bit differently. + 2009-04-09 Marcus Brinkmann * qt4/qsecurelineedit.h (QSecureLineEdit): Don't export. Modified: trunk/gtk+-2/pinentry-gtk-2.c =================================================================== --- trunk/gtk+-2/pinentry-gtk-2.c 2009-04-09 13:42:29 UTC (rev 202) +++ trunk/gtk+-2/pinentry-gtk-2.c 2009-04-14 19:27:15 UTC (rev 203) @@ -53,8 +53,8 @@ static pinentry_t pinentry; static int passphrase_ok; -static int confirm_yes; -static int window_closed; +typedef enum { CONFIRM_CANCEL, CONFIRM_OK, CONFIRM_NOTOK } confirm_value_t; +static confirm_value_t confirm_value; static GtkWidget *entry; static GtkWidget *qualitybar; @@ -150,7 +150,6 @@ static int delete_event (GtkWidget *widget, GdkEvent *event, gpointer data) { - window_closed = 1; gtk_main_quit (); return TRUE; } @@ -193,10 +192,7 @@ static void confirm_button_clicked (GtkWidget *widget, gpointer data) { - if (data) - /* Okay button. */ - confirm_yes = 1; - + confirm_value = (int) data; gtk_main_quit (); } @@ -445,10 +441,24 @@ gtk_container_add (GTK_CONTAINER (bbox), w); g_signal_connect (G_OBJECT (w), "clicked", G_CALLBACK (confirm_mode ? confirm_button_clicked - : button_clicked), NULL); + : button_clicked), + (gpointer) CONFIRM_CANCEL); GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); } + if (confirm_mode && !pinentry->one_button && pinentry->notok) + { + msg = pinentry_utf8_validate (pinentry->notok); + w = gtk_button_new_with_label (msg); + g_free (msg); + + gtk_container_add (GTK_CONTAINER (bbox), w); + g_signal_connect (G_OBJECT (w), "clicked", + G_CALLBACK (confirm_button_clicked), + (gpointer) CONFIRM_NOTOK); + GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); + } + if (pinentry->ok) { msg = pinentry_utf8_validate (pinentry->ok); @@ -471,7 +481,8 @@ else { g_signal_connect (G_OBJECT (w), "clicked", - G_CALLBACK(confirm_button_clicked), "ok"); + G_CALLBACK(confirm_button_clicked), + (gpointer) CONFIRM_OK); GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); } @@ -490,8 +501,7 @@ int want_pass = !!pe->pin; pinentry = pe; - confirm_yes = 0; - window_closed = 0; + confirm_value = CONFIRM_CANCEL; passphrase_ok = 0; w = create_window (want_pass ? 0 : 1); gtk_main (); @@ -499,8 +509,8 @@ while (gtk_events_pending ()) gtk_main_iteration (); - if (window_closed) - pe->user_closed = 1; + if (confirm_value == CONFIRM_CANCEL) + pe->canceled = 1; pinentry = NULL; if (want_pass) @@ -511,7 +521,7 @@ return -1; } else - return confirm_yes; + return (confirm_value == CONFIRM_OK) ? 1 : 0; } Modified: trunk/pinentry/pinentry-curses.c =================================================================== --- trunk/pinentry/pinentry-curses.c 2009-04-09 13:42:29 UTC (rev 202) +++ trunk/pinentry/pinentry-curses.c 2009-04-14 19:27:15 UTC (rev 203) @@ -45,6 +45,7 @@ #include "pinentry.h" #define STRING_OK "" +#define STRING_NOTOK "" #define STRING_CANCEL "" #define USE_COLORS (has_colors () && COLOR_PAIRS >= 2) @@ -58,6 +59,7 @@ DIALOG_POS_NONE, DIALOG_POS_PIN, DIALOG_POS_OK, + DIALOG_POS_NOTOK, DIALOG_POS_CANCEL } dialog_pos_t; @@ -82,6 +84,9 @@ int cancel_y; int cancel_x; char *cancel; + int notok_y; + int notok_x; + char *notok; }; typedef struct dialog *dialog_t; @@ -195,6 +200,10 @@ MAKE_BUTTON (cancel, STRING_CANCEL); else dialog->cancel = NULL; + if (!pinentry->one_button && pinentry->notok) + MAKE_BUTTON (notok, STRING_NOTOK); + else + dialog->notok = NULL; getmaxyx (stdscr, size_y, size_x); @@ -281,13 +290,16 @@ if (new_x > x) x = new_x; } - /* We position the buttons after the first and second third of the - width. Account for rounding. */ - if (x < 2 * strlen (dialog->ok)) - x = 2 * strlen (dialog->ok); + /* We position the buttons after the first, second and third fourth + of the width. Account for rounding. */ + if (x < 3 * strlen (dialog->ok)) + x = 3 * strlen (dialog->ok); if (dialog->cancel) - if (x < 2 * strlen (dialog->cancel)) - x = 2 * strlen (dialog->cancel); + if (x < 3 * strlen (dialog->cancel)) + x = 3 * strlen (dialog->cancel); + if (dialog->notok) + if (x < 3 * strlen (dialog->notok)) + x = 3 * strlen (dialog->notok); /* Add the frame. */ x += 4; @@ -415,19 +427,30 @@ move (ypos, xpos); addch (ACS_VLINE); - if (dialog->cancel) + if (dialog->cancel || dialog->notok) { dialog->ok_y = ypos; /* Calculating the left edge of the left button, rounding down. */ - dialog->ok_x = xpos + 2 + ((x - 4) / 2 - strlen (dialog->ok)) / 2; + dialog->ok_x = xpos + 2 + ((x - 4) / 3 - strlen (dialog->ok)) / 2; move (dialog->ok_y, dialog->ok_x); addstr (dialog->ok); - dialog->cancel_y = ypos; - /* Calculating the left edge of the right button, rounding up. */ - dialog->cancel_x = xpos + x - 2 - ((x - 4) / 2 + strlen (dialog->cancel)) / 2; - move (dialog->cancel_y, dialog->cancel_x); - addstr (dialog->cancel); + if (dialog->notok) + { + dialog->notok_y = ypos; + /* Calculating the left edge of the middle button, rounding up. */ + dialog->notok_x = xpos + x / 2 - strlen (dialog->notok) / 2; + move (dialog->notok_y, dialog->notok_x); + addstr (dialog->notok); + } + if (dialog->cancel) + { + dialog->cancel_y = ypos; + /* Calculating the left edge of the right button, rounding up. */ + dialog->cancel_x = xpos + x - 2 - ((x - 4) / 3 + strlen (dialog->cancel)) / 2; + move (dialog->cancel_y, dialog->cancel_x); + addstr (dialog->cancel); + } } else { @@ -478,6 +501,13 @@ move (diag->ok_y, diag->ok_x); addstr (diag->ok); break; + case DIALOG_POS_NOTOK: + if (diag->notok) + { + move (diag->notok_y, diag->notok_x); + addstr (diag->notok); + } + break; case DIALOG_POS_CANCEL: if (diag->cancel) { @@ -503,6 +533,17 @@ standend (); move (diag->ok_y, diag->ok_x); break; + case DIALOG_POS_NOTOK: + if (diag->notok) + { + set_cursor_state (0); + move (diag->notok_y, diag->notok_x); + standout (); + addstr (diag->notok); + standend (); + move (diag->notok_y, diag->notok_x); + } + break; case DIALOG_POS_CANCEL: if (diag->cancel) { @@ -665,9 +706,15 @@ if (diag.pin) dialog_switch_pos (&diag, DIALOG_POS_PIN); break; - case DIALOG_POS_CANCEL: + case DIALOG_POS_NOTOK: dialog_switch_pos (&diag, DIALOG_POS_OK); break; + case DIALOG_POS_CANCEL: + if (diag.notok) + dialog_switch_pos (&diag, DIALOG_POS_NOTOK); + else + dialog_switch_pos (&diag, DIALOG_POS_OK); + break; default: break; } @@ -681,6 +728,12 @@ dialog_switch_pos (&diag, DIALOG_POS_OK); break; case DIALOG_POS_OK: + if (diag.notok) + dialog_switch_pos (&diag, DIALOG_POS_NOTOK); + else + dialog_switch_pos (&diag, DIALOG_POS_CANCEL); + break; + case DIALOG_POS_NOTOK: dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; default: @@ -695,6 +748,12 @@ dialog_switch_pos (&diag, DIALOG_POS_OK); break; case DIALOG_POS_OK: + if (diag.notok) + dialog_switch_pos (&diag, DIALOG_POS_NOTOK); + else + dialog_switch_pos (&diag, DIALOG_POS_CANCEL); + break; + case DIALOG_POS_NOTOK: dialog_switch_pos (&diag, DIALOG_POS_CANCEL); break; case DIALOG_POS_CANCEL: @@ -719,6 +778,9 @@ case DIALOG_POS_OK: done = 1; break; + case DIALOG_POS_NOTOK: + done = -1; + break; case DIALOG_POS_CANCEL: done = -2; break; @@ -745,7 +807,10 @@ fclose (ttyfo); /* XXX Factor out into dialog_release or something. */ free (diag.ok); - free (diag.cancel); + if (diag.cancel) + free (diag.cancel); + if (diag.notok) + free (diag.notok); if (pinentry->pin) { @@ -761,6 +826,9 @@ } } + if (done == -2) + pinentry->canceled = 1; + return diag.pin ? (done < 0 ? -1 : diag.pin_len) : (done < 0 ? 0 : 1); } Modified: trunk/pinentry/pinentry.c =================================================================== --- trunk/pinentry/pinentry.c 2009-04-09 13:42:29 UTC (rev 202) +++ trunk/pinentry/pinentry.c 2009-04-14 19:27:15 UTC (rev 203) @@ -53,6 +53,7 @@ NULL, /* Error. */ NULL, /* Prompt. */ NULL, /* Ok button. */ + NULL, /* Not-Ok button. */ NULL, /* Cancel button. */ NULL, /* PIN. */ 2048, /* PIN length. */ @@ -67,6 +68,7 @@ 0, /* Parent Window ID. */ NULL, /* Touch file. */ 0, /* Result. */ + 0, /* Result Not-OK. */ 0, /* Locale error flag. */ 0, /* One-button flag. */ NULL, /* Quality-Bar flag and description. */ @@ -730,6 +732,23 @@ static int +cmd_setnotok (ASSUAN_CONTEXT ctx, char *line) +{ + char *newo; + newo = malloc (strlen (line) + 1); + + if (!newo) + return ASSUAN_Out_Of_Core; + + strcpy_escaped (newo, line); + if (pinentry.notok) + free (pinentry.notok); + pinentry.notok = newo; + return 0; +} + + +static int cmd_setcancel (ASSUAN_CONTEXT ctx, char *line) { char *newc; @@ -819,7 +838,6 @@ set_prompt = 1; } pinentry.locale_err = 0; - pinentry.user_closed = 0; pinentry.one_button = 0; pinentry.ctx_assuan = ctx; result = (*pinentry_cmd_handler) (&pinentry); @@ -876,7 +894,7 @@ pinentry.one_button = !!strstr (line, "--one-button"); pinentry.quality_bar = 0; pinentry.locale_err = 0; - pinentry.user_closed = 0; + pinentry.canceled = 0; result = (*pinentry_cmd_handler) (&pinentry); if (pinentry.error) { @@ -888,7 +906,7 @@ : (pinentry.locale_err? ASSUAN_Locale_Problem : (pinentry.one_button ? 0 - : (pinentry.user_closed + : (pinentry.canceled ? ASSUAN_Canceled : ASSUAN_Not_Confirmed))); } @@ -902,7 +920,6 @@ pinentry.one_button = 1; pinentry.quality_bar = 0; pinentry.locale_err = 0; - pinentry.user_closed = 0; result = (*pinentry_cmd_handler) (&pinentry); if (pinentry.error) { @@ -961,6 +978,7 @@ { "SETPROMPT", 0, cmd_setprompt }, { "SETERROR", 0, cmd_seterror }, { "SETOK", 0, cmd_setok }, + { "SETNOTOK", 0, cmd_setnotok }, { "SETCANCEL", 0, cmd_setcancel }, { "GETPIN", 0, cmd_getpin }, { "CONFIRM", 0, cmd_confirm }, Modified: trunk/pinentry/pinentry.h =================================================================== --- trunk/pinentry/pinentry.h 2009-04-09 13:42:29 UTC (rev 202) +++ trunk/pinentry/pinentry.h 2009-04-14 19:27:15 UTC (rev 203) @@ -48,6 +48,8 @@ char *prompt; /* The OK button text to display, or NULL. */ char *ok; + /* The Not-OK button text to display, or NULL. */ + char *notok; /* The Cancel button text to display, or NULL. */ char *cancel; /* The buffer to store the secret into. */ @@ -84,9 +86,8 @@ and to the length of the PIN stored in pin otherwise. */ int result; - /* The user should set this is the pinentry window was closed by the - user without using a button. */ - int user_closed; + /* The user should set this if the NOTOK button was pressed. */ + int canceled; /* The user should set this to true if an error with the local conversion occured. */ From cvs at cvs.gnupg.org Tue Apr 14 22:36:14 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 14 Apr 2009 22:36:14 +0200 Subject: [svn] GnuPG - r4984 - trunk/agent Message-ID: Author: marcus Date: 2009-04-14 22:36:14 +0200 (Tue, 14 Apr 2009) New Revision: 4984 Modified: trunk/agent/ChangeLog trunk/agent/call-pinentry.c Log: 2009-04-14 Marcus Brinkmann * call-pinentry.c (agent_get_confirmation): Try SETNOTOK command with pinentry. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2009-04-06 03:18:30 UTC (rev 4983) +++ trunk/agent/ChangeLog 2009-04-14 20:36:14 UTC (rev 4984) @@ -1,3 +1,8 @@ +2009-04-14 Marcus Brinkmann + + * call-pinentry.c (agent_get_confirmation): Try SETNOTOK command + with pinentry. + 2009-04-01 Werner Koch * protect-tool.c (pe_opt): New. Modified: trunk/agent/call-pinentry.c =================================================================== --- trunk/agent/call-pinentry.c 2009-04-06 03:18:30 UTC (rev 4983) +++ trunk/agent/call-pinentry.c 2009-04-14 20:36:14 UTC (rev 4984) @@ -870,9 +870,15 @@ } if (cancel) { - snprintf (line, DIM(line)-1, "SETCANCEL %s", cancel); + snprintf (line, DIM(line)-1, "SETNOTOK %s", cancel); line[DIM(line)-1] = 0; rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + if (gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD) + { + snprintf (line, DIM(line)-1, "SETCANCEL %s", cancel); + line[DIM(line)-1] = 0; + rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); + } if (rc) return unlock_pinentry (rc); } From cvs at cvs.gnupg.org Wed Apr 15 14:04:22 2009 From: cvs at cvs.gnupg.org (svn author marcus) Date: Wed, 15 Apr 2009 14:04:22 +0200 Subject: [svn] gpgme - r1363 - trunk/src Message-ID: Author: marcus Date: 2009-04-15 14:04:21 +0200 (Wed, 15 Apr 2009) New Revision: 1363 Modified: trunk/src/ChangeLog trunk/src/posix-io.c trunk/src/w32-io.c Log: 2009-04-15 Marcus Brinkmann * posix-io.c (_gpgme_io_socket, _gpgme_io_connect): New functions. * w32-io.c (_gpgme_io_connect): Fix stupid error. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2009-04-08 18:53:57 UTC (rev 1362) +++ trunk/src/ChangeLog 2009-04-15 12:04:21 UTC (rev 1363) @@ -1,3 +1,8 @@ +2009-04-15 Marcus Brinkmann + + * posix-io.c (_gpgme_io_socket, _gpgme_io_connect): New functions. + * w32-io.c (_gpgme_io_connect): Fix stupid error. + 2009-04-08 Marcus Brinkmann * w32-glib-io.c (giochannel_table): New members used, fd, socket. Modified: trunk/src/posix-io.c =================================================================== --- trunk/src/posix-io.c 2009-04-08 18:53:57 UTC (rev 1362) +++ trunk/src/posix-io.c 2009-04-15 12:04:21 UTC (rev 1363) @@ -653,3 +653,31 @@ return new_fd; } + + +int +_gpgme_io_socket (int domain, int type, int proto) +{ + int res; + + TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_socket", domain, + "type=%i, proto=%i", type, proto); + + res = socket (domain, type, proto); + + return TRACE_SYSRES (res); +} + + +int +_gpgme_io_connect (int fd, struct sockaddr *addr, int addrlen) +{ + int res; + + TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_connect", fd, + "addr=%p, addrlen=%i", addr, addrlen); + + res = ath_connect (fd, addr, addrlen); + + return TRACE_SYSRES (res); +} Modified: trunk/src/w32-io.c =================================================================== --- trunk/src/w32-io.c 2009-04-08 18:53:57 UTC (rev 1362) +++ trunk/src/w32-io.c 2009-04-15 12:04:21 UTC (rev 1363) @@ -1514,13 +1514,12 @@ int _gpgme_io_connect (int fd, struct sockaddr *addr, int addrlen) { - int sockfd; int res; TRACE_BEG2 (DEBUG_SYSIO, "_gpgme_io_connect", fd, "addr=%p, addrlen=%i", addr, addrlen); - res = connect (sockfd, addr, addrlen); + res = connect (fd, addr, addrlen); if (!res) { errno = wsa2errno (WSAGetLastError ()); From cvs at cvs.gnupg.org Fri Apr 17 17:01:55 2009 From: cvs at cvs.gnupg.org (cvs user werner) Date: Fri, 17 Apr 2009 17:01:55 +0200 Subject: misc-scripts (5 files) Message-ID: Date: Friday, April 17, 2009 @ 17:01:55 Author: werner Path: /cvs/wk/misc-scripts Added: gpg4win-stats undump.c Modified: ChangeLog rfc822parse.c scrutmime.c Add missing files From cvs at cvs.gnupg.org Fri Apr 17 20:40:33 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 17 Apr 2009 20:40:33 +0200 Subject: [svn] GnuPG - r4985 - trunk/tools Message-ID: Author: wk Date: 2009-04-17 20:40:32 +0200 (Fri, 17 Apr 2009) New Revision: 4985 Added: trunk/tools/ccidmon.c Modified: trunk/tools/ChangeLog trunk/tools/Makefile.am Log: Add a tool to analyze the CCID protocol on the USB bus. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2009-04-14 20:36:14 UTC (rev 4984) +++ trunk/tools/ChangeLog 2009-04-17 18:40:32 UTC (rev 4985) @@ -1,3 +1,7 @@ +2009-04-17 Werner Koch + + * ccidmon.c: New. + 2009-03-03 Werner Koch * gpgconf.c: New command --reload. Modified: trunk/tools/Makefile.am =================================================================== --- trunk/tools/Makefile.am 2009-04-14 20:36:14 UTC (rev 4984) +++ trunk/tools/Makefile.am 2009-04-17 18:40:32 UTC (rev 4985) @@ -19,7 +19,8 @@ EXTRA_DIST = \ Manifest watchgnupg.c \ addgnupghome applygnupgdefaults gpgsm-gencert.sh \ - lspgpot mail-signed-keys convert-from-106 sockprox.c + lspgpot mail-signed-keys convert-from-106 sockprox.c \ + ccidmon.c AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/intl -I$(top_srcdir)/common Added: trunk/tools/ccidmon.c =================================================================== --- trunk/tools/ccidmon.c (rev 0) +++ trunk/tools/ccidmon.c 2009-04-17 18:40:32 UTC (rev 4985) @@ -0,0 +1,789 @@ +/* ccidmon.c - CCID monitor for use with the Linux usbmon facility. + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of GnuPG. + * + * GnuPG is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * GnuPG is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + */ + + +/* This utility takes the output of usbmon, filters out the bulk data + and prints the CCID messages in a human friendly way. + +*/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifndef PACKAGE_VERSION +# define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]" +#endif +#ifndef PACKAGE_BUGREPORT +# define PACKAGE_BUGREPORT "devnull at example.org" +#endif +#define PGM "ccidmon" + +/* Option flags. */ +static int verbose; +static int debug; +static int skip_escape; +static int usb_bus, usb_dev; + +/* Error counter. */ +static int any_error; + +/* Data storage. */ +struct +{ + int is_bi; + char address[50]; + int count; + char data[2000]; +} databuffer; + + +enum { + RDR_to_PC_NotifySlotChange= 0x50, + RDR_to_PC_HardwareError = 0x51, + + PC_to_RDR_SetParameters = 0x61, + PC_to_RDR_IccPowerOn = 0x62, + PC_to_RDR_IccPowerOff = 0x63, + PC_to_RDR_GetSlotStatus = 0x65, + PC_to_RDR_Secure = 0x69, + PC_to_RDR_T0APDU = 0x6a, + PC_to_RDR_Escape = 0x6b, + PC_to_RDR_GetParameters = 0x6c, + PC_to_RDR_ResetParameters = 0x6d, + PC_to_RDR_IccClock = 0x6e, + PC_to_RDR_XfrBlock = 0x6f, + PC_to_RDR_Mechanical = 0x71, + PC_to_RDR_Abort = 0x72, + PC_to_RDR_SetDataRate = 0x73, + + RDR_to_PC_DataBlock = 0x80, + RDR_to_PC_SlotStatus = 0x81, + RDR_to_PC_Parameters = 0x82, + RDR_to_PC_Escape = 0x83, + RDR_to_PC_DataRate = 0x84 +}; + + +#define digitp(p) ((p) >= '0' && (p) <= '9') +#define hexdigitp(a) (digitp (a) \ + || ((a) >= 'A' && (a) <= 'F') \ + || ((a) >= 'a' && (a) <= 'f')) +#define ascii_isspace(a) ((a)==' ' || (a)=='\n' || (a)=='\r' || (a)=='\t') +#define xtoi_1(p) ((p) <= '9'? ((p)- '0'): \ + (p) <= 'F'? ((p)-'A'+10):((p)-'a'+10)) + + + +/* Print diagnostic message and exit with failure. */ +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + putc ('\n', stderr); + + exit (1); +} + + +/* Print diagnostic message. */ +static void +err (const char *format, ...) +{ + va_list arg_ptr; + + any_error = 1; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + putc ('\n', stderr); +} + + +/* Convert a little endian stored 4 byte value into an unsigned + integer. */ +static unsigned int +convert_le_u32 (const unsigned char *buf) +{ + 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 +print_pr_data (const unsigned char *data, size_t datalen, size_t off) +{ + int needlf = 0; + int first = 1; + + for (; off < datalen; off++) + { + if (!(off % 16) || first) + { + if (needlf) + putchar ('\n'); + printf (" [%04d] ", off); + } + printf (" %02X", data[off]); + needlf = 1; + first = 0; + } + if (needlf) + putchar ('\n'); +} + + +static void +print_p2r_header (const char *name, const unsigned char *msg, size_t msglen) +{ + printf ("%s:\n", name); + if (msglen < 7) + return; + printf (" dwLength ..........: %u\n", convert_le_u32 (msg+1)); + printf (" bSlot .............: %u\n", msg[5]); + printf (" 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; + printf (" 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; + printf (" bBWI ..............: 0x%02x\n", msg[7]); + val = convert_le_u16 (msg+8); + printf (" 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; + printf (" bProtocolNum ......: 0x%02x\n", msg[7]); + print_pr_data (msg, msglen, 8); +} + + +static void +print_p2r_escape (const unsigned char *msg, size_t msglen) +{ + if (skip_escape) + return; + 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; + printf (" 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; + printf (" bmChanges .........: 0x%02x\n", msg[7]); + printf (" bClassGetResponse .: 0x%02x\n", msg[8]); + printf (" 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; + printf (" bBMI ..............: 0x%02x\n", msg[7]); + val = convert_le_u16 (msg+8); + printf (" 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; + printf (" 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_p2r (const unsigned char *msg, size_t msglen) +{ + 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; + } +} + + +static void +print_r2p_header (const char *name, const unsigned char *msg, size_t msglen) +{ + printf ("%s:\n", name); + if (msglen < 9) + return; + printf (" dwLength ..........: %u\n", convert_le_u32 (msg+1)); + printf (" bSlot .............: %u\n", msg[5]); + printf (" bSeq ..............: %u\n", msg[6]); + printf (" bStatus ...........: %u\n", msg[7]); + if (msg[8]) + printf (" 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]) + printf (" 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; + printf (" 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; + + printf (" protocol ..........: T=%d\n", msg[9]); + if (msglen == 17 && msg[9] == 1) + { + /* Protocol T=1. */ + printf (" bmFindexDindex ....: %02X\n", msg[10]); + printf (" bmTCCKST1 .........: %02X\n", msg[11]); + printf (" bGuardTimeT1 ......: %02X\n", msg[12]); + printf (" bmWaitingIntegersT1: %02X\n", msg[13]); + printf (" bClockStop ........: %02X\n", msg[14]); + printf (" bIFSC .............: %d\n", msg[15]); + printf (" bNadValue .........: %d\n", msg[16]); + } + else + print_pr_data (msg, msglen, 10); +} + + +static void +print_r2p_escape (const unsigned char *msg, size_t msglen) +{ + if (skip_escape) + return; + print_r2p_header ("RDR_to_PC_Escape", msg, msglen); + if (msglen < 10) + return; + printf (" 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) + { + printf (" dwClockFrequency ..: %u\n", convert_le_u32 (msg+10)); + printf (" 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; + printf (" bMessageType ......: %02X\n", msg[0]); + printf (" buffer[9] .........: %02X\n", msg[9]); + print_pr_data (msg, msglen, 10); +} + + +static void +print_r2p (const unsigned char *msg, size_t msglen) +{ + switch (msglen? msg[0]:0) + { + case RDR_to_PC_DataBlock: + print_r2p_datablock (msg, msglen); + break; + case RDR_to_PC_SlotStatus: + print_r2p_slotstatus (msg, msglen); + break; + case RDR_to_PC_Parameters: + print_r2p_parameters (msg, msglen); + break; + case RDR_to_PC_Escape: + print_r2p_escape (msg, msglen); + break; + case RDR_to_PC_DataRate: + print_r2p_datarate (msg, msglen); + break; + default: + print_r2p_unknown (msg, msglen); + break; + } + +} + + +static void +flush_data (void) +{ + if (!databuffer.count) + return; + + if (verbose) + printf ("Address: %s\n", databuffer.address); + if (databuffer.is_bi) + { + print_r2p (databuffer.data, databuffer.count); + if (verbose) + putchar ('\n'); + } + else + print_p2r (databuffer.data, databuffer.count); + + databuffer.count = 0; +} + +static void +collect_data (char *hexdata, const char *address, unsigned int lineno) +{ + size_t length; + int is_bi; + char *s; + unsigned int value; + + is_bi = (*address && address[1] == 'i'); + + if (databuffer.is_bi != is_bi || strcmp (databuffer.address, address)) + flush_data (); + databuffer.is_bi = is_bi; + if (strlen (address) >= sizeof databuffer.address) + die ("address field too long"); + strcpy (databuffer.address, address); + + length = databuffer.count; + for (s=hexdata; *s; s++ ) + { + if (ascii_isspace (*s)) + continue; + if (!hexdigitp (*s)) + { + err ("invalid hex digit in line %u - line skipped", lineno); + break; + } + value = xtoi_1 (*s) * 16; + s++; + if (!hexdigitp (*s)) + { + err ("invalid hex digit in line %u - line skipped", lineno); + break; + } + value += xtoi_1 (*s); + + if (length >= sizeof (databuffer.data)) + { + err ("too much data at line %u - can handle only up to % bytes", + lineno, sizeof (databuffer.data)); + break; + } + databuffer.data[length++] = value; + } + databuffer.count = length; +} + + +static void +parse_line (char *line, unsigned int lineno) +{ + char *p; + char *event_type, *address, *data, *status, *datatag; + + if (debug) + printf ("line[%u] =`%s'\n", lineno, line); + + p = strtok (line, " "); + if (!p) + die ("invalid line %d (no URB)"); + p = strtok (NULL, " "); + if (!p) + die ("invalid line %d (no timestamp)"); + event_type = strtok (NULL, " "); + if (!event_type) + die ("invalid line %d (no event type)"); + address = strtok (NULL, " "); + if (!address) + die ("invalid line %d (no address"); + if (usb_bus || usb_dev) + { + int bus, dev; + + p = strchr (address, ':'); + if (!p) + die ("invalid line %d (invalid address"); + p++; + bus = atoi (p); + p = strchr (p, ':'); + if (!p) + die ("invalid line %d (invalid address"); + p++; + dev = atoi (p); + + if ((usb_bus && usb_bus != bus) || (usb_dev && usb_dev != dev)) + return; /* We don't want that one. */ + } + if (*address != 'B' || (address[1] != 'o' && address[1] != 'i')) + return; /* We only want block in and block out. */ + status = strtok (NULL, " "); + if (!status) + return; + if (!strchr ("-0123456789", *status)) + return; /* Setup packet. */ + /* We don't support "Z[io]" types thus we don't need to check here. */ + p = strtok (NULL, " "); + if (!p) + return; /* No data length. */ + + datatag = strtok (NULL, " "); + if (datatag && *datatag == '=') + { + data = strtok (NULL, ""); + collect_data (data?data:"", address, lineno); + } +} + + +static void +parse_input (FILE *fp) +{ + char line[2000]; + size_t length; + unsigned int lineno = 0; + + while (fgets (line, sizeof (line), fp)) + { + lineno++; + length = strlen (line); + if (length && line[length - 1] == '\n') + line[--length] = 0; + else + err ("line number %u too long or last line not terminated", lineno); + if (length && line[length - 1] == '\r') + line[--length] = 0; + parse_line (line, lineno); + } + flush_data (); + if (ferror (fp)) + err ("error reading input at line %u: %s", lineno, strerror (errno)); +} + + +int +main (int argc, char **argv) +{ + int last_argc = -1; + + if (argc) + { + argc--; argv++; + } + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--version")) + { + fputs (PGM " (GnuPG) " PACKAGE_VERSION "\n", stdout); + exit (0); + } + else if (!strcmp (*argv, "--help")) + { + puts ("Usage: " PGM " [BUS:DEV]\n" + "Parse the output of usbmod assuming it is CCID compliant.\n\n" + " --skip-escape do not show escape packets\n" + " --verbose enable extra informational output\n" + " --debug enable additional debug output\n" + " --help display this help and exit\n\n" + "Report bugs to " PACKAGE_BUGREPORT "."); + exit (0); + } + else if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--debug")) + { + verbose = debug = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--skip-escape")) + { + skip_escape = 1; + argc--; argv++; + } + } + + if (argc > 1) + die ("usage: " PGM " [BUS:DEV] (try --help for more information)\n"); + + if (argc == 1) + { + const char *s = strchr (argv[0], ':'); + + usb_bus = atoi (argv[0]); + if (s) + usb_dev = atoi (s+1); + if (usb_bus < 1 || usb_bus > 999 || usb_dev < 1 || usb_dev > 999) + die ("invalid bus:dev specified"); + } + + + signal (SIGPIPE, SIG_IGN); + + parse_input (stdin); + + return any_error? 1:0; +} + + +/* +Local Variables: +compile-command: "gcc -Wall -Wno-pointer-sign -g -o ccidmon ccidmon.c" +End: +*/ From cvs at cvs.gnupg.org Sun Apr 19 18:34:21 2009 From: cvs at cvs.gnupg.org (svn author wk) Date: Sun, 19 Apr 2009 18:34:21 +0200 Subject: [svn] GnuPG - r4986 - trunk/tests/openpgp Message-ID: Author: wk Date: 2009-04-19 18:34:21 +0200 (Sun, 19 Apr 2009) New Revision: 4986 Modified: trunk/tests/openpgp/ChangeLog trunk/tests/openpgp/mkdemodirs Log: Fix problem with incompatible gpg.conf files. Modified: trunk/tests/openpgp/ChangeLog =================================================================== --- trunk/tests/openpgp/ChangeLog 2009-04-17 18:40:32 UTC (rev 4985) +++ trunk/tests/openpgp/ChangeLog 2009-04-19 16:34:21 UTC (rev 4986) @@ -1,3 +1,7 @@ +2009-04-19 Werner Koch + + * mkdemodirs (GPG): Use --no-options. + 2008-09-29 Werner Koch * clearsig.test: Replace -sat by --clearsign. Modified: trunk/tests/openpgp/mkdemodirs =================================================================== --- trunk/tests/openpgp/mkdemodirs 2009-04-17 18:40:32 UTC (rev 4985) +++ trunk/tests/openpgp/mkdemodirs 2009-04-19 16:34:21 UTC (rev 4986) @@ -2,7 +2,11 @@ set -e -GPG="../g10/gpg2 --batch --quiet --no-secmem-warning --allow-secret-key-import" +# We need to use --no-options so that a gpg.conf from an older version +# of gpg is not used. +GPG="../g10/gpg2 --no-options --batch --quiet + --no-secmem-warning --allow-secret-key-import" + NAMES='Alpha Bravo Charlie Delta Echo Foxtrot Golf Hotel India Juliet Kilo Lima Mike November Oscar Papa Quebec Romeo Sierra Tango Uniform Victor Whisky XRay Yankee Zulu' From cvs at cvs.gnupg.org Sun Apr 19 20:03:49 2009 From: cvs at cvs.gnupg.org (svn author mo) Date: Sun, 19 Apr 2009 20:03:49 +0200 Subject: [svn] gpgme - r1364 - in trunk: . tests tests/gpg Message-ID: Author: mo Date: 2009-04-19 20:03:49 +0200 (Sun, 19 Apr 2009) New Revision: 1364 Added: trunk/tests/gpg/mkdemodirs.in Removed: trunk/tests/gpg/mkdemodirs Modified: trunk/ChangeLog trunk/Makefile.am trunk/tests/ChangeLog trunk/tests/gpg/Makefile.am Log: * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Specify --with-gpg. * gpg/Makefile.am (EXTRA_DIST): Replaced mkdemodirs with mkdemodirs.in. (mkdemodirs): New target. (clean-local): Added command for removing mkdemodirs script. (./Alpha/Secret.gpg): Added dependency on mkdemodirs. * gpg/mkdemodirs: Renamed to ... * gpg/mkdemodirs.in: ... here. * gpg/mkdemodirs.in (GPG): Derive value from @GPG@ instead of hard-coding "gpg". Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2009-04-15 12:04:21 UTC (rev 1363) +++ trunk/ChangeLog 2009-04-19 18:03:49 UTC (rev 1364) @@ -1,3 +1,7 @@ +2009-04-19 Moritz + + * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Specify --with-gpg. + 2009-03-06 Marcus Brinkmann * assuan/: Update to libassuan SVN 2009-03-06. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2009-04-15 12:04:21 UTC (rev 1363) +++ trunk/tests/ChangeLog 2009-04-19 18:03:49 UTC (rev 1364) @@ -1,3 +1,14 @@ +2009-04-19 Moritz + + * gpg/Makefile.am (EXTRA_DIST): Replaced mkdemodirs with mkdemodirs.in. + (mkdemodirs): New target. + (clean-local): Added command for removing mkdemodirs script. + (./Alpha/Secret.gpg): Added dependency on mkdemodirs. + + * gpg/mkdemodirs: Renamed to ... + * gpg/mkdemodirs.in: ... here. + * gpg/mkdemodirs.in (GPG): Derive value from @GPG@ instead of hard-coding "gpg". + 2009-02-24 Werner Koch * opassuan/t-command.c: Adjust for changed new op_assuan interface. Modified: trunk/Makefile.am =================================================================== --- trunk/Makefile.am 2009-04-15 12:04:21 UTC (rev 1363) +++ trunk/Makefile.am 2009-04-19 18:03:49 UTC (rev 1364) @@ -1,6 +1,6 @@ # Makefile.am - Top level Makefile for GPGME. # Copyright (C) 2000 Werner Koch (dd9jn) -# Copyright (C) 2001, 2002, 2004, 2005, 2008 g10 Code GmbH +# Copyright (C) 2001, 2002, 2004, 2005, 2008, 2009 g10 Code GmbH # # This file is part of GPGME. # @@ -22,6 +22,8 @@ ACLOCAL_AMFLAGS = -I m4 AUTOMAKE_OPTIONS = dist-bzip2 +DISTCHECK_CONFIGURE_FLAGS = --with-gpg="@GPG@" + EXTRA_DIST = gpgme.spec.in autogen.sh if BUILD_ASSUAN Modified: trunk/tests/gpg/Makefile.am =================================================================== --- trunk/tests/gpg/Makefile.am 2009-04-15 12:04:21 UTC (rev 1363) +++ trunk/tests/gpg/Makefile.am 2009-04-19 18:03:49 UTC (rev 1364) @@ -1,5 +1,5 @@ # Copyright (C) 2000 Werner Koch (dd9jn) -# Copyright (C) 2001, 2004, 2005 g10 Code GmbH +# Copyright (C) 2001, 2004, 2005, 2009 g10 Code GmbH # # This file is part of GPGME. # @@ -40,7 +40,7 @@ CLEANFILES = secring.gpg pubring.gpg pubring.kbx trustdb.gpg dirmngr.conf DISTCLEANFILES = pubring.gpg~ pubring.kbx~ random_seed gpg.conf gpg-agent.conf -EXTRA_DIST = mkdemodirs pubdemo.asc secdemo.asc cipher-1.asc cipher-2.asc \ +EXTRA_DIST = mkdemodirs.in pubdemo.asc secdemo.asc cipher-1.asc cipher-2.asc \ geheim.txt pubkey-1.asc seckey-1.asc pinentry INCLUDES = -I$(top_builddir)/src @@ -52,8 +52,13 @@ # We don't run t-genkey in the test suite, because it takes too long noinst_PROGRAMS = $(TESTS) t-genkey +mkdemodirs: mkdemodirs.in Makefile + sed -e 's,[@]GPG[@],$(GPG),g' < $(srcdir)/mkdemodirs.in > mkdemodirs + chmod +x mkdemodirs + clean-local: - $(srcdir)/mkdemodirs --clean + -./mkdemodirs --clean + -rm -f mkdemodirs all-local: ./pubring.gpg ./gpg.conf ./gpg-agent.conf @@ -62,8 +67,8 @@ $(GPG) --homedir . --allow-secret-key-import \ --import Alpha/Secret.gpg Zulu/Secret.gpg -./Alpha/Secret.gpg: secdemo.asc - srcdir=$(srcdir) $(srcdir)/mkdemodirs +./Alpha/Secret.gpg: mkdemodirs secdemo.asc + srcdir=$(srcdir) ./mkdemodirs ./gpg.conf: # This is required for t-sig-notations. Deleted: trunk/tests/gpg/mkdemodirs Copied: trunk/tests/gpg/mkdemodirs.in (from rev 1363, trunk/tests/gpg/mkdemodirs) =================================================================== --- trunk/tests/gpg/mkdemodirs.in (rev 0) +++ trunk/tests/gpg/mkdemodirs.in 2009-04-19 18:03:49 UTC (rev 1364) @@ -0,0 +1,55 @@ +#!/bin/sh +# Copyright (C) 2004 g10 Code GmbH +# +# This file is part of GPGME. +# +# GPGME is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of the +# License, or (at your option) any later version. +# +# GPGME is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General +# Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +set -e + +GPG="@GPG@ --batch --quiet --no-secmem-warning" +NAMES='Alpha Bravo Charlie Delta Echo Foxtrot Golf Hotel India + Juliet Kilo Lima Mike November Oscar Papa Quebec Romeo + Sierra Tango Uniform Victor Whisky XRay Yankee Zulu' + +if [ "$1" = "--clean" ]; then + (for i in $NAMES; do + [ -d $i ] && rm -r $i || true + done) || true + exit 0 +fi + +[ -z "$srcdir" ] && srcdir="../tests" + + +$GPG --dearmor -o secdemo.gpg --yes $srcdir/secdemo.asc +$GPG --dearmor -o pubdemo.gpg --yes $srcdir/pubdemo.asc +[ -f ./tdb.tmp ] && rm ./tdb.tmp +GPGDEMO="$GPG --homedir . --trustdb-name ./tdb.tmp --no-default-keyring + --keyring pubdemo.gpg --secret-keyring secdemo.gpg" +echo -n "Creating:" +for name in $NAMES; do + echo -n " $name" + [ -d $name ] && rm -r $name + mkdir $name + $GPGDEMO --export-secret-key -o - $name > $name/Secret.gpg + $GPG --homedir $name --allow-secret-key-import --import $name/Secret.gpg + $GPGDEMO --export -o - $name > $name/Public.gpg + $GPG --homedir $name --import $name/Public.gpg + [ -f $name/pubring.gpg~ ] && rm $name/pubring.gpg~ +done +echo "." +[ -f ./tdb.tmp ] && rm ./tdb.tmp +rm pubdemo.gpg secdemo.gpg Property changes on: trunk/tests/gpg/mkdemodirs.in ___________________________________________________________________ Name: svn:executable + * Name: svn:keywords + Author Date Id Revision Name: svn:mergeinfo + Name: svn:eol-style + native From cvs at cvs.gnupg.org Tue Apr 21 05:04:08 2009 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Tue, 21 Apr 2009 05:04:08 +0200 Subject: [svn] GnuPG - r4987 - branches/STABLE-BRANCH-1-4/keyserver Message-ID: Author: dshaw Date: 2009-04-21 05:04:08 +0200 (Tue, 21 Apr 2009) New Revision: 4987 Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c Log: * gpgkeys_hkp.c (srv_replace): New function to transform a SRV hostname to a real hostname. (main): Call it from here for the HAVE_LIBCURL case (without libcurl is handled via the curl-shim). Modified: branches/STABLE-BRANCH-1-4/keyserver/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-04-19 16:34:21 UTC (rev 4986) +++ branches/STABLE-BRANCH-1-4/keyserver/ChangeLog 2009-04-21 03:04:08 UTC (rev 4987) @@ -1,3 +1,10 @@ +2009-04-20 David Shaw + + * gpgkeys_hkp.c (srv_replace): New function to transform a SRV + hostname to a real hostname. + (main): Call it from here for the HAVE_LIBCURL case (without + libcurl is handled via the curl-shim). + 2009-04-02 David Shaw * curl-shim.h, curl-shim.c (curl_easy_setopt, curl_easy_perform): Modified: branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c =================================================================== --- branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-04-19 16:34:21 UTC (rev 4986) +++ branches/STABLE-BRANCH-1-4/keyserver/gpgkeys_hkp.c 2009-04-21 03:04:08 UTC (rev 4987) @@ -43,6 +43,9 @@ #else #include "curl-shim.h" #endif +#ifdef USE_DNS_SRV +#include "srv.h" +#endif #include "compat.h" #include "keyserver.h" #include "ksutil.h" @@ -188,6 +191,7 @@ strcat(key,encoded_key); strcpy(request,proto); + strcat(request,"://"); strcat(request,opt->host); strcat(request,":"); strcat(request,port); @@ -252,6 +256,7 @@ } strcpy(request,proto); + strcat(request,"://"); strcat(request,opt->host); strcat(request,":"); strcat(request,port); @@ -330,6 +335,7 @@ fprintf(output,"NAME %s BEGIN\n",getkey); strcpy(request,proto); + strcat(request,"://"); strcat(request,opt->host); strcat(request,":"); strcat(request,port); @@ -413,6 +419,7 @@ fprintf(output,"SEARCH %s BEGIN\n",searchkey); strcpy(request,proto); + strcat(request,"://"); strcat(request,opt->host); strcat(request,":"); strcat(request,port); @@ -483,6 +490,49 @@ } } +/* If there is a SRV record, take the highest ranked possibility. + This is a hack, as we don't proceed downwards. */ +static void +srv_replace(void) +{ +#ifdef USE_DNS_SRV + struct srventry *srvlist=NULL; + int srvcount; + + if(1+strlen(opt->scheme)+6+strlen(opt->host)+1<=MAXDNAME) + { + char srvname[MAXDNAME]; + + strcpy(srvname,"_"); + strcat(srvname,opt->scheme); + strcat(srvname,"._tcp."); + strcat(srvname,opt->host); + srvcount=getsrv(srvname,&srvlist); + } + + if(srvlist) + { + char *newname,*newport; + + newname=strdup(srvlist->target); + newport=malloc(MAX_PORT); + if(newname && newport) + { + free(opt->host); + free(opt->port); + opt->host=newname; + snprintf(newport,MAX_PORT,"%u",srvlist->port); + opt->port=newport; + } + else + { + free(newname); + free(newport); + } + } +#endif +} + static void show_help (FILE *fp) { @@ -495,7 +545,7 @@ int main(int argc,char *argv[]) { - int arg,ret=KEYSERVER_INTERNAL_ERROR; + int arg,ret=KEYSERVER_INTERNAL_ERROR,try_srv=1; char line[MAX_LINE]; int failed=0; struct keylist *keylist=NULL,*keyptr=NULL; @@ -609,15 +659,14 @@ } } } -#if 0 else if(ascii_strcasecmp(start,"try-dns-srv")==0) { if(no) - http_flags&=~HTTP_FLAG_TRY_SRV; + try_srv=0; else - http_flags|=HTTP_FLAG_TRY_SRV; + try_srv=1; } -#endif + continue; } } @@ -632,18 +681,15 @@ if(ascii_strcasecmp(opt->scheme,"hkps")==0) { - proto="https://"; + proto="https"; port="443"; } else { - proto="http://"; + proto="http"; port="11371"; } - if(opt->port) - port=opt->port; - if(!opt->host) { fprintf(console,"gpgkeys: no keyserver host provided\n"); @@ -665,6 +711,26 @@ goto fail; } + /* If the user gives a :port, then disable SRV. The semantics of a + specified port and SRV do not play well together. */ + if(opt->port) + port=opt->port; + else if(try_srv) + { +#ifdef HAVE_LIBCURL + /* We're using libcurl, so fake SRV support via our wrapper. + This isn't as good as true SRV support, as we do not try all + possible targets at one particular level and work our way + down the list, but it's better than nothing. */ + srv_replace(); +#else + /* We're using our internal curl shim, so we can use its (true) + SRV support. Obviously, CURLOPT_SRVTAG_GPG_HACK isn't a real + libcurl option. It's specific to our shim. */ + curl_easy_setopt(curl,CURLOPT_SRVTAG_GPG_HACK,opt->scheme); +#endif + } + curl_easy_setopt(curl,CURLOPT_ERRORBUFFER,errorbuffer); if(opt->auth) @@ -683,13 +749,6 @@ if(proxy) curl_easy_setopt(curl,CURLOPT_PROXY,proxy); -#if 0 - /* By suggested convention, if the user gives a :port, then disable - SRV. */ - if(opt->port) - http_flags&=~HTTP_FLAG_TRY_SRV; -#endif - /* If it's a GET or a SEARCH, the next thing to come in is the keyids. If it's a SEND, then there are no keyids. */