From 29ef9bd0fbd5b4a9c6a166ce9e335957a7d78091 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 9 Jan 2003 13:15:07 +0000 Subject: [PATCH] Updated from latest NewPG project --- assuan/ChangeLog | 33 ++++++++++ assuan/Makefile.am | 3 +- assuan/assuan-buffer.c | 27 +++----- assuan/assuan-defs.h | 9 ++- assuan/assuan-io.c | 60 ++++++++++++++++++ assuan/assuan-pipe-connect.c | 69 ++++++++++---------- assuan/assuan-socket-connect.c | 2 +- assuan/assuan-util.c | 112 +++++++++++++++++++-------------- assuan/assuan.h | 2 - tests/ChangeLog | 16 +++++ tests/Makefile.am | 44 ++++++------- tests/asschk.c | 15 ++++- tests/inittests | 3 + 13 files changed, 266 insertions(+), 129 deletions(-) create mode 100644 assuan/assuan-io.c diff --git a/assuan/ChangeLog b/assuan/ChangeLog index 670f7ef75..85dc5ef8b 100644 --- a/assuan/ChangeLog +++ b/assuan/ChangeLog @@ -1,3 +1,36 @@ +2002-11-10 Werner Koch + + * assuan-pipe-connect.c (assuan_pipe_connect): Changed the order + of the dups to handle cases where we have already used fd 2 for + other things. + +2002-10-31 Neal H. Walfield + + * assuan-util.c: Include . + (_assuan_log_print_buffer): Elide the magic numbers preferring the + standard isfoo functions. Use putc_unlocked where possible. + (_assuan_log_sanitized_string): Rewrite to use putc_unlocked and + the isfoo functions. + +2002-09-05 Neal H. Walfield + + * assuan-defs.h (_assuan_read_wrapper): Depreciated. + * assuan-util.c (_assuan_read_wrapper): Removed. + * assuan-defs.h (_assuan_write_wrapper): Depreciated. + * assuan-util.c (_assuan_write_wrapper): Removed. + * assuan.h (assuan_set_io_fun): Depreciated. + * assuan-util.c (assuan_set_io_fun): Removed. + + * assuan-defs.h (_assuan_read): New function. + (_assuan_write): Likewise. + * assuan-io.c: New file. + + * assuan-buffer.c (writen): Use _assuan_write rather than doing + the work here. + (readline): Likewise for _assuan_read. + + * Makefile.am (libassuan_a_SOURCES): Add assuan-io.c. + 2002-08-16 Werner Koch * assuan.h: Renamed Bad_Certificate_Path to Bad_Certificate_Chain. diff --git a/assuan/Makefile.am b/assuan/Makefile.am index 71560c9e3..2207145cf 100644 --- a/assuan/Makefile.am +++ b/assuan/Makefile.am @@ -42,7 +42,8 @@ libassuan_a_SOURCES = \ assuan-pipe-server.c \ assuan-socket-server.c \ assuan-pipe-connect.c \ - assuan-socket-connect.c + assuan-socket-connect.c \ + assuan-io.c assuan-errors.c : assuan.h diff --git a/assuan/assuan-buffer.c b/assuan/assuan-buffer.c index df5057543..8017183ea 100644 --- a/assuan/assuan-buffer.c +++ b/assuan/assuan-buffer.c @@ -48,9 +48,7 @@ writen ( int fd, const char *buffer, size_t length ) { while (length) { - int nwritten = _assuan_write_wrapper? - _assuan_write_wrapper (fd, buffer, length): - write (fd, buffer, length); + ssize_t nwritten = _assuan_write (fd, buffer, length); if (nwritten < 0) { @@ -75,9 +73,7 @@ readline (int fd, char *buf, size_t buflen, int *r_nread, int *eof) *r_nread = 0; while (nleft > 0) { - int n = _assuan_read_wrapper? - _assuan_read_wrapper (fd, buf, nleft): - read (fd, buf, nleft); + ssize_t n = _assuan_read (fd, buf, nleft); if (n < 0) { @@ -204,13 +200,12 @@ _assuan_read_line (ASSUAN_CONTEXT ctx) /* Read the next line from the client or server and return a pointer - to a buffer with holding that line. linelen returns the length of - the line. This buffer is valid until another read operation is - done on this buffer. The caller is allowed to modify this buffer. - He should only use the buffer if the function returns without an - error. + in *LINE to a buffer holding the line. LINELEN is the length of + *LINE. The buffer is valid until the next read operation on it. + The caller may modify the buffer. The buffer is invalid (i.e. must + not be used) if an error is returned. - Returns: 0 on success or an assuan error code + Returns 0 on success or an assuan error code. See also: assuan_pending_line(). */ AssuanError @@ -228,8 +223,8 @@ assuan_read_line (ASSUAN_CONTEXT ctx, char **line, size_t *linelen) } -/* Return true when a full line is pending for a read, without the need - for actual IO */ +/* Return true if a full line is buffered (i.e. an entire line may be + read without any I/O). */ int assuan_pending_line (ASSUAN_CONTEXT ctx) { @@ -437,7 +432,3 @@ assuan_send_data (ASSUAN_CONTEXT ctx, const void *buffer, size_t length) return 0; } - - - - diff --git a/assuan/assuan-defs.h b/assuan/assuan-defs.h index 3e408b179..f88586925 100644 --- a/assuan/assuan-defs.h +++ b/assuan/assuan-defs.h @@ -121,9 +121,6 @@ AssuanError _assuan_read_from_server (ASSUAN_CONTEXT ctx, int *okay, int *off); /*-- assuan-util.c --*/ -extern ssize_t (*_assuan_read_wrapper)(int,void*,size_t); -extern ssize_t (*_assuan_write_wrapper)(int,const void*,size_t); - void *_assuan_malloc (size_t n); void *_assuan_calloc (size_t n, size_t m); void *_assuan_realloc (void *p, size_t n); @@ -139,6 +136,12 @@ void _assuan_free (void *p); void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length); void _assuan_log_sanitized_string (const char *string); +/*-- assuan-io.c --*/ + +/* Wraps the standard read and write functions to do the Right + Thing depending on our linkage. */ +ssize_t _assuan_read (int fd, void *buffer, size_t size); +ssize_t _assuan_write (int fd, const void *buffer, size_t size); #endif /*ASSUAN_DEFS_H*/ diff --git a/assuan/assuan-io.c b/assuan/assuan-io.c new file mode 100644 index 000000000..135cb02d1 --- /dev/null +++ b/assuan/assuan-io.c @@ -0,0 +1,60 @@ +/* assuan-buffer.c - Wraps the read and write functions. + * Copyright (C) 2002 Free Software Foundation, Inc. + * + * This file is part of Assuan. + * + * Assuan 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. + * + * Assuan 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 + */ + +#include +#include + +extern ssize_t pth_read (int fd, void *buffer, size_t size); +extern ssize_t pth_write (int fd, const void *buffer, size_t size); + +#pragma weak pth_read +#pragma weak pth_write + +ssize_t +_assuan_read (int fd, void *buffer, size_t size) +{ + static ssize_t (*reader) (int, void *, size_t); + + if (! reader) + { + if (pth_read) + reader = pth_read; + else + reader = read; + } + + return reader (fd, buffer, size); +} + +ssize_t +_assuan_write (int fd, const void *buffer, size_t size) +{ + static ssize_t (*writer) (int, const void *, size_t); + + if (! writer) + { + if (pth_write) + writer = pth_write; + else + writer = write; + } + + return writer (fd, buffer, size); +} diff --git a/assuan/assuan-pipe-connect.c b/assuan/assuan-pipe-connect.c index 0cb48ca1a..d7595c9f3 100644 --- a/assuan/assuan-pipe-connect.c +++ b/assuan/assuan-pipe-connect.c @@ -172,25 +172,23 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[], char errbuf[512]; int *fdp; - /* Close all files which will not be duped and are not in the - fd_child_list. */ - n = sysconf (_SC_OPEN_MAX); - if (n < 0) - n = MAX_OPEN_FDS; - for (i=0; i < n; i++) + /* Dup handles to stdin/stdout. */ + if (rp[1] != STDOUT_FILENO) { - fdp = fd_child_list; - if (fdp) - { - while (*fdp != -1 && *fdp != i) - fdp++; - } - - if (!(fdp && *fdp != -1) - && i != rp[1] && i != wp[0]) - close(i); + if (dup2 (rp[1], STDOUT_FILENO) == -1) + { + LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno)); + _exit (4); + } + } + if (wp[0] != STDIN_FILENO) + { + if (dup2 (wp[0], STDIN_FILENO) == -1) + { + LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno)); + _exit (4); + } } - errno = 0; /* Dup stderr to /dev/null unless it is in the list of FDs to be passed to the child. */ @@ -213,28 +211,29 @@ assuan_pipe_connect (ASSUAN_CONTEXT *ctx, const char *name, char *const argv[], LOGERROR1 ("dup2(dev/null, 2) failed: %s\n", strerror (errno)); _exit (4); } - close (fd); } - /* Dup handles and to stdin/stdout and exec. */ - if (rp[1] != STDOUT_FILENO) + + /* Close all files which will not be duped and are not in the + fd_child_list. */ + n = sysconf (_SC_OPEN_MAX); + if (n < 0) + n = MAX_OPEN_FDS; + for (i=0; i < n; i++) { - if (dup2 (rp[1], STDOUT_FILENO) == -1) - { - LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno)); - _exit (4); - } - close (rp[1]); - } - if (wp[0] != STDIN_FILENO) - { - if (dup2 (wp[0], STDIN_FILENO) == -1) - { - LOGERROR1 ("dup2 failed in child: %s\n", strerror (errno)); - _exit (4); - } - close (wp[0]); + if ( i == STDIN_FILENO || i == STDOUT_FILENO || i == STDERR_FILENO) + continue; + fdp = fd_child_list; + if (fdp) + { + while (*fdp != -1 && *fdp != i) + fdp++; + } + + if (!(fdp && *fdp != -1)) + close(i); } + errno = 0; execv (name, argv); /* oops - use the pipe to tell the parent about it */ diff --git a/assuan/assuan-socket-connect.c b/assuan/assuan-socket-connect.c index 53f4a02d0..64a22bf54 100644 --- a/assuan/assuan-socket-connect.c +++ b/assuan/assuan-socket-connect.c @@ -66,7 +66,7 @@ do_deinit (ASSUAN_CONTEXT ctx) /* Make a connection to the Unix domain socket NAME and return a new Assuan context in CTX. SERVER_PID is currently not used but may - becode handy in future. */ + become handy in the future. */ AssuanError assuan_socket_connect (ASSUAN_CONTEXT *r_ctx, const char *name, pid_t server_pid) diff --git a/assuan/assuan-util.c b/assuan/assuan-util.c index a335b09f7..76f7f0650 100644 --- a/assuan/assuan-util.c +++ b/assuan/assuan-util.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "assuan-defs.h" @@ -29,16 +30,10 @@ #include "../jnlib/logging.h" #endif -ssize_t (*_assuan_read_wrapper)(int,void*,size_t) = NULL; -ssize_t (*_assuan_write_wrapper)(int,const void*,size_t) = NULL; - - static void *(*alloc_func)(size_t n) = malloc; static void *(*realloc_func)(void *p, size_t n) = realloc; static void (*free_func)(void*) = free; - - void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), void *(*new_realloc_func)(void *p, size_t n), @@ -77,18 +72,6 @@ _assuan_free (void *p) free_func (p); } -/* For use with Pth it is required to have special read and write - functions. We can't assume an ELF based system so we have to - explicitly set them if we are going to use Pth. */ -void -assuan_set_io_func (ssize_t (*r)(int,void*,size_t), - ssize_t (*w)(int,const void*,size_t)) -{ - _assuan_read_wrapper = r; - _assuan_write_wrapper = w; -} - - /* Store the error in the context so that the error sending function can take out a descriptive text. Inside the assuan code, use the @@ -145,6 +128,8 @@ assuan_end_confidential (ASSUAN_CONTEXT ctx) } } +/* Dump a possibly binary string (used for debugging). Distinguish + ascii text from binary and print it accordingly. */ void _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length) { @@ -152,26 +137,31 @@ _assuan_log_print_buffer (FILE *fp, const void *buffer, size_t length) int n; for (n=length,s=buffer; n; n--, s++) - { - if (*s < ' ' || (*s >= 0x7f && *s <= 0xa0)) - break; - } + if (!isascii (*s) || iscntrl (*s) || !isprint (*s)) + break; + s = buffer; if (!n && *s != '[') fwrite (buffer, length, 1, fp); else { - putc ('[', fp); +#ifdef HAVE_FLOCKFILE + flockfile (fp); +#endif + putc_unlocked ('[', fp); for (n=0; n < length; n++, s++) fprintf (fp, " %02x", *s); - putc (' ', fp); - putc (']', fp); + putc_unlocked (' ', fp); + putc_unlocked (']', fp); +#ifdef HAVE_FUNLOCKFILE + funlockfile (fp); +#endif } } -/* print a user supplied string after filtering out potential bad - characters*/ +/* Log a user supplied string. Escapes non-printable before + printing. */ void _assuan_log_sanitized_string (const char *string) { @@ -182,29 +172,59 @@ _assuan_log_sanitized_string (const char *string) FILE *fp = stderr; #endif + if (! *s) + return; + +#ifdef HAVE_FLOCKFILE + flockfile (fp); +#endif + for (; *s; s++) { - if (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)) - { - putc ('\\', fp); - if (*s == '\n') - putc ('n', fp); - else if (*s == '\r') - putc ('r', fp); - else if (*s == '\f') - putc ('f', fp); - else if (*s == '\v') - putc ('v', fp); - else if (*s == '\b') - putc ('b', fp); - else if (!*s) - putc ('0', fp); - else - fprintf (fp, "x%02x", *s ); + int c = 0; + + switch (*s) + { + case '\r': + c = 'r'; + break; + + case '\n': + c = 'n'; + break; + + case '\f': + c = 'f'; + break; + + case '\v': + c = 'v'; + break; + + case '\b': + c = 'b'; + break; + + default: + if (isascii (*s) && isprint (*s)) + putc_unlocked (*s, fp); + else + { + putc_unlocked ('\\', fp); + fprintf (fp, "x%02x", *s); + } + } + + if (c) + { + putc_unlocked ('\\', fp); + putc_unlocked (c, fp); } - else - putc (*s, fp); } + +#ifdef HAVE_FUNLOCKFILE + funlockfile (fp); +#endif } diff --git a/assuan/assuan.h b/assuan/assuan.h index 51f648a3a..d8b874eb6 100644 --- a/assuan/assuan.h +++ b/assuan/assuan.h @@ -214,8 +214,6 @@ AssuanError assuan_send_data (ASSUAN_CONTEXT ctx, void assuan_set_malloc_hooks ( void *(*new_alloc_func)(size_t n), void *(*new_realloc_func)(void *p, size_t n), void (*new_free_func)(void*) ); -void assuan_set_io_func (ssize_t (*r)(int,void*,size_t), - ssize_t (*w)(int,const void*,size_t)); void assuan_set_log_stream (ASSUAN_CONTEXT ctx, FILE *fp); int assuan_set_error (ASSUAN_CONTEXT ctx, int err, const char *text); void assuan_set_pointer (ASSUAN_CONTEXT ctx, void *pointer); diff --git a/tests/ChangeLog b/tests/ChangeLog index d9ff7eb8f..c6b3b9af1 100644 --- a/tests/ChangeLog +++ b/tests/ChangeLog @@ -1,3 +1,19 @@ +2002-12-04 Werner Koch + + * inittests (gpgsm.conf): Fake system time. + +2002-10-31 Neal H. Walfield + + * Makefile.am (inittests.stamp): Do not set LD_LIBRARY_PATH here. + (TESTS_ENVIRONMENT): Do it here. And also frob $(LIBGCRYPT_LIBS) + and $(PTH_LIBS). + +2002-10-31 Neal H. Walfield + + * asschk.c (die): New macro. + (read_assuan): If in verbose mode, dump the string that was read. + (write_assuan): Be more verbose on failure. + 2002-09-04 Neal H. Walfield * Makefile.am (inittests.stamp): Do not set LD_LIBRARY_PATH, but diff --git a/tests/Makefile.am b/tests/Makefile.am index b2fa56704..622b5fe58 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -22,7 +22,27 @@ GPGSM = ../sm/gpgsm # We can't unset a variable here so we unset GPG_AGENT_INFO in runtest -TESTS_ENVIRONMENT = GNUPGHOME=`pwd` LC_ALL=C GPGSM=$(GPGSM) $(srcdir)/runtest +TESTS_ENVIRONMENT = GNUPGHOME=`pwd` LC_ALL=C GPGSM=$(GPGSM) \ + LD_LIBRARY_PATH=$$(seen=0; \ + for i in $(LDFLAGS) $(LIBGCRYPT_LIBS) $(PTH_LIBS); \ + do \ + if echo "$$i" | egrep '^-L' >/dev/null 2>&1; \ + then \ + if test $$seen = 0; \ + then \ + seen=1; \ + else \ + printf ":"; \ + fi; \ + printf "%s" "$${i}" | sed 's/^-L//'; \ + fi; \ + done; \ + if test $$seen != 0 \ + && test x$${LD_LIBRARY_PATH} != x; \ + then \ + printf ":"; \ + fi; \ + printf "%s" "$${LD_LIBRARY_PATH}") $(srcdir)/runtest testscripts = sm-sign+verify sm-verify @@ -53,26 +73,6 @@ clean-local: srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests --clean inittests.stamp: inittests - LD_LIBRARY_PATH=$$(seen=0; \ - for i in $(LDFLAGS); \ - do \ - if echo "$$i" | egrep '^-L' >/dev/null 2>&1; \ - then \ - if test $$seen = 0; \ - then \ - seen=1; \ - else \ - printf ":"; \ - fi; \ - printf "%s" "$${i}" | sed 's/^-L//'; \ - fi; \ - done; \ - if test $$seen != 0 \ - && test x$${LD_LIBRARY_PATH} != x; \ - then \ - printf ":"; \ - fi; \ - printf "%s" "$${LD_LIBRARY_PATH}") \ - srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests + srcdir=$(srcdir) $(TESTS_ENVIRONMENT) $(srcdir)/inittests echo timestamp >./inittests.stamp diff --git a/tests/asschk.c b/tests/asschk.c index 1a11ead33..83a8ca5af 100644 --- a/tests/asschk.c +++ b/tests/asschk.c @@ -188,6 +188,8 @@ die (const char *format, ...) exit (1); } +#define die(format, args...) (die) ("%s: " format, __FUNCTION__ , ##args) + static void err (const char *format, ...) { @@ -282,6 +284,16 @@ read_assuan (int fd) } else n = read (fd, buf, nleft); + + if (opt_verbose) + { + int i; + printf ("%s: read \"", __FUNCTION__); + for (i = 0; i < n; i ++) + putc (buf[i], stdout); + printf ("\"\n"); + } + if (n < 0) { if (errno == EINTR) @@ -359,7 +371,8 @@ write_assuan (int fd, const char *line) buffer[n++] = '\n'; if (writen (fd, buffer, n)) - die ("sending line to %d failed: %s", fd, strerror (errno)); + die ("sending line (\"%s\") to %d failed: %s", buffer, fd, + strerror (errno)); } diff --git a/tests/inittests b/tests/inittests index b1860f5fd..05a94eb68 100755 --- a/tests/inittests +++ b/tests/inittests @@ -73,10 +73,13 @@ for i in ${private_keys}; do done # Create the configuration scripts +# Note, die to an expired test certificate, we need to use +# the faked system time option. cat > gpgsm.conf < gpg-agent.conf <