From dac70ca2fda12f4fb01eb3f2f33f3831a26c10a0 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Wed, 3 Jun 2009 17:24:24 +0000 Subject: [PATCH] Fixed an fopen problem on Windows Vista. --- agent/ChangeLog | 10 ++++++ agent/protect-tool.c | 22 ++++++------ agent/trustlist.c | 23 ++++++------ common/ChangeLog | 4 +++ common/estream.c | 84 +++++++++++++++++--------------------------- g10/card-util.c | 1 + 6 files changed, 70 insertions(+), 74 deletions(-) diff --git a/agent/ChangeLog b/agent/ChangeLog index 38d264c5a..4cbe8d927 100644 --- a/agent/ChangeLog +++ b/agent/ChangeLog @@ -1,3 +1,13 @@ +2009-06-03 Werner Koch + + * protect-tool.c: Include estream.h. + (store_private_key): Replace stdio streams by estream functions + for a portable use of the "x" mode. + * trustlist.c: Include estream.h. + (agent_marktrusted): Repalce stdio stream by estream functions. + + * protect-tool.c (store_private_key): Use bin2hex. + 2009-06-02 Werner Koch * gpg-agent.c (main): Run pth_kill after fork. Fixes bug#1066. diff --git a/agent/protect-tool.c b/agent/protect-tool.c index d0b68a1fa..58bda715a 100644 --- a/agent/protect-tool.c +++ b/agent/protect-tool.c @@ -44,6 +44,7 @@ #include "i18n.h" #include "get-passphrase.h" #include "sysutils.h" +#include "estream.h" enum cmd_and_opt_values @@ -1199,18 +1200,15 @@ static int store_private_key (const unsigned char *grip, const void *buffer, size_t length, int force) { - int i; char *fname; - FILE *fp; + estream_t fp; char hexgrip[40+4+1]; - for (i=0; i < 20; i++) - sprintf (hexgrip+2*i, "%02X", grip[i]); - strcpy (hexgrip+40, ".key"); + bin2hex (grip, 20, hexgrip); fname = make_filename (opt_homedir, GNUPG_PRIVATE_KEYS_DIR, hexgrip, NULL); if (force) - fp = fopen (fname, "wb"); + fp = es_fopen (fname, "wb"); else { if (!access (fname, F_OK)) @@ -1224,9 +1222,9 @@ store_private_key (const unsigned char *grip, xfree (fname); return opt_no_fail_on_exist? 0 : -1; } - fp = fopen (fname, "wbx"); /* FIXME: the x is a GNU extension - let - configure check whether this actually - works */ + /* FWIW: Under Windows Vista the standard fopen in the msvcrt + fails if the "x" GNU extension is used. */ + fp = es_fopen (fname, "wbx"); } if (!fp) @@ -1236,15 +1234,15 @@ store_private_key (const unsigned char *grip, return -1; } - if (fwrite (buffer, length, 1, fp) != 1) + if (es_fwrite (buffer, length, 1, fp) != 1) { log_error ("error writing `%s': %s\n", fname, strerror (errno)); - fclose (fp); + es_fclose (fp); remove (fname); xfree (fname); return -1; } - if ( fclose (fp) ) + if (es_fclose (fp)) { log_error ("error closing `%s': %s\n", fname, strerror (errno)); remove (fname); diff --git a/agent/trustlist.c b/agent/trustlist.c index 5fd364cc6..afb941412 100644 --- a/agent/trustlist.c +++ b/agent/trustlist.c @@ -31,6 +31,7 @@ #include "agent.h" #include /* fixme: need a way to avoid assuan calls here */ #include "i18n.h" +#include "estream.h" /* A structure to store the information from the trust file. */ @@ -552,7 +553,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag) gpg_error_t err = 0; char *desc; char *fname; - FILE *fp; + estream_t fp; char *fprformatted; char *nameformatted; int is_disabled; @@ -691,7 +692,7 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag) fname = make_filename (opt.homedir, "trustlist.txt", NULL); if ( access (fname, F_OK) && errno == ENOENT) { - fp = fopen (fname, "wx"); /* Warning: "x" is a GNU extension. */ + fp = es_fopen (fname, "wx"); if (!fp) { err = gpg_error_from_syserror (); @@ -702,10 +703,10 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag) xfree (nameformatted); return err; } - fputs (headerblurb, fp); - fclose (fp); + es_fputs (headerblurb, fp); + es_fclose (fp); } - fp = fopen (fname, "a+"); + fp = es_fopen (fname, "a+"); if (!fp) { err = gpg_error_from_syserror (); @@ -718,22 +719,22 @@ agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag) } /* Append the key. */ - fputs ("\n# ", fp); + es_fputs ("\n# ", fp); xfree (nameformatted); nameformatted = reformat_name (name, "\n# "); if (!nameformatted || strchr (name, '\n')) { /* Note that there should never be a LF in NAME but we better play safe and print a sanitized version in this case. */ - print_sanitized_string (fp, name, 0); + es_write_sanitized (fp, name, strlen (name), NULL, NULL); } else - fputs (nameformatted, fp); - fprintf (fp, "\n%s%s %c\n", yes_i_trust?"":"!", fprformatted, flag); - if (ferror (fp)) + es_fputs (nameformatted, fp); + es_fprintf (fp, "\n%s%s %c\n", yes_i_trust?"":"!", fprformatted, flag); + if (es_ferror (fp)) err = gpg_error_from_syserror (); - if (fclose (fp)) + if (es_fclose (fp)) err = gpg_error_from_syserror (); agent_reload_trustlist (); diff --git a/common/ChangeLog b/common/ChangeLog index 2f5a65a03..50669612e 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,7 @@ +2009-06-03 Werner Koch + + * estream.c (es_convert_mode): Rewrite and support the "x" flag. + 2009-05-28 David Shaw From 1.4: diff --git a/common/estream.c b/common/estream.c index ee6c51af8..214c2ff7d 100644 --- a/common/estream.c +++ b/common/estream.c @@ -897,67 +897,49 @@ static es_cookie_io_functions_t estream_functions_file = }; - -/* Stream primitives. */ - static int es_convert_mode (const char *mode, unsigned int *modeflags) { + unsigned int omode, oflags; - /* FIXME: We need to allow all mode flags permutations. */ - struct - { - const char *mode; - unsigned int flags; - } mode_flags[] = { { "r", - O_RDONLY }, - { "rb", - O_RDONLY | O_BINARY }, - { "w", - O_WRONLY | O_TRUNC | O_CREAT }, - { "wb", - O_WRONLY | O_TRUNC | O_CREAT | O_BINARY }, - { "a", - O_WRONLY | O_APPEND | O_CREAT }, - { "ab", - O_WRONLY | O_APPEND | O_CREAT | O_BINARY }, - { "r+", - O_RDWR }, - { "rb+", - O_RDWR | O_BINARY }, - { "r+b", - O_RDONLY | O_WRONLY | O_BINARY }, - { "w+", - O_RDWR | O_TRUNC | O_CREAT }, - { "wb+", - O_RDWR | O_TRUNC | O_CREAT | O_BINARY }, - { "w+b", - O_RDWR | O_TRUNC | O_CREAT | O_BINARY }, - { "a+", - O_RDWR | O_CREAT | O_APPEND }, - { "ab+", - O_RDWR | O_CREAT | O_APPEND | O_BINARY }, - { "a+b", - O_RDWR | O_CREAT | O_APPEND | O_BINARY } - }; - unsigned int i; - int err; - - for (i = 0; i < DIM (mode_flags); i++) - if (! strcmp (mode_flags[i].mode, mode)) + switch (*mode) + { + case 'r': + omode = O_RDONLY; + oflags = 0; break; - if (i == DIM (mode_flags)) - { + case 'w': + omode = O_WRONLY; + oflags = O_TRUNC | O_CREAT; + break; + case 'a': + omode = O_WRONLY; + oflags = O_APPEND | O_CREAT; + break; + default: errno = EINVAL; - err = -1; + return -1; } - else + for (mode++; *mode; mode++) { - err = 0; - *modeflags = mode_flags[i].flags; + switch (*mode) + { + case '+': + omode = O_RDWR; + break; + case 'b': + oflags |= O_BINARY; + break; + case 'x': + oflags |= O_EXCL; + break; + default: /* Ignore unknown flags. */ + break; + } } - return err; + *modeflags = (omode | oflags); + return 0; } diff --git a/g10/card-util.c b/g10/card-util.c index e12e4a7a1..b696144b0 100644 --- a/g10/card-util.c +++ b/g10/card-util.c @@ -195,6 +195,7 @@ get_manufacturer (unsigned int no) case 0x0004: return "Wewid AB"; case 0x0005: return "ZeitControl"; + case 0x002A: return "Magrathea"; /* 0x00000 and 0xFFFF are defined as test cards per spec, 0xFFF00 to 0xFFFE are assigned for use with randomly created serial numbers. */