From cvs at cvs.gnupg.org Tue Jun 5 16:47:50 2007 From: cvs at cvs.gnupg.org (svn author marcus) Date: Tue, 05 Jun 2007 16:47:50 +0200 Subject: [svn] gpgme - r1217 - trunk/doc Message-ID: Author: marcus Date: 2007-06-05 16:47:18 +0200 (Tue, 05 Jun 2007) New Revision: 1217 Modified: trunk/doc/ChangeLog trunk/doc/gpgme.texi Log: 2007-06-05 Marcus Brinkmann * gpgme.texi (Advanced Key Editing): New section. Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2007-05-18 22:30:42 UTC (rev 1216) +++ trunk/doc/ChangeLog 2007-06-05 14:47:18 UTC (rev 1217) @@ -1,3 +1,7 @@ +2007-06-05 Marcus Brinkmann + + * gpgme.texi (Advanced Key Editing): New section. + 2007-05-18 Marcus Brinkmann * gpgme.texi (Error Strings): Fix documentation of Modified: trunk/doc/gpgme.texi =================================================================== --- trunk/doc/gpgme.texi 2007-05-18 22:30:42 UTC (rev 1216) +++ trunk/doc/gpgme.texi 2007-06-05 14:47:18 UTC (rev 1217) @@ -1,4 +1,4 @@ -\input texinfo @c -*- Texinfo -*- +()\input texinfo @c -*- Texinfo -*- @setfilename gpgme.info @settitle The `GnuPG Made Easy' Reference Manual @@ -190,6 +190,7 @@ * Exporting Keys:: Retrieving key data from the key ring. * Importing Keys:: Adding keys to the key ring. * Deleting Keys:: Removing keys from the key ring. +* Advanced Key Editing:: Advanced key edit operation. Trust Item Management @@ -2617,6 +2618,7 @@ * Exporting Keys:: Retrieving key data from the key ring. * Importing Keys:: Adding keys to the key ring. * Deleting Keys:: Removing keys from the key ring. +* Advanced Key Editing:: Advanced key edit operation. @end menu @@ -3492,6 +3494,68 @@ @end deftypefun + at node Advanced Key Editing + at subsection Advanced Key Editing + at cindex key, edit + + at deftp {Data type} {gpgme_error_t (*gpgme_edit_cb_t) (@w{void *@var{handle}}, @w{gpgme_status_code_t @var{status}}, @w{const char *@var{args}}, @w{int @var{fd}})} + at tindex gpgme_edit_cb_t +The @code{gpgme_edit_cb_t} type is the type of functions which + at acronym{GPGME} calls if it a key edit operation is on-going. The +status code @var{status} and the argument line @var{args} are passed +through by @acronym{GPGME} from the crypto engine. The file +descriptor @var{fd} is -1 for normal status messages. If @var{status} +indicates a command rather than a status message, the response to the +command should be written to @var{fd}. The @var{handle} is provided +by the user at start of operation. + +The function should return @code{GPG_ERR_NO_ERROR} or an error value. + at end deftp + + at deftypefun gpgme_error_t gpgme_op_edit (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{key}}, @w{gpgme_edit_cb_t @var{fnc}}, @w{void *@var{handle}}, @w{gpgme_data_t @var{out}}) +The function @code{gpgme_op_edit} processes the key @var{KEY} +interactively, using the edit callback function @var{FNC} with the +handle @var{HANDLE}. The callback is invoked for every status and +command request from the crypto engine. The output of the crypto +engine is written to the data object @var{out}. + +Note that the protocol between the callback function and the crypto +engine is specific to the crypto engine and no further support in +implementing this protocol correctly is provided by @acronym{GPGME}. + +The function returns the error code @code{GPG_ERR_NO_ERROR} if the +edit operation completes successfully, @code{GPG_ERR_INV_VALUE} if + at var{ctx} or @var{key} is not a valid pointer, and any error returned +by the crypto engine or the edit callback handler. + at end deftypefun + + at deftypefun gpgme_error_t gpgme_op_edit_start (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{key}}, @w{gpgme_edit_cb_t @var{fnc}}, @w{void *@var{handle}}, @w{gpgme_data_t @var{out}}) +The function @code{gpgme_op_edit_start} initiates a + at code{gpgme_op_edit} operation. It can be completed by calling + at code{gpgme_wait} on the context. @xref{Waiting For Completion}. + +The function returns the error code @code{GPG_ERR_NO_ERROR} if the +operation was started successfully, and @code{GPG_ERR_INV_VALUE} if + at var{ctx} or @var{key} is not a valid pointer. + at end deftypefun + + + at deftypefun gpgme_error_t gpgme_op_card_edit (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{key}}, @w{gpgme_edit_cb_t @var{fnc}}, @w{void *@var{handle}}, @w{gpgme_data_t @var{out}}) +The function @code{gpgme_op_card_edit} is analogous to + at code{gpgme_op_edit}, but should be used to process the smart card corresponding to the key @var{key}. + at end deftypefun + + at deftypefun gpgme_error_t gpgme_op_card_edit_start (@w{gpgme_ctx_t @var{ctx}}, @w{gpgme_key_t @var{key}}, @w{gpgme_edit_cb_t @var{fnc}}, @w{void *@var{handle}}, @w{gpgme_data_t @var{out}}) +The function @code{gpgme_op_card_edit_start} initiates a + at code{gpgme_op_card_edit} operation. It can be completed by calling + at code{gpgme_wait} on the context. @xref{Waiting For Completion}. + +The function returns the error code @code{GPG_ERR_NO_ERROR} if the +operation was started successfully, and @code{GPG_ERR_INV_VALUE} if + at var{ctx} or @var{key} is not a valid pointer. + at end deftypefun + + @node Trust Item Management @section Trust Item Management @cindex trust item From cvs at cvs.gnupg.org Wed Jun 6 19:02:26 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 06 Jun 2007 19:02:26 +0200 Subject: [svn] gcry - r1255 - trunk/src Message-ID: Author: wk Date: 2007-06-06 19:01:56 +0200 (Wed, 06 Jun 2007) New Revision: 1255 Modified: trunk/src/ChangeLog trunk/src/gcrypt.h.in Log: Pth fix for W32. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2007-05-31 09:48:05 UTC (rev 1254) +++ trunk/src/ChangeLog 2007-06-06 17:01:56 UTC (rev 1255) @@ -1,3 +1,9 @@ +2007-06-06 Werner Koch + + * gcrypt.h.in (GCRY_THREAD_OPTION_PTH_IMPL): Factror network + related code out so that the prototypes can be adjusted for W32. + (_GCRY_THREAD_OPTION_PTH_IMPL_NET): New. + 2007-05-09 Werner Koch * libgcrypt.m4: Print found version on success. Modified: trunk/src/gcrypt.h.in =================================================================== --- trunk/src/gcrypt.h.in 2007-05-31 09:48:05 UTC (rev 1254) +++ trunk/src/gcrypt.h.in 2007-06-06 17:01:56 UTC (rev 1255) @@ -210,6 +210,36 @@ #endif }; +#ifdef _WIN32 +# define _GCRY_THREAD_OPTION_PTH_IMPL_NET \ +static ssize_t gcry_pth_select (int nfd, void *rset, void *wset, \ + void *eset, struct timeval *timeout) \ + { return pth_select (nfd, rset, wset, eset, timeout); } \ +static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options) \ + { return pth_waitpid (pid, status, options); } \ +static int gcry_pth_accept (int s, void *addr, \ + gcry_socklen_t *length_ptr) \ + { return pth_accept (s, addr, length_ptr); } \ +static int gcry_pth_connect (int s, void *addr, \ + gcry_socklen_t length) \ + { return pth_connect (s, addr, length); } +#else /*!_WIN32*/ +# define _GCRY_THREAD_OPTION_PTH_IMPL_NET \ +static ssize_t gcry_pth_select (int nfd, fd_set *rset, fd_set *wset, \ + fd_set *eset, struct timeval *timeout) \ + { return pth_select (nfd, rset, wset, eset, timeout); } \ +static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options) \ + { return pth_waitpid (pid, status, options); } \ +static int gcry_pth_accept (int s, struct sockaddr *addr, \ + gcry_socklen_t *length_ptr) \ + { return pth_accept (s, addr, length_ptr); } \ +static int gcry_pth_connect (int s, struct sockaddr *addr, \ + gcry_socklen_t length) \ + { return pth_connect (s, addr, length); } +#endif /*!_WIN32*/ + + + #define GCRY_THREAD_OPTION_PTH_IMPL \ static int gcry_pth_init (void) \ { return (pth_init () == FALSE) ? errno : 0; } \ @@ -246,17 +276,7 @@ { return pth_read (fd, buf, nbytes); } \ static ssize_t gcry_pth_write (int fd, const void *buf, size_t nbytes) \ { return pth_write (fd, buf, nbytes); } \ -static ssize_t gcry_pth_select (int nfd, fd_set *rset, fd_set *wset, \ - fd_set *eset, struct timeval *timeout) \ - { return pth_select (nfd, rset, wset, eset, timeout); } \ -static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options) \ - { return pth_waitpid (pid, status, options); } \ -static int gcry_pth_accept (int s, struct sockaddr *addr, \ - gcry_socklen_t *length_ptr) \ - { return pth_accept (s, addr, length_ptr); } \ -static int gcry_pth_connect (int s, struct sockaddr *addr, \ - gcry_socklen_t length) \ - { return pth_connect (s, addr, length); } \ +_GCRY_THREAD_OPTION_PTH_IMPL_NET \ \ /* FIXME: GNU Pth is missing pth_sendmsg and pth_recvmsg. */ \ static struct gcry_thread_cbs gcry_threads_pth = { GCRY_THREAD_OPTION_PTH, \ @@ -265,6 +285,7 @@ gcry_pth_select, gcry_pth_waitpid, gcry_pth_accept, gcry_pth_connect, \ NULL, NULL } + #define GCRY_THREAD_OPTION_PTHREAD_IMPL \ static int gcry_pthread_mutex_init (void **priv) \ { \ From cvs at cvs.gnupg.org Fri Jun 8 19:38:42 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 08 Jun 2007 19:38:42 +0200 Subject: [svn] GnuPG - r4509 - trunk/g10 Message-ID: Author: wk Date: 2007-06-08 19:38:13 +0200 (Fri, 08 Jun 2007) New Revision: 4509 Modified: trunk/g10/ChangeLog trunk/g10/Makefile.am Log: Syntax fix - should build now - however not tested. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2007-06-06 18:12:30 UTC (rev 4508) +++ trunk/g10/ChangeLog 2007-06-08 17:38:13 UTC (rev 4509) @@ -1,3 +1,7 @@ +2007-06-08 Werner Koch + + * Makefile.am (gpg2_LDADD): Syntax fix. + 2007-06-06 Werner Koch * passphrase.c (passphrase_get) [!ENABLE_NLS]: Do not define Modified: trunk/g10/Makefile.am =================================================================== --- trunk/g10/Makefile.am 2007-06-06 18:12:30 UTC (rev 4508) +++ trunk/g10/Makefile.am 2007-06-08 17:38:13 UTC (rev 4509) @@ -119,7 +119,7 @@ LDADD = $(needed_libs) ../common/libgpgrl.a \ $(ZLIBS) $(DNSLIBS) $(LIBREADLINE) \ $(LIBINTL) $(CAPLIBS) $(NETLIBS) -gpg2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS)$(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ +gpg2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ $(LIBICONV) gpgv2_LDADD = $(LDADD) $(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) $(GPG_ERROR_LIBS) \ $(LIBICONV) From cvs at cvs.gnupg.org Tue Jun 12 15:40:11 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 12 Jun 2007 15:40:11 +0200 Subject: [svn] assuan - r238 - in trunk: . m4 src Message-ID: Author: wk Date: 2007-06-12 15:39:37 +0200 (Tue, 12 Jun 2007) New Revision: 238 Modified: trunk/ChangeLog trunk/autogen.sh trunk/configure.ac trunk/m4/gnupg-pth.m4 trunk/src/ChangeLog trunk/src/assuan-connect.c trunk/src/assuan-defs.h trunk/src/assuan-io-pth.c trunk/src/assuan-io.c trunk/src/assuan-pipe-connect.c trunk/src/assuan-pipe-server.c trunk/src/assuan-socket-server.c trunk/src/assuan.h trunk/src/libassuan.m4 Log: Various minor changes for W32 Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/ChangeLog 2007-06-12 13:39:37 UTC (rev 238) @@ -1,3 +1,17 @@ +2007-05-30 Werner Koch + + * autogen.sh <--build-w32>: Modernize. + +2007-05-29 Werner Koch + + * configure.ac: Require automake 1.10 and autoconf 2.61. + (AM_PROG_CC_C_O): New. Error out if no C-89 cc is installed. + (gl_HEADER_SYS_SOCKET): Explicitly add this for documentation. + +2007-05-24 Werner Koch + + * configure.ac: Use -Wpointer-arith is possible. + 2006-11-22 Werner Koch Released 1.0.1. Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/autogen.sh 2007-06-12 13:39:37 UTC (rev 238) @@ -30,6 +30,11 @@ DIE=no +FORCE= +if test "$1" == "--force"; then + FORCE=" --force" + shift +fi # ***** W32 build script ******* @@ -47,25 +52,20 @@ [ -z "$w32root" ] && w32root="$HOME/w32root" echo "Using $w32root as standard install directory" >&2 - # See whether we have the Debian cross compiler package or the - # old mingw32/cpd system - if i586-mingw32msvc-gcc --version >/dev/null 2>&1 ; then - host=i586-mingw32msvc - crossbindir=/usr/$host/bin - else - host=i386--mingw32 - if ! mingw32 --version >/dev/null; then - echo "We need at least version 0.3 of MingW32/CPD" >&2 - exit 1 - fi - crossbindir=`mingw32 --install-dir`/bin - # Old autoconf version required us to setup the environment - # with the proper tool names. - CC=`mingw32 --get-path gcc` - CPP=`mingw32 --get-path cpp` - AR=`mingw32 --get-path ar` - RANLIB=`mingw32 --get-path ranlib` - export CC CPP AR RANLIB + crossbindir= + for host in i586-mingw32msvc i386-mingw32msvc mingw32; do + if ${host}-gcc --version >/dev/null 2>&1 ; then + crossbindir=/usr/${host}/bin + conf_CC="CC=${host}-gcc" + break; + fi + done + if [ -z "$crossbindir" ]; then + echo "Cross compiler kit not installed" >&2 + echo "Under Debian GNU/Linux, you may install it using" >&2 + echo " apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2 + echo "Stop." >&2 + exit 1 fi if [ -f "$tsdir/config.log" ]; then @@ -76,7 +76,8 @@ fi ./configure --enable-maintainer-mode --prefix=${w32root} \ - --host=i586-mingw32msvc --build=${build} \ + --host=${host} --build=${build} \ + --with-pth-prefix=${w32root} \ --disable-shared exit $? @@ -122,7 +123,7 @@ fi $tsdir/configure --enable-maintainer-mode --prefix=${amd64root} \ - --host=${host} --build=${build} + --host=${host} --build=${build} rc=$? exit $rc fi @@ -193,7 +194,7 @@ $AUTOHEADER echo "Running automake --gnu ..." $AUTOMAKE --gnu; -echo "Running autoconf..." -$AUTOCONF +echo "Running autoconf${FORCE} ..." +$AUTOCONF${FORCE} echo "You may now run \"./configure --enable-maintainer-mode && make\"." Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/configure.ac 2007-06-12 13:39:37 UTC (rev 238) @@ -20,8 +20,8 @@ # Process this file with autoconf to produce a configure script. -AC_PREREQ(2.59) -min_automake_version="1.9.3" +AC_PREREQ(2.61) +min_automake_version="1.10" # Remember to change the version number immediately *after* a release. # Set my_issvn to "yes" for non-released code. Remember to run an @@ -67,6 +67,10 @@ AC_PROG_AWK AC_PROG_CC AC_PROG_CPP +AM_PROG_CC_C_O +if test "x$ac_cv_prog_cc_c89" = "xno" ; then + AC_MSG_ERROR([[No C-89 compiler found]]) +fi AC_PROG_INSTALL AC_PROG_LN_S AC_PROG_MAKE_SET @@ -75,6 +79,16 @@ if test "$GCC" = yes; then CFLAGS="$CFLAGS -Wall -Wcast-align -Wshadow -Wstrict-prototypes" + + AC_MSG_CHECKING([if gcc supports -Wpointer-arith]) + _gcc_cflags_save=$CFLAGS + CFLAGS="-Wpointer-arith" + AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),_gcc_wopt=yes,_gcc_wopt=no) + AC_MSG_RESULT($_gcc_wopt) + CFLAGS=$_gcc_cflags_save; + if test x"$_gcc_wopt" = xyes ; then + CFLAGS="$CFLAGS -Wpointer-arith" + fi fi @@ -162,6 +176,7 @@ AC_TYPE_SIGNAL AC_DECL_SYS_SIGLIST +gl_HEADER_SYS_SOCKET gl_TYPE_SOCKLEN_T AC_CHECK_MEMBER(struct cmsghdr.cmsg_len, Modified: trunk/m4/gnupg-pth.m4 =================================================================== --- trunk/m4/gnupg-pth.m4 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/m4/gnupg-pth.m4 2007-06-12 13:39:37 UTC (rev 238) @@ -73,13 +73,11 @@ ]) -# + # GNUPG_PATH_PTH([MINIMUM_VERSION]) # -# This is a special version of the check whioch assumes that a -# emulation for W32 systems is available. The test assumes that -# $have_w32_system has already been set. On return $have_pth is set -# as well as HAVE_PTH is defined and PTH_CLFAGS and PTH_LIBS are AS_SUBST. +# On return $have_pth is set as well as HAVE_PTH is defined and +# PTH_CLFAGS and PTH_LIBS are AS_SUBST. # AC_DEFUN([GNUPG_PATH_PTH], [ AC_ARG_WITH(pth-prefix, @@ -91,8 +89,7 @@ fi AC_PATH_PROG(PTH_CONFIG, pth-config, no) tmp=ifelse([$1], ,1.3.7,$1) - if test "$have_w32_system" = no; then - if test "$PTH_CONFIG" != "no"; then + if test "$PTH_CONFIG" != "no"; then GNUPG_PTH_VERSION_CHECK($tmp) if test $have_pth = yes; then PTH_CFLAGS=`$PTH_CONFIG --cflags` @@ -101,12 +98,6 @@ AC_DEFINE(HAVE_PTH, 1, [Defined if the GNU Pth is available]) fi - fi - else - have_pth=yes - PTH_CFLAGS="" - PTH_LIBS="" - AC_DEFINE(HAVE_PTH, 1) fi AC_SUBST(PTH_CFLAGS) AC_SUBST(PTH_LIBS) Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/src/ChangeLog 2007-06-12 13:39:37 UTC (rev 238) @@ -1,3 +1,37 @@ +2007-06-12 Werner Koch + + * assuan-io.c (_assuan_simple_read): Hack to allow reading from a + socket. + (_assuan_simple_write): Likewise. + +2007-06-11 Werner Koch + + * assuan-io-pth.c (_assuan_simple_read, _assuan_simple_write): Use + pth versions also for W32. + +2007-05-29 Werner Koch + + * assuan-io-pth.c: Include sys/socket.h only if available. Remove + double inclusion of sys/wait.h + + * assuan-pipe-connect.c (build_w32_commandline): Make ARGV const. + + * assuan-pipe-server.c (is_valid_socket) [W32]: Do not define. + + * assuan-socket-server.c [W32]: Include ws2tcpip.h to define + socklen_t. + * assuan-defs.h (struct assuan_context_s): Define most peercred + members only if we can really set them. + (_assuan_simple_sendmsg, _assuan_simple_recvmsg) [W32]: Use a + different prototype. + * assuan.h (assuan_get_peercred) [W32]: Do not define. + * assuan-io.c (_assuan_simple_sendmsg, _assuan_simple_recvmsg) + [w32]: Use another prototype. + +2007-05-09 Werner Koch + + * libassuan.m4: Print found version on success. + 2007-05-01 Werner Koch * assuan-uds.c (uds_reader): Cast void ptr for arithmetics. Modified: trunk/src/assuan-connect.c =================================================================== --- trunk/src/assuan-connect.c 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/src/assuan-connect.c 2007-06-12 13:39:37 UTC (rev 238) @@ -62,6 +62,7 @@ /* Return user credentials. PID, UID and GID amy be gived as NULL if you are not interested in this value. For getting the pid of the peer the assuan_get_pid is usually better suited. */ +#ifndef _WIN32 assuan_error_t assuan_get_peercred (assuan_context_t ctx, pid_t *pid, uid_t *uid, gid_t *gid) { @@ -77,3 +78,4 @@ *gid = ctx->peercred.gid; return 0; } +#endif /*_WIN32*/ Modified: trunk/src/assuan-defs.h =================================================================== --- trunk/src/assuan-defs.h 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/src/assuan-defs.h 2007-06-12 13:39:37 UTC (rev 238) @@ -142,9 +142,11 @@ struct { int valid; /* Whether this structure has valid information. */ +#ifdef HAVE_SO_PEERCRED pid_t pid; /* The pid of the peer. */ uid_t uid; /* The uid of the peer. */ gid_t gid; /* The gid of the peer. */ +#endif /*HAVE_SO_PEERCRED*/ } peercred; /* Used for Unix domain sockets. */ @@ -280,8 +282,13 @@ ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size); ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size); +#ifdef _WIN32 +int _assuan_simple_sendmsg (assuan_context_t ctx, void *msg); +int _assuan_simple_recvmsg (assuan_context_t ctx, void *msg); +#else ssize_t _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg); ssize_t _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg); +#endif /*-- assuan-socket.c --*/ int _assuan_close (int fd); Modified: trunk/src/assuan-io-pth.c =================================================================== --- trunk/src/assuan-io-pth.c 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/src/assuan-io-pth.c 2007-06-12 13:39:37 UTC (rev 238) @@ -25,8 +25,9 @@ #include #include +#ifdef HAVE_SYS_SOCKET_H #include -#include +#endif #if HAVE_SYS_UIO_H # include #endif @@ -55,26 +56,22 @@ ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size) { -#ifndef HAVE_W32_SYSTEM return pth_read (ctx->inbound.fd, buffer, size); -#else - return recv (ctx->inbound.fd, buffer, size, 0); -#endif } ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size) { -#ifndef HAVE_W32_SYSTEM return pth_write (ctx->outbound.fd, buffer, size); -#else - return send (ctx->outbound.fd, buffer, size, 0); -#endif } - +#ifdef _WIN32 +int +_assuan_simple_sendmsg (assuan_context_t ctx, void *msg) +#else ssize_t _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg) +#endif { #if defined(HAVE_W32_SYSTEM) return _assuan_error (ASSUAN_Not_Implemented); @@ -109,9 +106,13 @@ #endif } - +#ifdef _WIN32 +int +_assuan_simple_recvmsg (assuan_context_t ctx, void *msg) +#else ssize_t _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg) +#endif { #if defined(HAVE_W32_SYSTEM) return _assuan_error (ASSUAN_Not_Implemented); Modified: trunk/src/assuan-io.c =================================================================== --- trunk/src/assuan-io.c 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/src/assuan-io.c 2007-06-12 13:39:37 UTC (rev 238) @@ -25,7 +25,9 @@ #include #include -#include +#ifdef HAVE_SYS_SOCKET_H +# include +#endif #include #include #ifdef HAVE_W32_SYSTEM @@ -49,18 +51,69 @@ ssize_t _assuan_simple_read (assuan_context_t ctx, void *buffer, size_t size) { +#ifdef HAVE_W32_SYSTEM + /* Due to the peculiarities of the W32 API we can't use read for a + network socket and thus we try to use recv first and fallback to + read if recv detects that it is not a network socket. */ + int n; + + n = recv (ctx->inbound.fd, buffer, size, 0); + if (n == -1 && WSAGetLastError () == WSAENOTSOCK) + { + DWORD nread = 0; + + n = ReadFile ((HANDLE)ctx->inbound.fd, buffer, size, &nread, NULL); + if (!n) + { + errno = EIO; /* FIXME: We should have a proper mapping. */ + n = -1; + } + else + n = (int)nread; + } + return n; +#else /*!HAVE_W32_SYSTEM*/ return read (ctx->inbound.fd, buffer, size); +#endif /*!HAVE_W32_SYSTEM*/ } ssize_t _assuan_simple_write (assuan_context_t ctx, const void *buffer, size_t size) { +#ifdef HAVE_W32_SYSTEM + /* Due to the peculiarities of the W32 API we can't use write for a + network socket and thus we try to use send first and fallback to + write if send detects that it is not a network socket. */ + int n; + + n = send (ctx->outbound.fd, buffer, size, 0); + if (n == -1 && WSAGetLastError () == WSAENOTSOCK) + { + DWORD nwrite; + + n = WriteFile ((HANDLE)ctx->outbound.fd, buffer, size, &nwrite, NULL); + if (!n) + { + errno = EIO; /* FIXME: We should have a proper mapping. */ + n = -1; + } + else + n = (int)nwrite; + } + return n; +#else /*!HAVE_W32_SYSTEM*/ return write (ctx->outbound.fd, buffer, size); +#endif /*!HAVE_W32_SYSTEM*/ } +#ifdef HAVE_W32_SYSTEM +int +_assuan_simple_sendmsg (assuan_context_t ctx, void *msg) +#else ssize_t _assuan_simple_sendmsg (assuan_context_t ctx, struct msghdr *msg) +#endif { #ifdef HAVE_W32_SYSTEM return _assuan_error (ASSUAN_Not_Implemented); @@ -73,8 +126,13 @@ } +#ifdef HAVE_W32_SYSTEM +int +_assuan_simple_recvmsg (assuan_context_t ctx, void *msg) +#else ssize_t _assuan_simple_recvmsg (assuan_context_t ctx, struct msghdr *msg) +#endif { #ifdef HAVE_W32_SYSTEM return _assuan_error (ASSUAN_Not_Implemented); Modified: trunk/src/assuan-pipe-connect.c =================================================================== --- trunk/src/assuan-pipe-connect.c 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/src/assuan-pipe-connect.c 2007-06-12 13:39:37 UTC (rev 238) @@ -554,7 +554,7 @@ /* Build a command line for use with W32's CreateProcess. On success CMDLINE gets the address of a newly allocated string. */ static int -build_w32_commandline (char * const *argv, char **cmdline) +build_w32_commandline (const char * const *argv, char **cmdline) { int i, n; const char *s; Modified: trunk/src/assuan-pipe-server.c =================================================================== --- trunk/src/assuan-pipe-server.c 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/src/assuan-pipe-server.c 2007-06-12 13:39:37 UTC (rev 238) @@ -92,6 +92,7 @@ /* Returns true if atoi(S) denotes a valid socket. */ +#ifndef HAVE_W32_SYSTEM static int is_valid_socket (const char *s) { @@ -101,6 +102,7 @@ return 0; return S_ISSOCK (buf.st_mode); } +#endif /*!HAVE_W32_SYSTEM*/ int Modified: trunk/src/assuan-socket-server.c =================================================================== --- trunk/src/assuan-socket-server.c 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/src/assuan-socket-server.c 2007-06-12 13:39:37 UTC (rev 238) @@ -25,13 +25,19 @@ #include #include #include -#ifndef HAVE_W32_SYSTEM -#include -#include +#ifdef HAVE_W32_SYSTEM +# include +# if HAVE_SYS_SOCKET_H +# include +# elif HAVE_WS2TCPIP_H +# include +# endif #else -#include +# include +# include #endif + #include "assuan-defs.h" static struct assuan_io io = { _assuan_simple_read, Modified: trunk/src/assuan.h =================================================================== --- trunk/src/assuan.h 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/src/assuan.h 2007-06-12 13:39:37 UTC (rev 238) @@ -425,8 +425,10 @@ /*-- assuan-connect.c --*/ void assuan_disconnect (assuan_context_t ctx); pid_t assuan_get_pid (assuan_context_t ctx); +#ifndef _WIN32 assuan_error_t assuan_get_peercred (assuan_context_t ctx, pid_t *pid, uid_t *uid, gid_t *gid); +#endif /*-- assuan-client.c --*/ assuan_error_t Modified: trunk/src/libassuan.m4 =================================================================== --- trunk/src/libassuan.m4 2007-05-06 21:57:58 UTC (rev 237) +++ trunk/src/libassuan.m4 2007-06-12 13:39:37 UTC (rev 238) @@ -74,7 +74,7 @@ fi if test $ok = yes; then - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes ($libassuan_version)]) else AC_MSG_RESULT(no) fi From cvs at cvs.gnupg.org Tue Jun 12 15:41:20 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 12 Jun 2007 15:41:20 +0200 Subject: [svn] w32pth - r3 - trunk Message-ID: Author: wk Date: 2007-06-12 15:40:50 +0200 (Tue, 12 Jun 2007) New Revision: 3 Modified: trunk/README trunk/libw32pth.def trunk/pth.h trunk/w32-pth.c Log: New functions. Modified: trunk/README =================================================================== --- trunk/README 2007-05-31 10:20:37 UTC (rev 2) +++ trunk/README 2007-06-12 13:40:50 UTC (rev 3) @@ -8,3 +8,9 @@ the behaviour of PTH. It is currently limited to what GnuPG 2.0 requires. + + +Thisng we need to implement: + + pth_select_ev - EV is currently ignored. + Modified: trunk/libw32pth.def =================================================================== --- trunk/libw32pth.def 2007-05-31 10:20:37 UTC (rev 2) +++ trunk/libw32pth.def 2007-06-12 13:40:50 UTC (rev 3) @@ -57,3 +57,8 @@ pth_event_occurred @30 pth_event_concat @31 pth_event @32 + + pth_select_ev @33 + pth_sigmask @34 + + Modified: trunk/pth.h =================================================================== --- trunk/pth.h 2007-05-31 10:20:37 UTC (rev 2) +++ trunk/pth.h 2007-06-12 13:40:50 UTC (rev 3) @@ -38,11 +38,24 @@ heavyweight - may be we should factor such code out to a second header and adjust all user files to include it only if required. */ +#include /* For sigset_t. */ #ifndef W32_PTH_HANDLE_INTERNAL #define W32_PTH_HANDLE_INTERNAL int #endif +/* We need to define value for the how argument of pth_sigmask. This + is required because Mingw does not yet define sigprocmask. We use + an enum to error out if Mingw eventually defines them. Also define + the sigset_t. */ +#ifdef __MINGW32__ +enum + { + SIG_BLOCK = 0, + SIG_UNBLOCK = 1, + SIG_SETMASK = 2 + }; +#endif /*__MINGW32__*/ /* Filedescriptor blocking modes. */ enum @@ -197,6 +210,8 @@ int pth_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, const struct timeval *timeout); +int pth_select_ev (int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, + const struct timeval * timeout, pth_event_t ev_extra); int pth_accept (int fd, struct sockaddr *addr, int *addrlen); int pth_accept_ev (int fd, struct sockaddr *addr, int *addrlen, @@ -236,7 +251,10 @@ pth_event_t pth_event (unsigned long spec, ...); +int pth_sigmask (int how, const sigset_t *set, sigset_t *old); + + /*-- pth_util.c --*/ /* void sigemptyset (struct sigset_s * ss); */ Modified: trunk/w32-pth.c =================================================================== --- trunk/w32-pth.c 2007-05-31 10:20:37 UTC (rev 2) +++ trunk/w32-pth.c 2007-06-12 13:40:50 UTC (rev 3) @@ -321,6 +321,17 @@ else n = (int)nwrite; } + else if (n == -1) + { + DWORD nwrite; + char strerr[256]; + + if (DBG_ERROR) + fprintf (stderr, "%s: pth_write(%d) failed in send: %s\n", + log_get_prefix (NULL), fd, + w32_strerror (strerr, sizeof strerr)); + n = -1; + } leave_pth (__FUNCTION__); return n; } @@ -341,6 +352,20 @@ int +pth_select_ev (int nfds, fd_set * rfds, fd_set * wfds, fd_set * efds, + const struct timeval * timeout, pth_event_t ev_extra) +{ + int n; + + implicit_init (); + enter_pth (__FUNCTION__); + n = select (nfds, rfds, wfds, efds, timeout); + leave_pth (__FUNCTION__); + return n; +} + + +int pth_fdmode (int fd, int mode) { unsigned long val; @@ -662,7 +687,7 @@ store the thread's handle in the context structure. We need to do this to be able to close the handle from the launch helper. - FIXME: We should no use th W32's Thread handle directly but keep + FIXME: We should not use W32's thread handle directly but keep our own thread control structure. CTX may be used for that. */ if (DBG_INFO) fprintf (stderr, "%s: do_pth_spawn creating thread ...\n", @@ -1380,8 +1405,15 @@ } +int +pth_sigmask (int how, const sigset_t *set, sigset_t *old) +{ + return 0; +} + + /* Some simple tests. From cvs at cvs.gnupg.org Tue Jun 12 22:20:01 2007 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Tue, 12 Jun 2007 22:20:01 +0200 Subject: [svn] GnuPG - r4510 - branches/STABLE-BRANCH-1-4/g10 Message-ID: Author: dshaw Date: 2007-06-12 22:19:31 +0200 (Tue, 12 Jun 2007) New Revision: 4510 Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog branches/STABLE-BRANCH-1-4/g10/sign.c Log: * sign.c (mk_notation_policy_etc): expect all sigs that this is called for are >=v4. (write_signature_packets, make_keysig_packet): Only call it for >=v4 sigs. This allows --force-v3-sigs and --force-v4-certs to enable or disable notations, policies, and keyserver URLs. This is bug#800. Modified: branches/STABLE-BRANCH-1-4/g10/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/g10/ChangeLog 2007-06-08 17:38:13 UTC (rev 4509) +++ branches/STABLE-BRANCH-1-4/g10/ChangeLog 2007-06-12 20:19:31 UTC (rev 4510) @@ -1,3 +1,12 @@ +2007-06-12 David Shaw + + * sign.c (mk_notation_policy_etc): expect all sigs that this is + called for are >=v4. + (write_signature_packets, make_keysig_packet): Only call it for + >=v4 sigs. This allows --force-v3-sigs and --force-v4-certs to + enable or disable notations, policies, and keyserver URLs. This + is bug#800. + 2007-04-16 David Shaw * packet.h, mainproc.c (reset_literals_seen): New function to Modified: branches/STABLE-BRANCH-1-4/g10/sign.c =================================================================== --- branches/STABLE-BRANCH-1-4/g10/sign.c 2007-06-08 17:38:13 UTC (rev 4509) +++ branches/STABLE-BRANCH-1-4/g10/sign.c 2007-06-12 20:19:31 UTC (rev 4510) @@ -1,6 +1,6 @@ /* sign.c - sign data - * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, - * 2006 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, + * 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -69,32 +69,17 @@ struct notation *nd=NULL; struct expando_args args; + assert(sig->version>=4); + memset(&args,0,sizeof(args)); args.pk=pk; args.sk=sk; - /* It is actually impossible to get here when making a v3 key - signature since keyedit.c:sign_uids will automatically bump a - signature with a notation or policy url up to v4, but it is - good to do these checks anyway. */ - /* notation data */ if(IS_SIG(sig) && opt.sig_notations) - { - if(sig->version<4) - log_error(_("can't put notation data into v3 (PGP 2.x style) " - "signatures\n")); - else - nd=opt.sig_notations; - } + nd=opt.sig_notations; else if( IS_CERT(sig) && opt.cert_notations ) - { - if(sig->version<4) - log_error(_("can't put notation data into v3 (PGP 2.x style) " - "key signatures\n")); - else - nd=opt.cert_notations; - } + nd=opt.cert_notations; if(nd) { @@ -119,21 +104,9 @@ /* set policy URL */ if( IS_SIG(sig) && opt.sig_policy_url ) - { - if(sig->version<4) - log_error(_("can't put a policy URL into v3 (PGP 2.x style) " - "signatures\n")); - else - pu=opt.sig_policy_url; - } + pu=opt.sig_policy_url; else if( IS_CERT(sig) && opt.cert_policy_url ) - { - if(sig->version<4) - log_error(_("can't put a policy URL into v3 key (PGP 2.x style) " - "signatures\n")); - else - pu=opt.cert_policy_url; - } + pu=opt.cert_policy_url; for(;pu;pu=pu->next) { @@ -156,12 +129,7 @@ /* preferred keyserver URL */ if( IS_SIG(sig) && opt.sig_keyserver_url ) - { - if(sig->version<4) - log_info("can't put a preferred keyserver URL into v3 signatures\n"); - else - pu=opt.sig_keyserver_url; - } + pu=opt.sig_keyserver_url; for(;pu;pu=pu->next) { @@ -689,8 +657,10 @@ md = md_copy (hash); if (sig->version >= 4) + { build_sig_subpkt_from_sig (sig); - mk_notation_policy_etc (sig, NULL, sk); + mk_notation_policy_etc (sig, NULL, sk); + } hash_sigversion_to_magic (md, sig); md_final (md); @@ -1474,8 +1444,10 @@ sig->expiredate=sig->timestamp+duration; sig->sig_class = sigclass; if( sig->version >= 4 ) + { build_sig_subpkt_from_sig( sig ); - mk_notation_policy_etc( sig, pk, sk ); + mk_notation_policy_etc( sig, pk, sk ); + } /* Crucial that the call to mksubpkt comes LAST before the calls to finalize the sig as that makes it possible for the mksubpkt From cvs at cvs.gnupg.org Wed Jun 13 17:28:44 2007 From: cvs at cvs.gnupg.org (svn author dshaw) Date: Wed, 13 Jun 2007 17:28:44 +0200 Subject: [svn] GnuPG - r4511 - in branches/STABLE-BRANCH-1-4: . cipher include Message-ID: Author: dshaw Date: 2007-06-13 17:28:11 +0200 (Wed, 13 Jun 2007) New Revision: 4511 Added: branches/STABLE-BRANCH-1-4/cipher/camellia-glue.c branches/STABLE-BRANCH-1-4/cipher/camellia.c branches/STABLE-BRANCH-1-4/cipher/camellia.h Modified: branches/STABLE-BRANCH-1-4/ChangeLog branches/STABLE-BRANCH-1-4/cipher/ChangeLog branches/STABLE-BRANCH-1-4/cipher/Makefile.am branches/STABLE-BRANCH-1-4/cipher/algorithms.h branches/STABLE-BRANCH-1-4/cipher/cipher.c branches/STABLE-BRANCH-1-4/configure.ac branches/STABLE-BRANCH-1-4/include/ChangeLog branches/STABLE-BRANCH-1-4/include/cipher.h Log: Add Camellia. Do not enable this if you are not doing interop testing. It is not (yet) legal OpenPGP, is not interop tested yet (obviously), and it's a great way to lose your data. Just don't do it. Modified: branches/STABLE-BRANCH-1-4/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/ChangeLog 2007-06-12 20:19:31 UTC (rev 4510) +++ branches/STABLE-BRANCH-1-4/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) @@ -1,3 +1,8 @@ +2007-06-13 David Shaw + + * configure.ac: Add --enable-camellia. Disabled by default. Do + not enable this unless you're doing interop testing. + 2007-04-16 Werner Koch * acinclude.m4: Fix last change. Make test self-conatined by Modified: branches/STABLE-BRANCH-1-4/cipher/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/cipher/ChangeLog 2007-06-12 20:19:31 UTC (rev 4510) +++ branches/STABLE-BRANCH-1-4/cipher/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) @@ -1,6 +1,17 @@ +2007-06-13 David Shaw + + * Makefile.am, algorithms.h, cipher.c (setup_cipher_table): Add + Camellia. + + * camellia-glue.c: New. These are glue functions to interface + GnuPG to the stock NTT Camellia distribution. + + * camellia.h, camellia.c: New. Version 1.2.0 of the Camellia code + (GPL) unchanged from + http://info.isl.ntt.co.jp/crypt/eng/camellia/index.html + 2006-12-11 Werner Koch - * elgamal.c (test_keys): Use new mpi_nlimb_hint_from_nbits function. This also rounds up the value. (generate): Use new mpi_nlimb_hint_from_nbits function. Modified: branches/STABLE-BRANCH-1-4/cipher/Makefile.am =================================================================== --- branches/STABLE-BRANCH-1-4/cipher/Makefile.am 2007-06-12 20:19:31 UTC (rev 4510) +++ branches/STABLE-BRANCH-1-4/cipher/Makefile.am 2007-06-13 15:28:11 UTC (rev 4511) @@ -1,5 +1,5 @@ -# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, -# 2005 Free Software Foundation, Inc. +# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2005, +# 2007 Free Software Foundation, Inc. # # This file is part of GnuPG. # @@ -38,6 +38,7 @@ blowfish.c \ cast5.c \ rijndael.c \ + camellia.c camellia.h camellia-glue.c \ elgamal.c \ elgamal.h \ rsa.c rsa.h \ Modified: branches/STABLE-BRANCH-1-4/cipher/algorithms.h =================================================================== --- branches/STABLE-BRANCH-1-4/cipher/algorithms.h 2007-06-12 20:19:31 UTC (rev 4510) +++ branches/STABLE-BRANCH-1-4/cipher/algorithms.h 2007-06-13 15:28:11 UTC (rev 4511) @@ -138,4 +138,12 @@ void (**decryptf)( void *c, byte *outbuf, const byte *inbuf ) ); +const char * +camellia_get_info(int algo, size_t *keylen, + size_t *blocksize, size_t *contextsize, + int (**setkeyf)( void *c, const byte *key, unsigned keylen ), + void (**encryptf)( void *c, byte *outbuf, const byte *inbuf), + void (**decryptf)( void *c, byte *outbuf, const byte *inbuf ) + ); + #endif /*GNUPG_ALGORITHMS_H*/ Added: branches/STABLE-BRANCH-1-4/cipher/camellia-glue.c =================================================================== --- branches/STABLE-BRANCH-1-4/cipher/camellia-glue.c 2007-06-12 20:19:31 UTC (rev 4510) +++ branches/STABLE-BRANCH-1-4/cipher/camellia-glue.c 2007-06-13 15:28:11 UTC (rev 4511) @@ -0,0 +1,173 @@ +/* camellia-glue.c - Glue for the Camellia cipher + * Copyright (C) 2007 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +/* I put the GnuPG-specific stuff in this file to keep the + camellia.c/camellia.h files exactly as provided by NTT. If they + update their code, this should make it easier to bring the changes + in. - dshaw */ + +#include +#include +#include +#include "types.h" +#include "cipher.h" +#include "algorithms.h" +#include "util.h" +#include "errors.h" +#include "camellia.h" + +typedef struct +{ + int keybitlength; + KEY_TABLE_TYPE keytable; +} CAMELLIA_context; + +static const char *selftest(void); + +static void +burn_stack(int bytes) +{ + char buf[128]; + + wipememory(buf,sizeof buf); + bytes -= sizeof buf; + if (bytes > 0) + burn_stack (bytes); +} + +static int +camellia_setkey(void *c, const byte *key, unsigned keylen) +{ + CAMELLIA_context *ctx=c; + static int initialized=0; + static const char *selftest_failed=NULL; + + if(keylen!=32) + return G10ERR_WRONG_KEYLEN; + + if(!initialized) + { + initialized=1; + selftest_failed=selftest(); + if(selftest_failed) + log_error("%s\n",selftest_failed); + } + + if(selftest_failed) + return G10ERR_SELFTEST_FAILED; + + ctx->keybitlength=keylen*8; + Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable); + + burn_stack + ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */ + +(4+32)*sizeof(u32)+2*sizeof(void*) /* camellia_setup192 */ + +0+sizeof(int)+2*sizeof(void*) /* Camellia_Ekeygen */ + +3*2*sizeof(void*) /* Function calls. */ + ); + + return 0; +} + +static void +camellia_encrypt(void *c, byte *outbuf, const byte *inbuf) +{ + CAMELLIA_context *ctx=c; + + Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); + burn_stack + (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE) + +4*sizeof(u32) + +2*sizeof(u32*)+4*sizeof(u32) + +2*2*sizeof(void*) /* Function calls. */ + ); +} + +static void +camellia_decrypt(void *c, byte *outbuf, const byte *inbuf) +{ + CAMELLIA_context *ctx=c; + + Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf); + burn_stack + (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE) + +4*sizeof(u32) + +2*sizeof(u32*)+4*sizeof(u32) + +2*2*sizeof(void*) /* Function calls. */ + ); +} + +static const char * +selftest(void) +{ + CAMELLIA_context ctx; + byte scratch[16]; + + /* These test vectors are from RFC-3713 */ + const byte plaintext[]= + { + 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, + 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10 + }; + const byte key_256[]= + { + 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba, + 0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55, + 0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff + }; + const byte ciphertext_256[]= + { + 0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c, + 0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09 + }; + + camellia_setkey(&ctx,key_256,sizeof(key_256)); + camellia_encrypt(&ctx,scratch,plaintext); + if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0) + return "CAMELLIA-256 test encryption failed."; + camellia_decrypt(&ctx,scratch,scratch); + if(memcmp(scratch,plaintext,sizeof(plaintext))!=0) + return "CAMELLIA-256 test decryption failed."; + + return NULL; +} + +const char * +camellia_get_info(int algo, size_t *keylen, + size_t *blocksize, size_t *contextsize, + int (**r_setkey)(void *c, const byte *key, unsigned keylen), + void (**r_encrypt)(void *c, byte *outbuf, const byte *inbuf), + void (**r_decrypt)(void *c, byte *outbuf, const byte *inbuf) + ) +{ + *keylen = 256; + *blocksize = CAMELLIA_BLOCK_SIZE; + *contextsize = sizeof (CAMELLIA_context); + + *r_setkey = camellia_setkey; + *r_encrypt = camellia_encrypt; + *r_decrypt = camellia_decrypt; + + if(algo==CIPHER_ALGO_CAMELLIA) + return "CAMELLIA"; + + return NULL; +} Added: branches/STABLE-BRANCH-1-4/cipher/camellia.c =================================================================== --- branches/STABLE-BRANCH-1-4/cipher/camellia.c 2007-06-12 20:19:31 UTC (rev 4510) +++ branches/STABLE-BRANCH-1-4/cipher/camellia.c 2007-06-13 15:28:11 UTC (rev 4511) @@ -0,0 +1,1461 @@ +/* camellia.h ver 1.2.0 + * + * Copyright (C) 2006,2007 + * NTT (Nippon Telegraph and Telephone Corporation). + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +/* + * Algorithm Specification + * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html + */ + +#include +#include + +#include "camellia.h" + +/* u32 must be 32bit word */ +typedef unsigned int u32; +typedef unsigned char u8; + +/* key constants */ + +#define CAMELLIA_SIGMA1L (0xA09E667FL) +#define CAMELLIA_SIGMA1R (0x3BCC908BL) +#define CAMELLIA_SIGMA2L (0xB67AE858L) +#define CAMELLIA_SIGMA2R (0x4CAA73B2L) +#define CAMELLIA_SIGMA3L (0xC6EF372FL) +#define CAMELLIA_SIGMA3R (0xE94F82BEL) +#define CAMELLIA_SIGMA4L (0x54FF53A5L) +#define CAMELLIA_SIGMA4R (0xF1D36F1CL) +#define CAMELLIA_SIGMA5L (0x10E527FAL) +#define CAMELLIA_SIGMA5R (0xDE682D1DL) +#define CAMELLIA_SIGMA6L (0xB05688C2L) +#define CAMELLIA_SIGMA6R (0xB3E6C1FDL) + +/* + * macros + */ + + +#if defined(_MSC_VER) + +# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) +# define GETU32(p) SWAP(*((u32 *)(p))) +# define PUTU32(ct, st) {*((u32 *)(ct)) = SWAP((st));} + +#else /* not MS-VC */ + +# define GETU32(pt) \ + (((u32)(pt)[0] << 24) \ + ^ ((u32)(pt)[1] << 16) \ + ^ ((u32)(pt)[2] << 8) \ + ^ ((u32)(pt)[3])) + +# define PUTU32(ct, st) { \ + (ct)[0] = (u8)((st) >> 24); \ + (ct)[1] = (u8)((st) >> 16); \ + (ct)[2] = (u8)((st) >> 8); \ + (ct)[3] = (u8)(st); } + +#endif + +#define CamelliaSubkeyL(INDEX) (subkey[(INDEX)*2]) +#define CamelliaSubkeyR(INDEX) (subkey[(INDEX)*2 + 1]) + +/* rotation right shift 1byte */ +#define CAMELLIA_RR8(x) (((x) >> 8) + ((x) << 24)) +/* rotation left shift 1bit */ +#define CAMELLIA_RL1(x) (((x) << 1) + ((x) >> 31)) +/* rotation left shift 1byte */ +#define CAMELLIA_RL8(x) (((x) << 8) + ((x) >> 24)) + +#define CAMELLIA_ROLDQ(ll, lr, rl, rr, w0, w1, bits) \ + do { \ + w0 = ll; \ + ll = (ll << bits) + (lr >> (32 - bits)); \ + lr = (lr << bits) + (rl >> (32 - bits)); \ + rl = (rl << bits) + (rr >> (32 - bits)); \ + rr = (rr << bits) + (w0 >> (32 - bits)); \ + } while(0) + +#define CAMELLIA_ROLDQo32(ll, lr, rl, rr, w0, w1, bits) \ + do { \ + w0 = ll; \ + w1 = lr; \ + ll = (lr << (bits - 32)) + (rl >> (64 - bits)); \ + lr = (rl << (bits - 32)) + (rr >> (64 - bits)); \ + rl = (rr << (bits - 32)) + (w0 >> (64 - bits)); \ + rr = (w0 << (bits - 32)) + (w1 >> (64 - bits)); \ + } while(0) + +#define CAMELLIA_SP1110(INDEX) (camellia_sp1110[(INDEX)]) +#define CAMELLIA_SP0222(INDEX) (camellia_sp0222[(INDEX)]) +#define CAMELLIA_SP3033(INDEX) (camellia_sp3033[(INDEX)]) +#define CAMELLIA_SP4404(INDEX) (camellia_sp4404[(INDEX)]) + +#define CAMELLIA_F(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ + do { \ + il = xl ^ kl; \ + ir = xr ^ kr; \ + t0 = il >> 16; \ + t1 = ir >> 16; \ + yl = CAMELLIA_SP1110(ir & 0xff) \ + ^ CAMELLIA_SP0222((t1 >> 8) & 0xff) \ + ^ CAMELLIA_SP3033(t1 & 0xff) \ + ^ CAMELLIA_SP4404((ir >> 8) & 0xff); \ + yr = CAMELLIA_SP1110((t0 >> 8) & 0xff) \ + ^ CAMELLIA_SP0222(t0 & 0xff) \ + ^ CAMELLIA_SP3033((il >> 8) & 0xff) \ + ^ CAMELLIA_SP4404(il & 0xff); \ + yl ^= yr; \ + yr = CAMELLIA_RR8(yr); \ + yr ^= yl; \ + } while(0) + + +/* + * for speed up + * + */ +#define CAMELLIA_FLS(ll, lr, rl, rr, kll, klr, krl, krr, t0, t1, t2, t3) \ + do { \ + t0 = kll; \ + t0 &= ll; \ + lr ^= CAMELLIA_RL1(t0); \ + t1 = klr; \ + t1 |= lr; \ + ll ^= t1; \ + \ + t2 = krr; \ + t2 |= rr; \ + rl ^= t2; \ + t3 = krl; \ + t3 &= rl; \ + rr ^= CAMELLIA_RL1(t3); \ + } while(0) + +#define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1) \ + do { \ + ir = CAMELLIA_SP1110(xr & 0xff) \ + ^ CAMELLIA_SP0222((xr >> 24) & 0xff) \ + ^ CAMELLIA_SP3033((xr >> 16) & 0xff) \ + ^ CAMELLIA_SP4404((xr >> 8) & 0xff); \ + il = CAMELLIA_SP1110((xl >> 24) & 0xff) \ + ^ CAMELLIA_SP0222((xl >> 16) & 0xff) \ + ^ CAMELLIA_SP3033((xl >> 8) & 0xff) \ + ^ CAMELLIA_SP4404(xl & 0xff); \ + il ^= kl; \ + ir ^= kr; \ + ir ^= il; \ + il = CAMELLIA_RR8(il); \ + il ^= ir; \ + yl ^= ir; \ + yr ^= il; \ + } while(0) + + +static const u32 camellia_sp1110[256] = { + 0x70707000,0x82828200,0x2c2c2c00,0xececec00, + 0xb3b3b300,0x27272700,0xc0c0c000,0xe5e5e500, + 0xe4e4e400,0x85858500,0x57575700,0x35353500, + 0xeaeaea00,0x0c0c0c00,0xaeaeae00,0x41414100, + 0x23232300,0xefefef00,0x6b6b6b00,0x93939300, + 0x45454500,0x19191900,0xa5a5a500,0x21212100, + 0xededed00,0x0e0e0e00,0x4f4f4f00,0x4e4e4e00, + 0x1d1d1d00,0x65656500,0x92929200,0xbdbdbd00, + 0x86868600,0xb8b8b800,0xafafaf00,0x8f8f8f00, + 0x7c7c7c00,0xebebeb00,0x1f1f1f00,0xcecece00, + 0x3e3e3e00,0x30303000,0xdcdcdc00,0x5f5f5f00, + 0x5e5e5e00,0xc5c5c500,0x0b0b0b00,0x1a1a1a00, + 0xa6a6a600,0xe1e1e100,0x39393900,0xcacaca00, + 0xd5d5d500,0x47474700,0x5d5d5d00,0x3d3d3d00, + 0xd9d9d900,0x01010100,0x5a5a5a00,0xd6d6d600, + 0x51515100,0x56565600,0x6c6c6c00,0x4d4d4d00, + 0x8b8b8b00,0x0d0d0d00,0x9a9a9a00,0x66666600, + 0xfbfbfb00,0xcccccc00,0xb0b0b000,0x2d2d2d00, + 0x74747400,0x12121200,0x2b2b2b00,0x20202000, + 0xf0f0f000,0xb1b1b100,0x84848400,0x99999900, + 0xdfdfdf00,0x4c4c4c00,0xcbcbcb00,0xc2c2c200, + 0x34343400,0x7e7e7e00,0x76767600,0x05050500, + 0x6d6d6d00,0xb7b7b700,0xa9a9a900,0x31313100, + 0xd1d1d100,0x17171700,0x04040400,0xd7d7d700, + 0x14141400,0x58585800,0x3a3a3a00,0x61616100, + 0xdedede00,0x1b1b1b00,0x11111100,0x1c1c1c00, + 0x32323200,0x0f0f0f00,0x9c9c9c00,0x16161600, + 0x53535300,0x18181800,0xf2f2f200,0x22222200, + 0xfefefe00,0x44444400,0xcfcfcf00,0xb2b2b200, + 0xc3c3c300,0xb5b5b500,0x7a7a7a00,0x91919100, + 0x24242400,0x08080800,0xe8e8e800,0xa8a8a800, + 0x60606000,0xfcfcfc00,0x69696900,0x50505000, + 0xaaaaaa00,0xd0d0d000,0xa0a0a000,0x7d7d7d00, + 0xa1a1a100,0x89898900,0x62626200,0x97979700, + 0x54545400,0x5b5b5b00,0x1e1e1e00,0x95959500, + 0xe0e0e000,0xffffff00,0x64646400,0xd2d2d200, + 0x10101000,0xc4c4c400,0x00000000,0x48484800, + 0xa3a3a300,0xf7f7f700,0x75757500,0xdbdbdb00, + 0x8a8a8a00,0x03030300,0xe6e6e600,0xdadada00, + 0x09090900,0x3f3f3f00,0xdddddd00,0x94949400, + 0x87878700,0x5c5c5c00,0x83838300,0x02020200, + 0xcdcdcd00,0x4a4a4a00,0x90909000,0x33333300, + 0x73737300,0x67676700,0xf6f6f600,0xf3f3f300, + 0x9d9d9d00,0x7f7f7f00,0xbfbfbf00,0xe2e2e200, + 0x52525200,0x9b9b9b00,0xd8d8d800,0x26262600, + 0xc8c8c800,0x37373700,0xc6c6c600,0x3b3b3b00, + 0x81818100,0x96969600,0x6f6f6f00,0x4b4b4b00, + 0x13131300,0xbebebe00,0x63636300,0x2e2e2e00, + 0xe9e9e900,0x79797900,0xa7a7a700,0x8c8c8c00, + 0x9f9f9f00,0x6e6e6e00,0xbcbcbc00,0x8e8e8e00, + 0x29292900,0xf5f5f500,0xf9f9f900,0xb6b6b600, + 0x2f2f2f00,0xfdfdfd00,0xb4b4b400,0x59595900, + 0x78787800,0x98989800,0x06060600,0x6a6a6a00, + 0xe7e7e700,0x46464600,0x71717100,0xbababa00, + 0xd4d4d400,0x25252500,0xababab00,0x42424200, + 0x88888800,0xa2a2a200,0x8d8d8d00,0xfafafa00, + 0x72727200,0x07070700,0xb9b9b900,0x55555500, + 0xf8f8f800,0xeeeeee00,0xacacac00,0x0a0a0a00, + 0x36363600,0x49494900,0x2a2a2a00,0x68686800, + 0x3c3c3c00,0x38383800,0xf1f1f100,0xa4a4a400, + 0x40404000,0x28282800,0xd3d3d300,0x7b7b7b00, + 0xbbbbbb00,0xc9c9c900,0x43434300,0xc1c1c100, + 0x15151500,0xe3e3e300,0xadadad00,0xf4f4f400, + 0x77777700,0xc7c7c700,0x80808000,0x9e9e9e00, +}; + +static const u32 camellia_sp0222[256] = { + 0x00e0e0e0,0x00050505,0x00585858,0x00d9d9d9, + 0x00676767,0x004e4e4e,0x00818181,0x00cbcbcb, + 0x00c9c9c9,0x000b0b0b,0x00aeaeae,0x006a6a6a, + 0x00d5d5d5,0x00181818,0x005d5d5d,0x00828282, + 0x00464646,0x00dfdfdf,0x00d6d6d6,0x00272727, + 0x008a8a8a,0x00323232,0x004b4b4b,0x00424242, + 0x00dbdbdb,0x001c1c1c,0x009e9e9e,0x009c9c9c, + 0x003a3a3a,0x00cacaca,0x00252525,0x007b7b7b, + 0x000d0d0d,0x00717171,0x005f5f5f,0x001f1f1f, + 0x00f8f8f8,0x00d7d7d7,0x003e3e3e,0x009d9d9d, + 0x007c7c7c,0x00606060,0x00b9b9b9,0x00bebebe, + 0x00bcbcbc,0x008b8b8b,0x00161616,0x00343434, + 0x004d4d4d,0x00c3c3c3,0x00727272,0x00959595, + 0x00ababab,0x008e8e8e,0x00bababa,0x007a7a7a, + 0x00b3b3b3,0x00020202,0x00b4b4b4,0x00adadad, + 0x00a2a2a2,0x00acacac,0x00d8d8d8,0x009a9a9a, + 0x00171717,0x001a1a1a,0x00353535,0x00cccccc, + 0x00f7f7f7,0x00999999,0x00616161,0x005a5a5a, + 0x00e8e8e8,0x00242424,0x00565656,0x00404040, + 0x00e1e1e1,0x00636363,0x00090909,0x00333333, + 0x00bfbfbf,0x00989898,0x00979797,0x00858585, + 0x00686868,0x00fcfcfc,0x00ececec,0x000a0a0a, + 0x00dadada,0x006f6f6f,0x00535353,0x00626262, + 0x00a3a3a3,0x002e2e2e,0x00080808,0x00afafaf, + 0x00282828,0x00b0b0b0,0x00747474,0x00c2c2c2, + 0x00bdbdbd,0x00363636,0x00222222,0x00383838, + 0x00646464,0x001e1e1e,0x00393939,0x002c2c2c, + 0x00a6a6a6,0x00303030,0x00e5e5e5,0x00444444, + 0x00fdfdfd,0x00888888,0x009f9f9f,0x00656565, + 0x00878787,0x006b6b6b,0x00f4f4f4,0x00232323, + 0x00484848,0x00101010,0x00d1d1d1,0x00515151, + 0x00c0c0c0,0x00f9f9f9,0x00d2d2d2,0x00a0a0a0, + 0x00555555,0x00a1a1a1,0x00414141,0x00fafafa, + 0x00434343,0x00131313,0x00c4c4c4,0x002f2f2f, + 0x00a8a8a8,0x00b6b6b6,0x003c3c3c,0x002b2b2b, + 0x00c1c1c1,0x00ffffff,0x00c8c8c8,0x00a5a5a5, + 0x00202020,0x00898989,0x00000000,0x00909090, + 0x00474747,0x00efefef,0x00eaeaea,0x00b7b7b7, + 0x00151515,0x00060606,0x00cdcdcd,0x00b5b5b5, + 0x00121212,0x007e7e7e,0x00bbbbbb,0x00292929, + 0x000f0f0f,0x00b8b8b8,0x00070707,0x00040404, + 0x009b9b9b,0x00949494,0x00212121,0x00666666, + 0x00e6e6e6,0x00cecece,0x00ededed,0x00e7e7e7, + 0x003b3b3b,0x00fefefe,0x007f7f7f,0x00c5c5c5, + 0x00a4a4a4,0x00373737,0x00b1b1b1,0x004c4c4c, + 0x00919191,0x006e6e6e,0x008d8d8d,0x00767676, + 0x00030303,0x002d2d2d,0x00dedede,0x00969696, + 0x00262626,0x007d7d7d,0x00c6c6c6,0x005c5c5c, + 0x00d3d3d3,0x00f2f2f2,0x004f4f4f,0x00191919, + 0x003f3f3f,0x00dcdcdc,0x00797979,0x001d1d1d, + 0x00525252,0x00ebebeb,0x00f3f3f3,0x006d6d6d, + 0x005e5e5e,0x00fbfbfb,0x00696969,0x00b2b2b2, + 0x00f0f0f0,0x00313131,0x000c0c0c,0x00d4d4d4, + 0x00cfcfcf,0x008c8c8c,0x00e2e2e2,0x00757575, + 0x00a9a9a9,0x004a4a4a,0x00575757,0x00848484, + 0x00111111,0x00454545,0x001b1b1b,0x00f5f5f5, + 0x00e4e4e4,0x000e0e0e,0x00737373,0x00aaaaaa, + 0x00f1f1f1,0x00dddddd,0x00595959,0x00141414, + 0x006c6c6c,0x00929292,0x00545454,0x00d0d0d0, + 0x00787878,0x00707070,0x00e3e3e3,0x00494949, + 0x00808080,0x00505050,0x00a7a7a7,0x00f6f6f6, + 0x00777777,0x00939393,0x00868686,0x00838383, + 0x002a2a2a,0x00c7c7c7,0x005b5b5b,0x00e9e9e9, + 0x00eeeeee,0x008f8f8f,0x00010101,0x003d3d3d, +}; + +static const u32 camellia_sp3033[256] = { + 0x38003838,0x41004141,0x16001616,0x76007676, + 0xd900d9d9,0x93009393,0x60006060,0xf200f2f2, + 0x72007272,0xc200c2c2,0xab00abab,0x9a009a9a, + 0x75007575,0x06000606,0x57005757,0xa000a0a0, + 0x91009191,0xf700f7f7,0xb500b5b5,0xc900c9c9, + 0xa200a2a2,0x8c008c8c,0xd200d2d2,0x90009090, + 0xf600f6f6,0x07000707,0xa700a7a7,0x27002727, + 0x8e008e8e,0xb200b2b2,0x49004949,0xde00dede, + 0x43004343,0x5c005c5c,0xd700d7d7,0xc700c7c7, + 0x3e003e3e,0xf500f5f5,0x8f008f8f,0x67006767, + 0x1f001f1f,0x18001818,0x6e006e6e,0xaf00afaf, + 0x2f002f2f,0xe200e2e2,0x85008585,0x0d000d0d, + 0x53005353,0xf000f0f0,0x9c009c9c,0x65006565, + 0xea00eaea,0xa300a3a3,0xae00aeae,0x9e009e9e, + 0xec00ecec,0x80008080,0x2d002d2d,0x6b006b6b, + 0xa800a8a8,0x2b002b2b,0x36003636,0xa600a6a6, + 0xc500c5c5,0x86008686,0x4d004d4d,0x33003333, + 0xfd00fdfd,0x66006666,0x58005858,0x96009696, + 0x3a003a3a,0x09000909,0x95009595,0x10001010, + 0x78007878,0xd800d8d8,0x42004242,0xcc00cccc, + 0xef00efef,0x26002626,0xe500e5e5,0x61006161, + 0x1a001a1a,0x3f003f3f,0x3b003b3b,0x82008282, + 0xb600b6b6,0xdb00dbdb,0xd400d4d4,0x98009898, + 0xe800e8e8,0x8b008b8b,0x02000202,0xeb00ebeb, + 0x0a000a0a,0x2c002c2c,0x1d001d1d,0xb000b0b0, + 0x6f006f6f,0x8d008d8d,0x88008888,0x0e000e0e, + 0x19001919,0x87008787,0x4e004e4e,0x0b000b0b, + 0xa900a9a9,0x0c000c0c,0x79007979,0x11001111, + 0x7f007f7f,0x22002222,0xe700e7e7,0x59005959, + 0xe100e1e1,0xda00dada,0x3d003d3d,0xc800c8c8, + 0x12001212,0x04000404,0x74007474,0x54005454, + 0x30003030,0x7e007e7e,0xb400b4b4,0x28002828, + 0x55005555,0x68006868,0x50005050,0xbe00bebe, + 0xd000d0d0,0xc400c4c4,0x31003131,0xcb00cbcb, + 0x2a002a2a,0xad00adad,0x0f000f0f,0xca00caca, + 0x70007070,0xff00ffff,0x32003232,0x69006969, + 0x08000808,0x62006262,0x00000000,0x24002424, + 0xd100d1d1,0xfb00fbfb,0xba00baba,0xed00eded, + 0x45004545,0x81008181,0x73007373,0x6d006d6d, + 0x84008484,0x9f009f9f,0xee00eeee,0x4a004a4a, + 0xc300c3c3,0x2e002e2e,0xc100c1c1,0x01000101, + 0xe600e6e6,0x25002525,0x48004848,0x99009999, + 0xb900b9b9,0xb300b3b3,0x7b007b7b,0xf900f9f9, + 0xce00cece,0xbf00bfbf,0xdf00dfdf,0x71007171, + 0x29002929,0xcd00cdcd,0x6c006c6c,0x13001313, + 0x64006464,0x9b009b9b,0x63006363,0x9d009d9d, + 0xc000c0c0,0x4b004b4b,0xb700b7b7,0xa500a5a5, + 0x89008989,0x5f005f5f,0xb100b1b1,0x17001717, + 0xf400f4f4,0xbc00bcbc,0xd300d3d3,0x46004646, + 0xcf00cfcf,0x37003737,0x5e005e5e,0x47004747, + 0x94009494,0xfa00fafa,0xfc00fcfc,0x5b005b5b, + 0x97009797,0xfe00fefe,0x5a005a5a,0xac00acac, + 0x3c003c3c,0x4c004c4c,0x03000303,0x35003535, + 0xf300f3f3,0x23002323,0xb800b8b8,0x5d005d5d, + 0x6a006a6a,0x92009292,0xd500d5d5,0x21002121, + 0x44004444,0x51005151,0xc600c6c6,0x7d007d7d, + 0x39003939,0x83008383,0xdc00dcdc,0xaa00aaaa, + 0x7c007c7c,0x77007777,0x56005656,0x05000505, + 0x1b001b1b,0xa400a4a4,0x15001515,0x34003434, + 0x1e001e1e,0x1c001c1c,0xf800f8f8,0x52005252, + 0x20002020,0x14001414,0xe900e9e9,0xbd00bdbd, + 0xdd00dddd,0xe400e4e4,0xa100a1a1,0xe000e0e0, + 0x8a008a8a,0xf100f1f1,0xd600d6d6,0x7a007a7a, + 0xbb00bbbb,0xe300e3e3,0x40004040,0x4f004f4f, +}; + +static const u32 camellia_sp4404[256] = { + 0x70700070,0x2c2c002c,0xb3b300b3,0xc0c000c0, + 0xe4e400e4,0x57570057,0xeaea00ea,0xaeae00ae, + 0x23230023,0x6b6b006b,0x45450045,0xa5a500a5, + 0xeded00ed,0x4f4f004f,0x1d1d001d,0x92920092, + 0x86860086,0xafaf00af,0x7c7c007c,0x1f1f001f, + 0x3e3e003e,0xdcdc00dc,0x5e5e005e,0x0b0b000b, + 0xa6a600a6,0x39390039,0xd5d500d5,0x5d5d005d, + 0xd9d900d9,0x5a5a005a,0x51510051,0x6c6c006c, + 0x8b8b008b,0x9a9a009a,0xfbfb00fb,0xb0b000b0, + 0x74740074,0x2b2b002b,0xf0f000f0,0x84840084, + 0xdfdf00df,0xcbcb00cb,0x34340034,0x76760076, + 0x6d6d006d,0xa9a900a9,0xd1d100d1,0x04040004, + 0x14140014,0x3a3a003a,0xdede00de,0x11110011, + 0x32320032,0x9c9c009c,0x53530053,0xf2f200f2, + 0xfefe00fe,0xcfcf00cf,0xc3c300c3,0x7a7a007a, + 0x24240024,0xe8e800e8,0x60600060,0x69690069, + 0xaaaa00aa,0xa0a000a0,0xa1a100a1,0x62620062, + 0x54540054,0x1e1e001e,0xe0e000e0,0x64640064, + 0x10100010,0x00000000,0xa3a300a3,0x75750075, + 0x8a8a008a,0xe6e600e6,0x09090009,0xdddd00dd, + 0x87870087,0x83830083,0xcdcd00cd,0x90900090, + 0x73730073,0xf6f600f6,0x9d9d009d,0xbfbf00bf, + 0x52520052,0xd8d800d8,0xc8c800c8,0xc6c600c6, + 0x81810081,0x6f6f006f,0x13130013,0x63630063, + 0xe9e900e9,0xa7a700a7,0x9f9f009f,0xbcbc00bc, + 0x29290029,0xf9f900f9,0x2f2f002f,0xb4b400b4, + 0x78780078,0x06060006,0xe7e700e7,0x71710071, + 0xd4d400d4,0xabab00ab,0x88880088,0x8d8d008d, + 0x72720072,0xb9b900b9,0xf8f800f8,0xacac00ac, + 0x36360036,0x2a2a002a,0x3c3c003c,0xf1f100f1, + 0x40400040,0xd3d300d3,0xbbbb00bb,0x43430043, + 0x15150015,0xadad00ad,0x77770077,0x80800080, + 0x82820082,0xecec00ec,0x27270027,0xe5e500e5, + 0x85850085,0x35350035,0x0c0c000c,0x41410041, + 0xefef00ef,0x93930093,0x19190019,0x21210021, + 0x0e0e000e,0x4e4e004e,0x65650065,0xbdbd00bd, + 0xb8b800b8,0x8f8f008f,0xebeb00eb,0xcece00ce, + 0x30300030,0x5f5f005f,0xc5c500c5,0x1a1a001a, + 0xe1e100e1,0xcaca00ca,0x47470047,0x3d3d003d, + 0x01010001,0xd6d600d6,0x56560056,0x4d4d004d, + 0x0d0d000d,0x66660066,0xcccc00cc,0x2d2d002d, + 0x12120012,0x20200020,0xb1b100b1,0x99990099, + 0x4c4c004c,0xc2c200c2,0x7e7e007e,0x05050005, + 0xb7b700b7,0x31310031,0x17170017,0xd7d700d7, + 0x58580058,0x61610061,0x1b1b001b,0x1c1c001c, + 0x0f0f000f,0x16160016,0x18180018,0x22220022, + 0x44440044,0xb2b200b2,0xb5b500b5,0x91910091, + 0x08080008,0xa8a800a8,0xfcfc00fc,0x50500050, + 0xd0d000d0,0x7d7d007d,0x89890089,0x97970097, + 0x5b5b005b,0x95950095,0xffff00ff,0xd2d200d2, + 0xc4c400c4,0x48480048,0xf7f700f7,0xdbdb00db, + 0x03030003,0xdada00da,0x3f3f003f,0x94940094, + 0x5c5c005c,0x02020002,0x4a4a004a,0x33330033, + 0x67670067,0xf3f300f3,0x7f7f007f,0xe2e200e2, + 0x9b9b009b,0x26260026,0x37370037,0x3b3b003b, + 0x96960096,0x4b4b004b,0xbebe00be,0x2e2e002e, + 0x79790079,0x8c8c008c,0x6e6e006e,0x8e8e008e, + 0xf5f500f5,0xb6b600b6,0xfdfd00fd,0x59590059, + 0x98980098,0x6a6a006a,0x46460046,0xbaba00ba, + 0x25250025,0x42420042,0xa2a200a2,0xfafa00fa, + 0x07070007,0x55550055,0xeeee00ee,0x0a0a000a, + 0x49490049,0x68680068,0x38380038,0xa4a400a4, + 0x28280028,0x7b7b007b,0xc9c900c9,0xc1c100c1, + 0xe3e300e3,0xf4f400f4,0xc7c700c7,0x9e9e009e, +}; + + +/** + * Stuff related to the Camellia key schedule + */ +#define subl(x) subL[(x)] +#define subr(x) subR[(x)] + +void camellia_setup128(const unsigned char *key, u32 *subkey) +{ + u32 kll, klr, krl, krr; + u32 il, ir, t0, t1, w0, w1; + u32 kw4l, kw4r, dw, tl, tr; + u32 subL[26]; + u32 subR[26]; + + /** + * k == kll || klr || krl || krr (|| is concatination) + */ + kll = GETU32(key ); + klr = GETU32(key + 4); + krl = GETU32(key + 8); + krr = GETU32(key + 12); + /** + * generate KL dependent subkeys + */ + subl(0) = kll; subr(0) = klr; + subl(1) = krl; subr(1) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); + subl(4) = kll; subr(4) = klr; + subl(5) = krl; subr(5) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); + subl(10) = kll; subr(10) = klr; + subl(11) = krl; subr(11) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); + subl(13) = krl; subr(13) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); + subl(16) = kll; subr(16) = klr; + subl(17) = krl; subr(17) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); + subl(18) = kll; subr(18) = klr; + subl(19) = krl; subr(19) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); + subl(22) = kll; subr(22) = klr; + subl(23) = krl; subr(23) = krr; + + /* generate KA */ + kll = subl(0); klr = subr(0); + krl = subl(1); krr = subr(1); + CAMELLIA_F(kll, klr, + CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, + w0, w1, il, ir, t0, t1); + krl ^= w0; krr ^= w1; + CAMELLIA_F(krl, krr, + CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, + kll, klr, il, ir, t0, t1); + CAMELLIA_F(kll, klr, + CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, + krl, krr, il, ir, t0, t1); + krl ^= w0; krr ^= w1; + CAMELLIA_F(krl, krr, + CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, + w0, w1, il, ir, t0, t1); + kll ^= w0; klr ^= w1; + + /* generate KA dependent subkeys */ + subl(2) = kll; subr(2) = klr; + subl(3) = krl; subr(3) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); + subl(6) = kll; subr(6) = klr; + subl(7) = krl; subr(7) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); + subl(8) = kll; subr(8) = klr; + subl(9) = krl; subr(9) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); + subl(12) = kll; subr(12) = klr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); + subl(14) = kll; subr(14) = klr; + subl(15) = krl; subr(15) = krr; + CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); + subl(20) = kll; subr(20) = klr; + subl(21) = krl; subr(21) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); + subl(24) = kll; subr(24) = klr; + subl(25) = krl; subr(25) = krr; + + + /* absorb kw2 to other subkeys */ + subl(3) ^= subl(1); subr(3) ^= subr(1); + subl(5) ^= subl(1); subr(5) ^= subr(1); + subl(7) ^= subl(1); subr(7) ^= subr(1); + subl(1) ^= subr(1) & ~subr(9); + dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); + subl(11) ^= subl(1); subr(11) ^= subr(1); + subl(13) ^= subl(1); subr(13) ^= subr(1); + subl(15) ^= subl(1); subr(15) ^= subr(1); + subl(1) ^= subr(1) & ~subr(17); + dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); + subl(19) ^= subl(1); subr(19) ^= subr(1); + subl(21) ^= subl(1); subr(21) ^= subr(1); + subl(23) ^= subl(1); subr(23) ^= subr(1); + subl(24) ^= subl(1); subr(24) ^= subr(1); + + /* absorb kw4 to other subkeys */ + kw4l = subl(25); kw4r = subr(25); + subl(22) ^= kw4l; subr(22) ^= kw4r; + subl(20) ^= kw4l; subr(20) ^= kw4r; + subl(18) ^= kw4l; subr(18) ^= kw4r; + kw4l ^= kw4r & ~subr(16); + dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw); + subl(14) ^= kw4l; subr(14) ^= kw4r; + subl(12) ^= kw4l; subr(12) ^= kw4r; + subl(10) ^= kw4l; subr(10) ^= kw4r; + kw4l ^= kw4r & ~subr(8); + dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw); + subl(6) ^= kw4l; subr(6) ^= kw4r; + subl(4) ^= kw4l; subr(4) ^= kw4r; + subl(2) ^= kw4l; subr(2) ^= kw4r; + subl(0) ^= kw4l; subr(0) ^= kw4r; + + /* key XOR is end of F-function */ + CamelliaSubkeyL(0) = subl(0) ^ subl(2); + CamelliaSubkeyR(0) = subr(0) ^ subr(2); + CamelliaSubkeyL(2) = subl(3); + CamelliaSubkeyR(2) = subr(3); + CamelliaSubkeyL(3) = subl(2) ^ subl(4); + CamelliaSubkeyR(3) = subr(2) ^ subr(4); + CamelliaSubkeyL(4) = subl(3) ^ subl(5); + CamelliaSubkeyR(4) = subr(3) ^ subr(5); + CamelliaSubkeyL(5) = subl(4) ^ subl(6); + CamelliaSubkeyR(5) = subr(4) ^ subr(6); + CamelliaSubkeyL(6) = subl(5) ^ subl(7); + CamelliaSubkeyR(6) = subr(5) ^ subr(7); + tl = subl(10) ^ (subr(10) & ~subr(8)); + dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); + CamelliaSubkeyL(7) = subl(6) ^ tl; + CamelliaSubkeyR(7) = subr(6) ^ tr; + CamelliaSubkeyL(8) = subl(8); + CamelliaSubkeyR(8) = subr(8); + CamelliaSubkeyL(9) = subl(9); + CamelliaSubkeyR(9) = subr(9); + tl = subl(7) ^ (subr(7) & ~subr(9)); + dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); + CamelliaSubkeyL(10) = tl ^ subl(11); + CamelliaSubkeyR(10) = tr ^ subr(11); + CamelliaSubkeyL(11) = subl(10) ^ subl(12); + CamelliaSubkeyR(11) = subr(10) ^ subr(12); + CamelliaSubkeyL(12) = subl(11) ^ subl(13); + CamelliaSubkeyR(12) = subr(11) ^ subr(13); + CamelliaSubkeyL(13) = subl(12) ^ subl(14); + CamelliaSubkeyR(13) = subr(12) ^ subr(14); + CamelliaSubkeyL(14) = subl(13) ^ subl(15); + CamelliaSubkeyR(14) = subr(13) ^ subr(15); + tl = subl(18) ^ (subr(18) & ~subr(16)); + dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); + CamelliaSubkeyL(15) = subl(14) ^ tl; + CamelliaSubkeyR(15) = subr(14) ^ tr; + CamelliaSubkeyL(16) = subl(16); + CamelliaSubkeyR(16) = subr(16); + CamelliaSubkeyL(17) = subl(17); + CamelliaSubkeyR(17) = subr(17); + tl = subl(15) ^ (subr(15) & ~subr(17)); + dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); + CamelliaSubkeyL(18) = tl ^ subl(19); + CamelliaSubkeyR(18) = tr ^ subr(19); + CamelliaSubkeyL(19) = subl(18) ^ subl(20); + CamelliaSubkeyR(19) = subr(18) ^ subr(20); + CamelliaSubkeyL(20) = subl(19) ^ subl(21); + CamelliaSubkeyR(20) = subr(19) ^ subr(21); + CamelliaSubkeyL(21) = subl(20) ^ subl(22); + CamelliaSubkeyR(21) = subr(20) ^ subr(22); + CamelliaSubkeyL(22) = subl(21) ^ subl(23); + CamelliaSubkeyR(22) = subr(21) ^ subr(23); + CamelliaSubkeyL(23) = subl(22); + CamelliaSubkeyR(23) = subr(22); + CamelliaSubkeyL(24) = subl(24) ^ subl(23); + CamelliaSubkeyR(24) = subr(24) ^ subr(23); + + /* apply the inverse of the last half of P-function */ + dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw; + dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw; + dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw; + dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw; + dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw; + dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw; + dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw; + dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw; + dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw; + dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw; + dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw; + dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw; + dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw; + dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw; + dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw; + dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw; + dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw; + dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw; + + return; +} + +void camellia_setup256(const unsigned char *key, u32 *subkey) +{ + u32 kll,klr,krl,krr; /* left half of key */ + u32 krll,krlr,krrl,krrr; /* right half of key */ + u32 il, ir, t0, t1, w0, w1; /* temporary variables */ + u32 kw4l, kw4r, dw, tl, tr; + u32 subL[34]; + u32 subR[34]; + + /** + * key = (kll || klr || krl || krr || krll || krlr || krrl || krrr) + * (|| is concatination) + */ + + kll = GETU32(key ); + klr = GETU32(key + 4); + krl = GETU32(key + 8); + krr = GETU32(key + 12); + krll = GETU32(key + 16); + krlr = GETU32(key + 20); + krrl = GETU32(key + 24); + krrr = GETU32(key + 28); + + /* generate KL dependent subkeys */ + subl(0) = kll; subr(0) = klr; + subl(1) = krl; subr(1) = krr; + CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 45); + subl(12) = kll; subr(12) = klr; + subl(13) = krl; subr(13) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); + subl(16) = kll; subr(16) = klr; + subl(17) = krl; subr(17) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 17); + subl(22) = kll; subr(22) = klr; + subl(23) = krl; subr(23) = krr; + CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 34); + subl(30) = kll; subr(30) = klr; + subl(31) = krl; subr(31) = krr; + + /* generate KR dependent subkeys */ + CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); + subl(4) = krll; subr(4) = krlr; + subl(5) = krrl; subr(5) = krrr; + CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 15); + subl(8) = krll; subr(8) = krlr; + subl(9) = krrl; subr(9) = krrr; + CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); + subl(18) = krll; subr(18) = krlr; + subl(19) = krrl; subr(19) = krrr; + CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); + subl(26) = krll; subr(26) = krlr; + subl(27) = krrl; subr(27) = krrr; + CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 34); + + /* generate KA */ + kll = subl(0) ^ krll; klr = subr(0) ^ krlr; + krl = subl(1) ^ krrl; krr = subr(1) ^ krrr; + CAMELLIA_F(kll, klr, + CAMELLIA_SIGMA1L, CAMELLIA_SIGMA1R, + w0, w1, il, ir, t0, t1); + krl ^= w0; krr ^= w1; + CAMELLIA_F(krl, krr, + CAMELLIA_SIGMA2L, CAMELLIA_SIGMA2R, + kll, klr, il, ir, t0, t1); + kll ^= krll; klr ^= krlr; + CAMELLIA_F(kll, klr, + CAMELLIA_SIGMA3L, CAMELLIA_SIGMA3R, + krl, krr, il, ir, t0, t1); + krl ^= w0 ^ krrl; krr ^= w1 ^ krrr; + CAMELLIA_F(krl, krr, + CAMELLIA_SIGMA4L, CAMELLIA_SIGMA4R, + w0, w1, il, ir, t0, t1); + kll ^= w0; klr ^= w1; + + /* generate KB */ + krll ^= kll; krlr ^= klr; + krrl ^= krl; krrr ^= krr; + CAMELLIA_F(krll, krlr, + CAMELLIA_SIGMA5L, CAMELLIA_SIGMA5R, + w0, w1, il, ir, t0, t1); + krrl ^= w0; krrr ^= w1; + CAMELLIA_F(krrl, krrr, + CAMELLIA_SIGMA6L, CAMELLIA_SIGMA6R, + w0, w1, il, ir, t0, t1); + krll ^= w0; krlr ^= w1; + + /* generate KA dependent subkeys */ + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 15); + subl(6) = kll; subr(6) = klr; + subl(7) = krl; subr(7) = krr; + CAMELLIA_ROLDQ(kll, klr, krl, krr, w0, w1, 30); + subl(14) = kll; subr(14) = klr; + subl(15) = krl; subr(15) = krr; + subl(24) = klr; subr(24) = krl; + subl(25) = krr; subr(25) = kll; + CAMELLIA_ROLDQo32(kll, klr, krl, krr, w0, w1, 49); + subl(28) = kll; subr(28) = klr; + subl(29) = krl; subr(29) = krr; + + /* generate KB dependent subkeys */ + subl(2) = krll; subr(2) = krlr; + subl(3) = krrl; subr(3) = krrr; + CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); + subl(10) = krll; subr(10) = krlr; + subl(11) = krrl; subr(11) = krrr; + CAMELLIA_ROLDQ(krll, krlr, krrl, krrr, w0, w1, 30); + subl(20) = krll; subr(20) = krlr; + subl(21) = krrl; subr(21) = krrr; + CAMELLIA_ROLDQo32(krll, krlr, krrl, krrr, w0, w1, 51); + subl(32) = krll; subr(32) = krlr; + subl(33) = krrl; subr(33) = krrr; + + /* absorb kw2 to other subkeys */ + subl(3) ^= subl(1); subr(3) ^= subr(1); + subl(5) ^= subl(1); subr(5) ^= subr(1); + subl(7) ^= subl(1); subr(7) ^= subr(1); + subl(1) ^= subr(1) & ~subr(9); + dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); + subl(11) ^= subl(1); subr(11) ^= subr(1); + subl(13) ^= subl(1); subr(13) ^= subr(1); + subl(15) ^= subl(1); subr(15) ^= subr(1); + subl(1) ^= subr(1) & ~subr(17); + dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); + subl(19) ^= subl(1); subr(19) ^= subr(1); + subl(21) ^= subl(1); subr(21) ^= subr(1); + subl(23) ^= subl(1); subr(23) ^= subr(1); + subl(1) ^= subr(1) & ~subr(25); + dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw); + subl(27) ^= subl(1); subr(27) ^= subr(1); + subl(29) ^= subl(1); subr(29) ^= subr(1); + subl(31) ^= subl(1); subr(31) ^= subr(1); + subl(32) ^= subl(1); subr(32) ^= subr(1); + + /* absorb kw4 to other subkeys */ + kw4l = subl(33); kw4r = subr(33); + subl(30) ^= kw4l; subr(30) ^= kw4r; + subl(28) ^= kw4l; subr(28) ^= kw4r; + subl(26) ^= kw4l; subr(26) ^= kw4r; + kw4l ^= kw4r & ~subr(24); + dw = kw4l & subl(24), kw4r ^= CAMELLIA_RL1(dw); + subl(22) ^= kw4l; subr(22) ^= kw4r; + subl(20) ^= kw4l; subr(20) ^= kw4r; + subl(18) ^= kw4l; subr(18) ^= kw4r; + kw4l ^= kw4r & ~subr(16); + dw = kw4l & subl(16), kw4r ^= CAMELLIA_RL1(dw); + subl(14) ^= kw4l; subr(14) ^= kw4r; + subl(12) ^= kw4l; subr(12) ^= kw4r; + subl(10) ^= kw4l; subr(10) ^= kw4r; + kw4l ^= kw4r & ~subr(8); + dw = kw4l & subl(8), kw4r ^= CAMELLIA_RL1(dw); + subl(6) ^= kw4l; subr(6) ^= kw4r; + subl(4) ^= kw4l; subr(4) ^= kw4r; + subl(2) ^= kw4l; subr(2) ^= kw4r; + subl(0) ^= kw4l; subr(0) ^= kw4r; + + /* key XOR is end of F-function */ + CamelliaSubkeyL(0) = subl(0) ^ subl(2); + CamelliaSubkeyR(0) = subr(0) ^ subr(2); + CamelliaSubkeyL(2) = subl(3); + CamelliaSubkeyR(2) = subr(3); + CamelliaSubkeyL(3) = subl(2) ^ subl(4); + CamelliaSubkeyR(3) = subr(2) ^ subr(4); + CamelliaSubkeyL(4) = subl(3) ^ subl(5); + CamelliaSubkeyR(4) = subr(3) ^ subr(5); + CamelliaSubkeyL(5) = subl(4) ^ subl(6); + CamelliaSubkeyR(5) = subr(4) ^ subr(6); + CamelliaSubkeyL(6) = subl(5) ^ subl(7); + CamelliaSubkeyR(6) = subr(5) ^ subr(7); + tl = subl(10) ^ (subr(10) & ~subr(8)); + dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); + CamelliaSubkeyL(7) = subl(6) ^ tl; + CamelliaSubkeyR(7) = subr(6) ^ tr; + CamelliaSubkeyL(8) = subl(8); + CamelliaSubkeyR(8) = subr(8); + CamelliaSubkeyL(9) = subl(9); + CamelliaSubkeyR(9) = subr(9); + tl = subl(7) ^ (subr(7) & ~subr(9)); + dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); + CamelliaSubkeyL(10) = tl ^ subl(11); + CamelliaSubkeyR(10) = tr ^ subr(11); + CamelliaSubkeyL(11) = subl(10) ^ subl(12); + CamelliaSubkeyR(11) = subr(10) ^ subr(12); + CamelliaSubkeyL(12) = subl(11) ^ subl(13); + CamelliaSubkeyR(12) = subr(11) ^ subr(13); + CamelliaSubkeyL(13) = subl(12) ^ subl(14); + CamelliaSubkeyR(13) = subr(12) ^ subr(14); + CamelliaSubkeyL(14) = subl(13) ^ subl(15); + CamelliaSubkeyR(14) = subr(13) ^ subr(15); + tl = subl(18) ^ (subr(18) & ~subr(16)); + dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); + CamelliaSubkeyL(15) = subl(14) ^ tl; + CamelliaSubkeyR(15) = subr(14) ^ tr; + CamelliaSubkeyL(16) = subl(16); + CamelliaSubkeyR(16) = subr(16); + CamelliaSubkeyL(17) = subl(17); + CamelliaSubkeyR(17) = subr(17); + tl = subl(15) ^ (subr(15) & ~subr(17)); + dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); + CamelliaSubkeyL(18) = tl ^ subl(19); + CamelliaSubkeyR(18) = tr ^ subr(19); + CamelliaSubkeyL(19) = subl(18) ^ subl(20); + CamelliaSubkeyR(19) = subr(18) ^ subr(20); + CamelliaSubkeyL(20) = subl(19) ^ subl(21); + CamelliaSubkeyR(20) = subr(19) ^ subr(21); + CamelliaSubkeyL(21) = subl(20) ^ subl(22); + CamelliaSubkeyR(21) = subr(20) ^ subr(22); + CamelliaSubkeyL(22) = subl(21) ^ subl(23); + CamelliaSubkeyR(22) = subr(21) ^ subr(23); + tl = subl(26) ^ (subr(26) & ~subr(24)); + dw = tl & subl(24), tr = subr(26) ^ CAMELLIA_RL1(dw); + CamelliaSubkeyL(23) = subl(22) ^ tl; + CamelliaSubkeyR(23) = subr(22) ^ tr; + CamelliaSubkeyL(24) = subl(24); + CamelliaSubkeyR(24) = subr(24); + CamelliaSubkeyL(25) = subl(25); + CamelliaSubkeyR(25) = subr(25); + tl = subl(23) ^ (subr(23) & ~subr(25)); + dw = tl & subl(25), tr = subr(23) ^ CAMELLIA_RL1(dw); + CamelliaSubkeyL(26) = tl ^ subl(27); + CamelliaSubkeyR(26) = tr ^ subr(27); + CamelliaSubkeyL(27) = subl(26) ^ subl(28); + CamelliaSubkeyR(27) = subr(26) ^ subr(28); + CamelliaSubkeyL(28) = subl(27) ^ subl(29); + CamelliaSubkeyR(28) = subr(27) ^ subr(29); + CamelliaSubkeyL(29) = subl(28) ^ subl(30); + CamelliaSubkeyR(29) = subr(28) ^ subr(30); + CamelliaSubkeyL(30) = subl(29) ^ subl(31); + CamelliaSubkeyR(30) = subr(29) ^ subr(31); + CamelliaSubkeyL(31) = subl(30); + CamelliaSubkeyR(31) = subr(30); + CamelliaSubkeyL(32) = subl(32) ^ subl(31); + CamelliaSubkeyR(32) = subr(32) ^ subr(31); + + /* apply the inverse of the last half of P-function */ + dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw; + dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw; + dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw; + dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw; + dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw; + dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw; + dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw; + dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw; + dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw; + dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw; + dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw; + dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw; + dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw; + dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw; + dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw; + dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw; + dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw; + dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw; + dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw; + dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw; + dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw; + dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw; + dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw; + dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw); + CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw; + + return; +} + +void camellia_setup192(const unsigned char *key, u32 *subkey) +{ + unsigned char kk[32]; + u32 krll, krlr, krrl,krrr; + + memcpy(kk, key, 24); + memcpy((unsigned char *)&krll, key+16,4); + memcpy((unsigned char *)&krlr, key+20,4); + krrl = ~krll; + krrr = ~krlr; + memcpy(kk+24, (unsigned char *)&krrl, 4); + memcpy(kk+28, (unsigned char *)&krrr, 4); + camellia_setup256(kk, subkey); + return; +} + + +/** + * Stuff related to camellia encryption/decryption + * + * "io" must be 4byte aligned and big-endian data. + */ +void camellia_encrypt128(const u32 *subkey, u32 *io) +{ + u32 il, ir, t0, t1; + + /* pre whitening but absorb kw2*/ + io[0] ^= CamelliaSubkeyL(0); + io[1] ^= CamelliaSubkeyR(0); + /* main iteration */ + + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(2),CamelliaSubkeyR(2), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(3),CamelliaSubkeyR(3), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(4),CamelliaSubkeyR(4), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(5),CamelliaSubkeyR(5), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(6),CamelliaSubkeyR(6), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(7),CamelliaSubkeyR(7), + io[0],io[1],il,ir,t0,t1); + + CAMELLIA_FLS(io[0],io[1],io[2],io[3], + CamelliaSubkeyL(8),CamelliaSubkeyR(8), + CamelliaSubkeyL(9),CamelliaSubkeyR(9), + t0,t1,il,ir); + + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(10),CamelliaSubkeyR(10), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(11),CamelliaSubkeyR(11), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(12),CamelliaSubkeyR(12), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(13),CamelliaSubkeyR(13), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(14),CamelliaSubkeyR(14), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(15),CamelliaSubkeyR(15), + io[0],io[1],il,ir,t0,t1); + + CAMELLIA_FLS(io[0],io[1],io[2],io[3], + CamelliaSubkeyL(16),CamelliaSubkeyR(16), + CamelliaSubkeyL(17),CamelliaSubkeyR(17), + t0,t1,il,ir); + + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(18),CamelliaSubkeyR(18), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(19),CamelliaSubkeyR(19), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(20),CamelliaSubkeyR(20), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(21),CamelliaSubkeyR(21), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(22),CamelliaSubkeyR(22), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(23),CamelliaSubkeyR(23), + io[0],io[1],il,ir,t0,t1); + + /* post whitening but kw4 */ + io[2] ^= CamelliaSubkeyL(24); + io[3] ^= CamelliaSubkeyR(24); + + t0 = io[0]; + t1 = io[1]; + io[0] = io[2]; + io[1] = io[3]; + io[2] = t0; + io[3] = t1; + + return; +} + +void camellia_decrypt128(const u32 *subkey, u32 *io) +{ + u32 il,ir,t0,t1; /* temporary valiables */ + + /* pre whitening but absorb kw2*/ + io[0] ^= CamelliaSubkeyL(24); + io[1] ^= CamelliaSubkeyR(24); + + /* main iteration */ + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(23),CamelliaSubkeyR(23), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(22),CamelliaSubkeyR(22), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(21),CamelliaSubkeyR(21), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(20),CamelliaSubkeyR(20), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(19),CamelliaSubkeyR(19), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(18),CamelliaSubkeyR(18), + io[0],io[1],il,ir,t0,t1); + + CAMELLIA_FLS(io[0],io[1],io[2],io[3], + CamelliaSubkeyL(17),CamelliaSubkeyR(17), + CamelliaSubkeyL(16),CamelliaSubkeyR(16), + t0,t1,il,ir); + + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(15),CamelliaSubkeyR(15), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(14),CamelliaSubkeyR(14), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(13),CamelliaSubkeyR(13), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(12),CamelliaSubkeyR(12), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(11),CamelliaSubkeyR(11), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(10),CamelliaSubkeyR(10), + io[0],io[1],il,ir,t0,t1); + + CAMELLIA_FLS(io[0],io[1],io[2],io[3], + CamelliaSubkeyL(9),CamelliaSubkeyR(9), + CamelliaSubkeyL(8),CamelliaSubkeyR(8), + t0,t1,il,ir); + + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(7),CamelliaSubkeyR(7), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(6),CamelliaSubkeyR(6), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(5),CamelliaSubkeyR(5), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(4),CamelliaSubkeyR(4), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(3),CamelliaSubkeyR(3), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(2),CamelliaSubkeyR(2), + io[0],io[1],il,ir,t0,t1); + + /* post whitening but kw4 */ + io[2] ^= CamelliaSubkeyL(0); + io[3] ^= CamelliaSubkeyR(0); + + t0 = io[0]; + t1 = io[1]; + io[0] = io[2]; + io[1] = io[3]; + io[2] = t0; + io[3] = t1; + + return; +} + +/** + * stuff for 192 and 256bit encryption/decryption + */ +void camellia_encrypt256(const u32 *subkey, u32 *io) +{ + u32 il,ir,t0,t1; /* temporary valiables */ + + /* pre whitening but absorb kw2*/ + io[0] ^= CamelliaSubkeyL(0); + io[1] ^= CamelliaSubkeyR(0); + + /* main iteration */ + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(2),CamelliaSubkeyR(2), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(3),CamelliaSubkeyR(3), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(4),CamelliaSubkeyR(4), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(5),CamelliaSubkeyR(5), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(6),CamelliaSubkeyR(6), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(7),CamelliaSubkeyR(7), + io[0],io[1],il,ir,t0,t1); + + CAMELLIA_FLS(io[0],io[1],io[2],io[3], + CamelliaSubkeyL(8),CamelliaSubkeyR(8), + CamelliaSubkeyL(9),CamelliaSubkeyR(9), + t0,t1,il,ir); + + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(10),CamelliaSubkeyR(10), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(11),CamelliaSubkeyR(11), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(12),CamelliaSubkeyR(12), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(13),CamelliaSubkeyR(13), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(14),CamelliaSubkeyR(14), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(15),CamelliaSubkeyR(15), + io[0],io[1],il,ir,t0,t1); + + CAMELLIA_FLS(io[0],io[1],io[2],io[3], + CamelliaSubkeyL(16),CamelliaSubkeyR(16), + CamelliaSubkeyL(17),CamelliaSubkeyR(17), + t0,t1,il,ir); + + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(18),CamelliaSubkeyR(18), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(19),CamelliaSubkeyR(19), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(20),CamelliaSubkeyR(20), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(21),CamelliaSubkeyR(21), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(22),CamelliaSubkeyR(22), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(23),CamelliaSubkeyR(23), + io[0],io[1],il,ir,t0,t1); + + CAMELLIA_FLS(io[0],io[1],io[2],io[3], + CamelliaSubkeyL(24),CamelliaSubkeyR(24), + CamelliaSubkeyL(25),CamelliaSubkeyR(25), + t0,t1,il,ir); + + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(26),CamelliaSubkeyR(26), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(27),CamelliaSubkeyR(27), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(28),CamelliaSubkeyR(28), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(29),CamelliaSubkeyR(29), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(30),CamelliaSubkeyR(30), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(31),CamelliaSubkeyR(31), + io[0],io[1],il,ir,t0,t1); + + /* post whitening but kw4 */ + io[2] ^= CamelliaSubkeyL(32); + io[3] ^= CamelliaSubkeyR(32); + + t0 = io[0]; + t1 = io[1]; + io[0] = io[2]; + io[1] = io[3]; + io[2] = t0; + io[3] = t1; + + return; +} + +void camellia_decrypt256(const u32 *subkey, u32 *io) +{ + u32 il,ir,t0,t1; /* temporary valiables */ + + /* pre whitening but absorb kw2*/ + io[0] ^= CamelliaSubkeyL(32); + io[1] ^= CamelliaSubkeyR(32); + + /* main iteration */ + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(31),CamelliaSubkeyR(31), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(30),CamelliaSubkeyR(30), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(29),CamelliaSubkeyR(29), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(28),CamelliaSubkeyR(28), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(27),CamelliaSubkeyR(27), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(26),CamelliaSubkeyR(26), + io[0],io[1],il,ir,t0,t1); + + CAMELLIA_FLS(io[0],io[1],io[2],io[3], + CamelliaSubkeyL(25),CamelliaSubkeyR(25), + CamelliaSubkeyL(24),CamelliaSubkeyR(24), + t0,t1,il,ir); + + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(23),CamelliaSubkeyR(23), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(22),CamelliaSubkeyR(22), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(21),CamelliaSubkeyR(21), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(20),CamelliaSubkeyR(20), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(19),CamelliaSubkeyR(19), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(18),CamelliaSubkeyR(18), + io[0],io[1],il,ir,t0,t1); + + CAMELLIA_FLS(io[0],io[1],io[2],io[3], + CamelliaSubkeyL(17),CamelliaSubkeyR(17), + CamelliaSubkeyL(16),CamelliaSubkeyR(16), + t0,t1,il,ir); + + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(15),CamelliaSubkeyR(15), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(14),CamelliaSubkeyR(14), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(13),CamelliaSubkeyR(13), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(12),CamelliaSubkeyR(12), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(11),CamelliaSubkeyR(11), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(10),CamelliaSubkeyR(10), + io[0],io[1],il,ir,t0,t1); + + CAMELLIA_FLS(io[0],io[1],io[2],io[3], + CamelliaSubkeyL(9),CamelliaSubkeyR(9), + CamelliaSubkeyL(8),CamelliaSubkeyR(8), + t0,t1,il,ir); + + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(7),CamelliaSubkeyR(7), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(6),CamelliaSubkeyR(6), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(5),CamelliaSubkeyR(5), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(4),CamelliaSubkeyR(4), + io[0],io[1],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[0],io[1], + CamelliaSubkeyL(3),CamelliaSubkeyR(3), + io[2],io[3],il,ir,t0,t1); + CAMELLIA_ROUNDSM(io[2],io[3], + CamelliaSubkeyL(2),CamelliaSubkeyR(2), + io[0],io[1],il,ir,t0,t1); + + /* post whitening but kw4 */ + io[2] ^= CamelliaSubkeyL(0); + io[3] ^= CamelliaSubkeyR(0); + + t0 = io[0]; + t1 = io[1]; + io[0] = io[2]; + io[1] = io[3]; + io[2] = t0; + io[3] = t1; + + return; +} + +/*** + * + * API for compatibility + */ + +void Camellia_Ekeygen(const int keyBitLength, + const unsigned char *rawKey, + KEY_TABLE_TYPE keyTable) +{ + switch(keyBitLength) { + case 128: + camellia_setup128(rawKey, keyTable); + break; + case 192: + camellia_setup192(rawKey, keyTable); + break; + case 256: + camellia_setup256(rawKey, keyTable); + break; + default: + break; + } +} + + +void Camellia_EncryptBlock(const int keyBitLength, + const unsigned char *plaintext, + const KEY_TABLE_TYPE keyTable, + unsigned char *ciphertext) +{ + u32 tmp[4]; + + tmp[0] = GETU32(plaintext); + tmp[1] = GETU32(plaintext + 4); + tmp[2] = GETU32(plaintext + 8); + tmp[3] = GETU32(plaintext + 12); + + switch (keyBitLength) { + case 128: + camellia_encrypt128(keyTable, tmp); + break; + case 192: + /* fall through */ + case 256: + camellia_encrypt256(keyTable, tmp); + break; + default: + break; + } + + PUTU32(ciphertext, tmp[0]); + PUTU32(ciphertext + 4, tmp[1]); + PUTU32(ciphertext + 8, tmp[2]); + PUTU32(ciphertext + 12, tmp[3]); +} + +void Camellia_DecryptBlock(const int keyBitLength, + const unsigned char *ciphertext, + const KEY_TABLE_TYPE keyTable, + unsigned char *plaintext) +{ + u32 tmp[4]; + + tmp[0] = GETU32(ciphertext); + tmp[1] = GETU32(ciphertext + 4); + tmp[2] = GETU32(ciphertext + 8); + tmp[3] = GETU32(ciphertext + 12); + + switch (keyBitLength) { + case 128: + camellia_decrypt128(keyTable, tmp); + break; + case 192: + /* fall through */ + case 256: + camellia_decrypt256(keyTable, tmp); + break; + default: + break; + } + PUTU32(plaintext, tmp[0]); + PUTU32(plaintext + 4, tmp[1]); + PUTU32(plaintext + 8, tmp[2]); + PUTU32(plaintext + 12, tmp[3]); +} Added: branches/STABLE-BRANCH-1-4/cipher/camellia.h =================================================================== --- branches/STABLE-BRANCH-1-4/cipher/camellia.h 2007-06-12 20:19:31 UTC (rev 4510) +++ branches/STABLE-BRANCH-1-4/cipher/camellia.h 2007-06-13 15:28:11 UTC (rev 4511) @@ -0,0 +1,54 @@ +/* camellia.h ver 1.2.0 + * + * Copyright (C) 2006,2007 + * NTT (Nippon Telegraph and Telephone Corporation). + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef HEADER_CAMELLIA_H +#define HEADER_CAMELLIA_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define CAMELLIA_BLOCK_SIZE 16 +#define CAMELLIA_TABLE_BYTE_LEN 272 +#define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) + +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; + + +void Camellia_Ekeygen(const int keyBitLength, + const unsigned char *rawKey, + KEY_TABLE_TYPE keyTable); + +void Camellia_EncryptBlock(const int keyBitLength, + const unsigned char *plaintext, + const KEY_TABLE_TYPE keyTable, + unsigned char *cipherText); + +void Camellia_DecryptBlock(const int keyBitLength, + const unsigned char *cipherText, + const KEY_TABLE_TYPE keyTable, + unsigned char *plaintext); + + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_CAMELLIA_H */ Modified: branches/STABLE-BRANCH-1-4/cipher/cipher.c =================================================================== --- branches/STABLE-BRANCH-1-4/cipher/cipher.c 2007-06-12 20:19:31 UTC (rev 4510) +++ branches/STABLE-BRANCH-1-4/cipher/cipher.c 2007-06-13 15:28:11 UTC (rev 4511) @@ -1,5 +1,6 @@ /* cipher.c - cipher dispatcher - * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 + * 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -178,6 +179,20 @@ BUG(); i++; +#ifdef USE_CAMELLIA + cipher_table[i].algo = CIPHER_ALGO_CAMELLIA; + cipher_table[i].name = camellia_get_info( cipher_table[i].algo, + &cipher_table[i].keylen, + &cipher_table[i].blocksize, + &cipher_table[i].contextsize, + &cipher_table[i].setkey, + &cipher_table[i].encrypt, + &cipher_table[i].decrypt ); + if( !cipher_table[i].name ) + BUG(); + i++; +#endif + #ifdef USE_IDEA cipher_table[i].algo = CIPHER_ALGO_IDEA; cipher_table[i].name = idea_get_info( cipher_table[i].algo, Modified: branches/STABLE-BRANCH-1-4/configure.ac =================================================================== --- branches/STABLE-BRANCH-1-4/configure.ac 2007-06-12 20:19:31 UTC (rev 4510) +++ branches/STABLE-BRANCH-1-4/configure.ac 2007-06-13 15:28:11 UTC (rev 4511) @@ -1,6 +1,6 @@ dnl configure.ac script for GnuPG -dnl Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, -dnl 2006 Free Software Foundation, Inc. +dnl Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, +dnl 2007 Free Software Foundation, Inc. dnl dnl This file is part of GnuPG. dnl @@ -140,6 +140,7 @@ use_blowfish=yes use_aes=yes use_twofish=yes +use_camellia=no use_sha256=yes use_sha512=yes use_bzip2=yes @@ -158,6 +159,7 @@ use_blowfish=no use_aes=no use_twofish=no + use_camellia=no use_sha256=no use_sha512=no use_bzip2=no @@ -255,7 +257,20 @@ AC_DEFINE(USE_TWOFISH,1,[Define to include the TWOFISH cipher]) fi -AC_MSG_CHECKING([whether to enable the SHA-256 digest]) +AC_MSG_CHECKING([whether to enable the CAMELLIA cipher]) +AC_ARG_ENABLE(camellia, + AC_HELP_STRING([--enable-camellia],[enable the CAMELLIA cipher]), + use_camellia=$enableval) +AC_MSG_RESULT($use_camellia) +if test x"$use_camellia" = xyes ; then + AC_DEFINE(USE_CAMELLIA,1,[Define to include the CAMELLIA cipher]) + AC_MSG_WARN([[ +*** +*** The Camellia cipher is for testing only and is NOT for production use! +***]]) +fi + +AC_MSG_CHECKING([whether to enable the SHA-224 and SHA-256 digests]) AC_ARG_ENABLE(sha256, AC_HELP_STRING([--disable-sha256],[disable the SHA-224 and SHA-256 digests]), use_sha256=$enableval) @@ -1407,3 +1422,8 @@ echo " Extra cpu specific functions:$show_extraasm" fi echo + +if test x"$use_camellia" = xyes ; then + echo "WARNING: The Camellia cipher is for testing only and is NOT for production use!" + echo +fi Modified: branches/STABLE-BRANCH-1-4/include/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/include/ChangeLog 2007-06-12 20:19:31 UTC (rev 4510) +++ branches/STABLE-BRANCH-1-4/include/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) @@ -1,3 +1,7 @@ +2007-06-13 David Shaw + + * cipher.h (CIPHER_ALGO_CAMELLIA): Add Camellia define. + 2007-04-16 David Shaw * util.h (ascii_toupper, ascii_tolower, ascii_strcasecmp, Modified: branches/STABLE-BRANCH-1-4/include/cipher.h =================================================================== --- branches/STABLE-BRANCH-1-4/include/cipher.h 2007-06-12 20:19:31 UTC (rev 4510) +++ branches/STABLE-BRANCH-1-4/include/cipher.h 2007-06-13 15:28:11 UTC (rev 4511) @@ -1,6 +1,6 @@ /* cipher.h - * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, - * 2006 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, + * 2007 Free Software Foundation, Inc. * * This file is part of GNUPG. * @@ -38,6 +38,8 @@ #define CIPHER_ALGO_AES192 8 #define CIPHER_ALGO_AES256 9 #define CIPHER_ALGO_TWOFISH 10 /* twofish 256 bit */ +#define CIPHER_ALGO_CAMELLIA 11 /* camellia 256 bit */ + #define CIPHER_ALGO_DUMMY 110 /* no encryption at all */ #define PUBKEY_ALGO_RSA 1 From cvs at cvs.gnupg.org Thu Jun 14 19:05:47 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 14 Jun 2007 19:05:47 +0200 Subject: [svn] GnuPG - r4512 - in trunk: . agent am common doc g10 jnlib kbx keyserver scd sm tools Message-ID: Author: wk Date: 2007-06-14 19:05:07 +0200 (Thu, 14 Jun 2007) New Revision: 4512 Added: trunk/common/init.c Modified: trunk/ChangeLog trunk/NEWS trunk/agent/ChangeLog trunk/agent/Makefile.am trunk/agent/agent.h trunk/agent/call-pinentry.c trunk/agent/call-scd.c trunk/agent/gpg-agent.c trunk/agent/minip12.c trunk/agent/preset-passphrase.c trunk/agent/protect-tool.c trunk/agent/trustlist.c trunk/am/cmacros.am trunk/common/ChangeLog trunk/common/Makefile.am trunk/common/estream.c trunk/common/homedir.c trunk/common/http.c trunk/common/simple-pwquery.c trunk/common/simple-pwquery.h trunk/common/util.h trunk/configure.ac trunk/doc/gpgsm.texi trunk/g10/ChangeLog trunk/g10/Makefile.am trunk/g10/call-agent.c trunk/g10/gpg.c trunk/g10/gpgv.c trunk/g10/keyserver.c trunk/g10/misc.c trunk/g10/openfile.c trunk/jnlib/ChangeLog trunk/jnlib/utf8conv.c trunk/jnlib/utf8conv.h trunk/kbx/ChangeLog trunk/kbx/kbxutil.c trunk/keyserver/ChangeLog trunk/keyserver/gpgkeys_hkp.c trunk/scd/ChangeLog trunk/scd/Makefile.am trunk/scd/apdu.c trunk/scd/command.c trunk/scd/scdaemon.c trunk/scd/scdaemon.h trunk/sm/ChangeLog trunk/sm/Makefile.am trunk/sm/call-agent.c trunk/sm/call-dirmngr.c trunk/sm/export.c trunk/sm/gpgsm.c trunk/sm/import.c trunk/sm/qualified.c trunk/tools/ChangeLog trunk/tools/Makefile.am trunk/tools/gpg-connect-agent.c trunk/tools/gpgconf-comp.c trunk/tools/gpgconf.c trunk/tools/symcryptrun.c Log: A whole bunch of changes to allow building for Windows. See the ChangeLogs for details. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/ChangeLog 2007-06-14 17:05:07 UTC (rev 4512) @@ -1,3 +1,16 @@ +2007-06-14 Werner Koch + + * configure.ac [AH_BOTTOM]: Remove the hardwired names of modules. + +2007-06-12 Werner Koch + + * configure.ac [AH_BOTTOM]: Define HTTP_NO_WSASTARTUP. + +2007-06-11 Werner Koch + + * am/cmacros.am (libcommonstd, libcommonpth, libcommonstd_ldadd) + (libcommonpth_ldadd): Add macros. + 2007-06-06 Werner Koch * configure.ac: Add a few notices message so make browsing of the Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/NEWS 2007-06-14 17:05:07 UTC (rev 4512) @@ -3,7 +3,9 @@ * Fixed bug when using the --p12-charset without --armor. + * Changes required for a port to Windows. + Noteworthy changes in version 2.0.4 (2007-05-09) ------------------------------------------------ Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/agent/ChangeLog 2007-06-14 17:05:07 UTC (rev 4512) @@ -1,3 +1,48 @@ +2007-06-14 Werner Koch + + * protect-tool.c (main): Setup default socket name for + simple-pwquery. + (MAP_SPWQ_ERROR_IMPL): New. Use map_spwq_error for spqw related + error codes. + * preset-passphrase.c (main): Setup default socket name for + simple-pwquery. + (map_spwq_error): Remove. + (MAP_SPWQ_ERROR_IMPL): New. + + * call-pinentry.c (start_pinentry): Use gnupg_module_name. + * call-scd.c (start_scd): Ditto. + +2007-06-12 Werner Koch + + * taskbar.c: New. + + * trustlist.c (read_one_trustfile): Replace GNUPG_SYSCONFDIR by a + function call. + (read_trustfiles): Ditto. + + * gpg-agent.c (main): Replace some calls by init_common_subsystems. + * preset-passphrase.c (main): Ditto. + * protect-tool.c (main): Ditto. + +2007-06-11 Werner Koch + + * Makefile.am (common_libs): Use libcommonstd macro. + (commonpth_libs): Use libcommonpth macro. + + * protect-tool.c (main) [W32]: Call pth_init. + + * preset-passphrase.c (main) [W32]: Repalce the explicit Winsocket + init by a call to pth_init. + + * trustlist.c (initialize_module_trustlist): New. + * gpg-agent.c (main): Call it. + + * call-pinentry.c (initialize_module_query): Rename to + initialize_module_call_pinentry. + + * minip12.c: Remove iconv.h. Add utf8conf.h. Changed all iconv + calss to use these jnlib wrappers. + 2007-06-06 Werner Koch * minip12.c (enum): Rename CONTEXT to ASNCONTEXT as winnt.h Modified: trunk/agent/Makefile.am =================================================================== --- trunk/agent/Makefile.am 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/agent/Makefile.am 2007-06-14 17:05:07 UTC (rev 4512) @@ -23,6 +23,8 @@ libexec_PROGRAMS = gpg-protect-tool gpg-preset-passphrase noinst_PROGRAMS = $(TESTS) +EXTRA_DIST = gpg-agent.ico gpg-agent-resource.rc + AM_CPPFLAGS = -I$(top_srcdir)/gl -I$(top_srcdir)/common -I$(top_srcdir)/intl include $(top_srcdir)/am/cmacros.am @@ -45,15 +47,33 @@ call-scd.c \ learncard.c +if HAVE_W32_SYSTEM +gpg_agent_SOURCES += w32main.c w32main.h +endif -common_libs = ../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a -commonpth_libs = ../jnlib/libjnlib.a ../common/libcommonpth.a ../gl/libgnu.a +common_libs = ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a +commonpth_libs = ../jnlib/libjnlib.a $(libcommonpth) ../gl/libgnu.a pwquery_libs = ../common/libsimple-pwquery.a +if HAVE_W32_SYSTEM +.rc.o: + $(WINDRES) `echo $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) | \ + sed -e 's/-I/--include-dir /g;s/-D/--define /g'` -i $< -o $@ + +gpg_agent_res_ldflags = -Wl,gpg-agent-resource.o +gpg_agent_res_deps = gpg-agent-resource.o +else +gpg_agent_res_ldflags = +gpg_agent_res_deps = +endif + + gpg_agent_CFLAGS = $(AM_CFLAGS) $(LIBASSUAN_PTH_CFLAGS) $(PTH_CFLAGS) gpg_agent_LDADD = $(commonpth_libs) \ $(LIBGCRYPT_LIBS) $(LIBASSUAN_PTH_LIBS) $(PTH_LIBS) \ $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) +gpg_agent_LDFLAGS = $(gpg_agent_res_ldflags) +gpg_agent_DEPENDENCIES = $(gpg_agent_res_deps) gpg_protect_tool_SOURCES = \ protect-tool.c \ @@ -61,14 +81,15 @@ minip12.c minip12.h # Needs $(NETLIBS) for libsimple-pwquery.la. -gpg_protect_tool_LDADD = $(pwquery_libs) $(common_libs) \ +gpg_protect_tool_LDADD = $(pwquery_libs) $(common_libs) \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) gpg_preset_passphrase_SOURCES = \ preset-passphrase.c # Needs $(NETLIBS) for libsimple-pwquery.la. -gpg_preset_passphrase_LDADD = $(pwquery_libs) $(common_libs) \ +gpg_preset_passphrase_LDADD = \ + $(pwquery_libs) $(common_libs) \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) @@ -77,6 +98,7 @@ $(PROGRAMS): $(common_libs) $(commonpth_libs) $(pwquery_libs) + # # Module tests # Modified: trunk/agent/agent.h =================================================================== --- trunk/agent/agent.h 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/agent/agent.h 2007-06-14 17:05:07 UTC (rev 4512) @@ -215,8 +215,8 @@ gcry_sexp_t *result); int agent_key_available (const unsigned char *grip); -/*-- query.c --*/ -void initialize_module_query (void); +/*-- call-pinentry.c --*/ +void initialize_module_call_pinentry (void); void agent_query_dump_state (void); void agent_reset_query (ctrl_t ctrl); int pinentry_active_p (ctrl_t ctrl, int waitseconds); @@ -276,6 +276,7 @@ /*-- trustlist.c --*/ +void initialize_module_trustlist (void); gpg_error_t agent_istrusted (ctrl_t ctrl, const char *fpr); gpg_error_t agent_listtrusted (void *assuan_context); gpg_error_t agent_marktrusted (ctrl_t ctrl, const char *name, Modified: trunk/agent/call-pinentry.c =================================================================== --- trunk/agent/call-pinentry.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/agent/call-pinentry.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -87,7 +87,7 @@ static initialization because Pth emulation code might not be able to do a static init; in particular, it is not possible for W32. */ void -initialize_module_query (void) +initialize_module_call_pinentry (void) { static int initialized; @@ -217,7 +217,7 @@ } if (!opt.pinentry_program || !*opt.pinentry_program) - opt.pinentry_program = GNUPG_DEFAULT_PINENTRY; + opt.pinentry_program = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY); pgmname = opt.pinentry_program; if ( !(pgmname = strrchr (opt.pinentry_program, '/'))) pgmname = opt.pinentry_program; @@ -751,6 +751,9 @@ ; /* No pid available can't send a kill. */ else if (popup_finished) ; /* Already finished and ready for joining. */ +#ifdef HAVE_W32_SYSTEM +# warning need to implement a kill mechanism for pinentry +#else else if (pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) ) { /* The daemon already died. No need to send a kill. However because we already waited for the process, we need to tell @@ -762,6 +765,7 @@ else if (pid > 0) kill (pid, SIGKILL); /* Need to use SIGKILL due to bad interaction of SIGINT with Pth. */ +#endif /* Now wait for the thread to terminate. */ rc = pth_join (popup_tid, NULL); Modified: trunk/agent/call-scd.c =================================================================== --- trunk/agent/call-scd.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/agent/call-scd.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -300,7 +300,7 @@ } if (!opt.scdaemon_program || !*opt.scdaemon_program) - opt.scdaemon_program = GNUPG_DEFAULT_SCDAEMON; + opt.scdaemon_program = gnupg_module_name (GNUPG_MODULE_NAME_SCDAEMON); if ( !(pgmname = strrchr (opt.scdaemon_program, '/'))) pgmname = opt.scdaemon_program; else @@ -424,6 +424,9 @@ if (primary_scd_ctx) { pid = assuan_get_pid (primary_scd_ctx); +#ifdef HAVE_W32_SYSTEM +#warning Need to implement an alive test for scdaemon +#else if (pid != (pid_t)(-1) && pid && ((rc=waitpid (pid, NULL, WNOHANG))==-1 || (rc == pid)) ) { @@ -454,6 +457,7 @@ xfree (socket_name); socket_name = NULL; } +#endif } if (!pth_mutex_release (&start_scd_lock)) Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/agent/gpg-agent.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -33,9 +33,9 @@ #include #include #ifndef HAVE_W32_SYSTEM -#include -#include -#endif /*HAVE_W32_SYSTEM*/ +# include +# include +#endif /*!HAVE_W32_SYSTEM*/ #include #include #include @@ -47,7 +47,8 @@ #include "i18n.h" #include "sysutils.h" #ifdef HAVE_W32_SYSTEM -#include "../jnlib/w32-afunix.h" +# include "../jnlib/w32-afunix.h" +# include "w32main.h" #endif #include "setenv.h" @@ -408,8 +409,16 @@ } +/* The main entry point. For W32 another name is used as the real + entry points needs to be named WinMain and is defined in + w32main.c. */ +#ifdef HAVE_W32_SYSTEM int +w32_main (int argc, char **argv ) +#else +int main (int argc, char **argv ) +#endif { ARGPARSE_ARGS pargs; int orig_argc; @@ -434,6 +443,7 @@ gpg_error_t err; const char *env_file_name = NULL; + set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); /* Please note that we may running SUID(ROOT), so be very CAREFUL @@ -441,8 +451,8 @@ somewhere after the option parsing */ log_set_prefix ("gpg-agent", JNLIB_LOG_WITH_PREFIX|JNLIB_LOG_WITH_PID); - /* Try to auto set the character set. */ - set_native_charset (NULL); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); i18n_init (); @@ -663,8 +673,9 @@ exit (1); } - initialize_module_query (); + initialize_module_call_pinentry (); initialize_module_call_scd (); + initialize_module_trustlist (); /* Try to create missing directories. */ create_directories (); @@ -837,6 +848,7 @@ #ifdef HAVE_W32_SYSTEM pid = getpid (); printf ("set GPG_AGENT_INFO=%s;%lu;1\n", socket_name, (ulong)pid); + w32_setup_taskbar (); #else /*!HAVE_W32_SYSTEM*/ pid = fork (); if (pid == (pid_t)-1) @@ -1029,6 +1041,7 @@ return 0; } + void agent_exit (int rc) { @@ -1048,7 +1061,6 @@ exit (rc); } - static void agent_init_default_ctrl (ctrl_t ctrl) { @@ -1153,13 +1165,13 @@ /* Create a name for the socket. With USE_STANDARD_SOCKET given as - true using STANDARD_NAME in the home directory or if given has + true using STANDARD_NAME in the home directory or if given as false from the mkdir type name TEMPLATE. In the latter case a unique name in a unique new directory will be created. In both cases check for valid characters as well as against a maximum allowed length for a unix domain socket is done. The function terminates the process in case of an error. Returns: Pointer to an - allcoated string with the absolute name of the socket used. */ + allocated string with the absolute name of the socket used. */ static char * create_socket_name (int use_standard_socket, char *standard_name, char *template) @@ -1303,6 +1315,9 @@ create_directories (void) { struct stat statbuf; +#ifdef HAVE_W32_SYSTEM +#warning change it so that it works like in gpg. +#endif const char *defhome = GNUPG_DEFAULT_HOMEDIR; char *home; @@ -1478,7 +1493,7 @@ } -/* Connection handler loop. Wait for coecntion requests and spawn a +/* Connection handler loop. Wait for connection requests and spawn a thread after accepting a connection. */ static void handle_connections (int listen_fd, int listen_fd_ssh) @@ -1510,6 +1525,7 @@ ev = pth_event (PTH_EVENT_SIGS, &sigs, &signo); #else ev = NULL; + signo = 0; #endif time_ev = NULL; @@ -1522,6 +1538,10 @@ { sigset_t oldsigs; +#ifdef HAVE_W32_SYSTEM + w32_poll_events (); +#endif + if (shutdown_pending) { if (pth_ctrl (PTH_CTRL_GETTHREADS) == 1) Modified: trunk/agent/minip12.c =================================================================== --- trunk/agent/minip12.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/agent/minip12.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -27,7 +27,6 @@ #include #include #include -#include #include #ifdef TEST @@ -36,18 +35,14 @@ #endif #include "../jnlib/logging.h" +#include "../jnlib/utf8conv.h" #include "minip12.h" #ifndef DIM #define DIM(v) (sizeof(v)/sizeof((v)[0])) #endif -#ifndef ICONV_CONST -#define ICONV_CONST -#endif - - enum { UNIVERSAL = 0, @@ -532,7 +527,7 @@ { if (*charsets[charsetidx]) { - iconv_t cd; + jnlib_iconv_t cd; const char *inptr; char *outptr; size_t inbytes, outbytes; @@ -553,22 +548,22 @@ } } - cd = iconv_open (charsets[charsetidx], "utf-8"); - if (cd == (iconv_t)(-1)) + cd = jnlib_iconv_open (charsets[charsetidx], "utf-8"); + if (cd == (jnlib_iconv_t)(-1)) continue; inptr = pw; inbytes = strlen (pw); outptr = convertedpw; outbytes = convertedpwsize - 1; - if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes, + if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes, &outptr, &outbytes) == (size_t)-1) { - iconv_close (cd); + jnlib_iconv_close (cd); continue; } *outptr = 0; - iconv_close (cd); + jnlib_iconv_close (cd); log_info ("decryption failed; trying charset `%s'\n", charsets[charsetidx]); } @@ -2167,7 +2162,7 @@ if (charset && pw && *pw) { - iconv_t cd; + jnlib_iconv_t cd; const char *inptr; char *outptr; size_t inbytes, outbytes; @@ -2182,8 +2177,8 @@ goto failure; } - cd = iconv_open (charset, "utf-8"); - if (cd == (iconv_t)(-1)) + cd = jnlib_iconv_open (charset, "utf-8"); + if (cd == (jnlib_iconv_t)(-1)) { log_error ("can't convert passphrase to" " requested charset `%s': %s\n", @@ -2196,18 +2191,18 @@ inbytes = strlen (pw); outptr = pwbuf; outbytes = pwbufsize - 1; - if ( iconv (cd, (ICONV_CONST char **)&inptr, &inbytes, + if ( jnlib_iconv (cd, (const char **)&inptr, &inbytes, &outptr, &outbytes) == (size_t)-1) { log_error ("error converting passphrase to" " requested charset `%s': %s\n", charset, strerror (errno)); gcry_free (pwbuf); - iconv_close (cd); + jnlib_iconv_close (cd); goto failure; } *outptr = 0; - iconv_close (cd); + jnlib_iconv_close (cd); pw = pwbuf; } Modified: trunk/agent/preset-passphrase.c =================================================================== --- trunk/agent/preset-passphrase.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/agent/preset-passphrase.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -111,31 +111,9 @@ -static gpg_error_t -map_spwq_error (int err) -{ - switch (err) - { - case 0: - return 0; - case SPWQ_OUT_OF_CORE: - return gpg_error_from_errno (ENOMEM); - case SPWQ_IO_ERROR: - return gpg_error_from_errno (EIO); - case SPWQ_PROTOCOL_ERROR: - return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); - case SPWQ_ERR_RESPONSE: - return gpg_error (GPG_ERR_INV_RESPONSE); - case SPWQ_NO_AGENT: - return gpg_error (GPG_ERR_NO_AGENT); - case SPWQ_SYS_ERROR: - return gpg_error_from_syserror (); - case SPWQ_GENERAL_ERROR: - default: - return gpg_error (GPG_ERR_GENERAL); - } -} +/* Include the implementation of map_spwq_error. */ +MAP_SPWQ_ERROR_IMPL /* Convert the string SRC into HEX encoding. Caller needs to xfree the returned string. */ @@ -260,24 +238,9 @@ set_strusage (my_strusage); log_set_prefix ("gpg-preset-passphrase", 1); - /* Try to auto set the character set. */ - set_native_charset (NULL); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); -#ifdef HAVE_W32_SYSTEM - /* Fixme: Need to initialize the Windows sockets: This should be - moved to another place and we should make sure that it won't get - done twice, like when Pth is used too. */ - { - WSADATA wsadat; - if (WSAStartup (0x202, &wsadat) ) - { - log_error ("error initializing socket library: ec=%d\n", - (int)WSAGetLastError () ); - return 2; - } - } -#endif - i18n_init (); opt_homedir = default_homedir (); @@ -307,6 +270,13 @@ else 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); + } + if (cmd == oPreset) preset_passphrase (keygrip); else if (cmd == oForget) Modified: trunk/agent/protect-tool.c =================================================================== --- trunk/agent/protect-tool.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/agent/protect-tool.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -160,6 +160,8 @@ } +/* Include the implementation of map_spwq_error. */ +MAP_SPWQ_ERROR_IMPL /* static void */ /* print_mpi (const char *text, gcry_mpi_t a) */ @@ -1033,8 +1035,8 @@ gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); log_set_prefix ("gpg-protect-tool", 1); - /* Try to auto set the character set. */ - set_native_charset (NULL); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); i18n_init (); @@ -1092,6 +1094,13 @@ 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); + } + if (opt_prompt) opt_prompt = percent_plus_unescape_string (xstrdup (opt_prompt)); @@ -1194,6 +1203,7 @@ pw = simple_pwquery (NULL, error_msgno == 1? _("does not match - try again"):NULL, _("Passphrase:"), desc, opt_check, &err); + err = map_spwq_error (err); #ifdef ENABLE_NLS if (orig_codeset) Modified: trunk/agent/trustlist.c =================================================================== --- trunk/agent/trustlist.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/agent/trustlist.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -53,7 +53,7 @@ static trustitem_t *trusttable; static size_t trusttablesize; /* A mutex used to protect the table. */ -static pth_mutex_t trusttable_lock = PTH_MUTEX_INIT; +static pth_mutex_t trusttable_lock; @@ -71,7 +71,25 @@ "\n"; +/* This function must be called once to initialize this module. This + has to be done before a second thread is spawned. We can't do the + static initialization because Pth emulation code might not be able + to do a static init; in particular, it is not possible for W32. */ +void +initialize_module_trustlist (void) +{ + static int initialized; + if (!initialized) + { + if (!pth_mutex_init (&trusttable_lock)) + log_fatal ("error initializing mutex: %s\n", strerror (errno)); + initialized = 1; + } +} + + + static void lock_trusttable (void) @@ -153,7 +171,7 @@ } /* fixme: Should check for trailing garbage. */ - etcname = make_filename (GNUPG_SYSCONFDIR, "trustlist.txt", NULL); + etcname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL); if ( !strcmp (etcname, fname) ) /* Same file. */ log_info (_("statement \"%s\" ignored in `%s', line %d\n"), "include-default", fname, lnr); @@ -303,7 +321,7 @@ log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err)); } xfree (fname); - fname = make_filename (GNUPG_SYSCONFDIR, "trustlist.txt", NULL); + fname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL); allow_include = 0; } err = read_one_trustfile (fname, allow_include, Modified: trunk/am/cmacros.am =================================================================== --- trunk/am/cmacros.am 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/am/cmacros.am 2007-06-14 17:05:07 UTC (rev 4512) @@ -30,6 +30,10 @@ -DGNUPG_SYSCONFDIR="\"$(sysconfdir)/@PACKAGE@\"" endif + +# If a specific protect tool program has been defined, pass its name +# to cc. Note that these macros should not be used directly but via +# the gnupg_module_name function. if GNUPG_AGENT_PGM AM_CPPFLAGS += -DGNUPG_DEFAULT_AGENT="\"@GNUPG_AGENT_PGM@\"" endif @@ -45,3 +49,9 @@ if GNUPG_PROTECT_TOOL_PGM AM_CPPFLAGS += -DGNUPG_DEFAULT_PROTECT_TOOL="\"@GNUPG_PROTECT_TOOL_PGM@\"" endif + + +# Convenience macros +libcommon = ../common/libcommon.a +libcommonpth = ../common/libcommonpth.a + Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/common/ChangeLog 2007-06-14 17:05:07 UTC (rev 4512) @@ -1,3 +1,36 @@ +2007-06-14 Werner Koch + + * simple-pwquery.h (MAP_SPWQ_ERROR_IMPL): New. + (SPWQ_NO_PIN_ENTRY): New. + * simple-pwquery.c (simple_pw_set_socket): New. + (agent_open): Use it if GPG_AGENT_INFO is not set. + (simple_pwquery): Extended to allow returning of otehyr error codes. + + * util.h (GNUPG_MODULE_NAME_AGENT, GNUPG_MODULE_NAME_PINENTRY) + (GNUPG_MODULE_NAME_SCDAEMON, GNUPG_MODULE_NAME_DIRMNGR) + (GNUPG_MODULE_NAME_PROTECT_TOOL): New. + * homedir.c (gnupg_module_name): New. + (gnupg_bindir): New. + +2007-06-12 Werner Koch + + * homedir.c (gnupg_sysconfdir): New. + (gnupg_libexecdir): New. Taken from g10/misc.c:get_libexecdir. + (gnupg_datadir): New. + (gnupg_libdir): New. + + * http.c (connect_server) [W32]: Do not call init_sockets if + HTTP_NO_WSASTARTUP is defined. + + * init.c: New. + + * estream.c (es_init_do): Init stream lock here because we can't + use a static initialization with W32pth. + +2007-06-11 Werner Koch + + * Makefile.am (t_common_ldadd): Use libcommonstd macro. + 2007-06-06 Werner Koch * Makefile.am: Include am/cmacros.am. Modified: trunk/common/Makefile.am =================================================================== --- trunk/common/Makefile.am 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/common/Makefile.am 2007-06-14 17:05:07 UTC (rev 4512) @@ -37,6 +37,7 @@ openpgpdefs.h \ keyserver.h \ sexp-parse.h \ + init.c \ sexputil.c \ sysutils.c sysutils.h \ homedir.c \ @@ -59,6 +60,7 @@ pka.c pka.h \ http.c http.h + libcommon_a_SOURCES = $(common_sources) if USE_DNS_SRV libcommon_a_SOURCES += srv.c @@ -83,7 +85,7 @@ # module_tests = t-convert -t_common_ldadd = ../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a \ +t_common_ldadd = ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a \ $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV) t_convert_DEPENDENCIES = convert.c libcommon.a Modified: trunk/common/estream.c =================================================================== --- trunk/common/estream.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/common/estream.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -109,8 +109,6 @@ ((pth_mutex_acquire (&(mutex), 1, NULL) == TRUE) ? 0 : -1) # define ESTREAM_MUTEX_INITIALIZE(mutex) \ pth_mutex_init (&(mutex)) -# define ESTREAM_THREADING_INIT() ((pth_init () == TRUE) ? 0 : -1) - #else typedef void *estream_mutex_t; @@ -119,8 +117,6 @@ # define ESTREAM_MUTEX_UNLOCK(mutex) (void) 0 # define ESTREAM_MUTEX_TRYLOCK(mutex) 0 # define ESTREAM_MUTEX_INITIALIZE(mutex) (void) 0 -# define ESTREAM_THREADING_INIT() 0 - #endif /* Memory allocator functions. */ @@ -194,13 +190,9 @@ static estream_list_t estream_list; #ifdef HAVE_PTH -/* Note that we can't use a static initialization with W32Pth; however - W32Pth does an implicit initialization anyway. */ -static estream_mutex_t estream_list_lock -# ifndef _W32_PTH_H - = ESTREAM_MUTEX_INITIALIZER -# endif - ; +/* Note that we can't use a static initialization with W32Pth, thus we + do it in es_init. */ +static estream_mutex_t estream_list_lock; #endif #define ESTREAM_LIST_LOCK ESTREAM_MUTEX_LOCK (estream_list_lock) @@ -308,11 +300,18 @@ static int es_init_do (void) { - int err; +#ifdef HAVE_PTH + static int initialized; - err = ESTREAM_THREADING_INIT (); - - return err; + if (!initialized) + { + if (!pth_init ()) + return -1; + if (pth_mutex_init (&estream_list_lock)) + initialized = 1; + } +#endif + return 0; } Modified: trunk/common/homedir.c =================================================================== --- trunk/common/homedir.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/common/homedir.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -124,3 +124,152 @@ return dir; } + + +/* Return the name of the sysconfdir. This is a static string. This + function is required because under Windows we can't simply compile + it in. */ +const char * +gnupg_sysconfdir (void) +{ +#ifdef HAVE_W32_SYSTEM +#warning get the sysconfdir from somewhere else + return GNUPG_SYSCONFDIR; +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_SYSCONFDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +const char * +gnupg_bindir (void) +{ +#ifdef HAVE_W32_SYSTEM + return gnupg_libexecdir (); +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_BINDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Return the name of the libexec directory. The name is allocated in + a static area on the first use. This function won't fail. */ +const char * +gnupg_libexecdir (void) +{ +#ifdef HAVE_W32_SYSTEM + static int got_dir; + static char dir[MAX_PATH+5]; + + if (!got_dir) + { + char *p; + + if ( !GetModuleFileName ( NULL, dir, MAX_PATH) ) + { + log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0)); + *dir = 0; + } + got_dir = 1; + p = strrchr (dir, DIRSEP_C); + if (p) + *p = 0; + else + { + log_debug ("bad filename `%s' returned for this process\n", dir); + *dir = 0; + } + } + + if (*dir) + return dir; + /* Fallback to the hardwired value. */ +#endif /*HAVE_W32_SYSTEM*/ + + return GNUPG_LIBEXECDIR; +} + +const char * +gnupg_libdir (void) +{ +#ifdef HAVE_W32_SYSTEM +#warning get the libdir from somewhere else + return GNUPG_LIBDIR; +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_LIBDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + +const char * +gnupg_datadir (void) +{ +#ifdef HAVE_W32_SYSTEM +#warning get the datadir from somewhere else + return GNUPG_DATADIR; +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_DATADIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Return the file name of a helper tool. WHICH is one of the + GNUPG_MODULE_NAME_foo constants. */ +const char * +gnupg_module_name (int which) +{ + const char *s, *s2; + +#define X(a,b) do { \ + static char *name; \ + if (!name) \ + { \ + s = gnupg_ ## a (); \ + s2 = DIRSEP_S b EXEEXT_S; \ + name = xmalloc (strlen (s) + strlen (s2) + 1); \ + strcpy (stpcpy (name, s), s2); \ + } \ + return name; \ + } while (0) + + switch (which) + { + case GNUPG_MODULE_NAME_AGENT: +#ifdef GNUPG_DEFAULT_AGENT + return GNUPG_DEFAULT_AGENT; +#else + X(bindir, "gpg-agent"); +#endif + + case GNUPG_MODULE_NAME_PINENTRY: +#ifdef GNUPG_DEFAULT_PINENTRY + return GNUPG_DEFAULT_PINENTRY; +#else + X(bindir, "pinentry"); +#endif + + case GNUPG_MODULE_NAME_SCDAEMON: +#ifdef GNUPG_DEFAULT_SCDAEMON + return GNUPG_DEFAULT_SCDAEMON; +#else + X(bindir, "scdaemon"); +#endif + + case GNUPG_MODULE_NAME_DIRMNGR: +#ifdef GNUPG_DEFAULT_DIRMNGR + return GNUPG_DEFAULT_DIRMNGR; +#else + X(bindir, "dirmngr"); +#endif + + case GNUPG_MODULE_NAME_PROTECT_TOOL: +#ifdef GNUPG_DEFAULT_PROTECT_TOOL + return GNUPG_DEFAULT_PROTECT_TOOL; +#else + X(libexecdir, "gpg-protect-tool"); +#endif + + default: + BUG (); + } +#undef X +} Modified: trunk/common/http.c =================================================================== --- trunk/common/http.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/common/http.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -30,6 +30,10 @@ - With HTTP_USE_ESTREAM defined, all I/O is done through estream. - With HTTP_USE_GNUTLS support for https is provided (this also requires estream). + - With HTTP_NO_WSASTARTUP the socket initialization is not done + under Windows. This is useful if the socket layer has already + been initialized elsewhere. This also avoids the installation of + an exit handler to cleanup the socket layer. */ #ifdef HAVE_CONFIG_H @@ -200,7 +204,7 @@ -#ifdef HAVE_W32_SYSTEM +#if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP) #if GNUPG_MAJOR_VERSION == 1 #define REQ_WINSOCK_MAJOR 1 @@ -244,7 +248,7 @@ atexit ( deinit_sockets ); initialized = 1; } -#endif /*HAVE_W32_SYSTEM*/ +#endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/ @@ -1504,7 +1508,9 @@ #ifdef HAVE_W32_SYSTEM unsigned long inaddr; - init_sockets(); +#ifndef HTTP_NO_WSASTARTUP + init_sockets (); +#endif /* Win32 gethostbyname doesn't handle IP addresses internally, so we try inet_addr first on that platform only. */ inaddr = inet_addr(server); Added: trunk/common/init.c =================================================================== --- trunk/common/init.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/common/init.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -0,0 +1,73 @@ +/* init.c - Various initializations + * Copyright (C) 2007 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include + +#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */ +#undef HAVE_PTH +#undef USE_GNU_PTH +#endif + +#ifdef HAVE_W32_SYSTEM +#include +#endif +#ifdef HAVE_PTH +#include +#endif + +#include "estream.h" +#include "util.h" + + +/* This function is to be used early at program startup to make sure + that some subsystems are initialized. This is in particualr + important for W32 to initialize the sockets so that our socket + emulation code used directly as well as in libassuan may be used. + It should best be called before any I/O is done so that setup + required for logging is ready. CAUTION: This might be called while + running suid(root). */ +void +init_common_subsystems (void) +{ + /* Try to auto set the character set. */ + set_native_charset (NULL); + +#ifdef HAVE_W32_SYSTEM + /* For W32 we need to initialize the socket layer. This is becuase + we use recv and send in libassuan as well as at some other + places. If we are building with PTH we let pth_init do it. We + can't do much on error so we ignore them. An error would anyway + later pop up if one of the socket functions is used. */ +# ifdef HAVE_PTH + pth_init (); +# else + { + WSADATA wsadat; + + WSAStartup (0x202, &wsadat); + } +# endif /*!HAVE_PTH*/ +#endif + + /* Initialize the Estream library. */ + es_init (); +} + Modified: trunk/common/simple-pwquery.c =================================================================== --- trunk/common/simple-pwquery.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/common/simple-pwquery.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -1,5 +1,5 @@ /* simple-pwquery.c - A simple password query client for gpg-agent - * Copyright (C) 2002, 2004 Free Software Foundation, Inc. + * Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -68,8 +68,13 @@ #endif +/* Name of the socket to be used if GPG_AGENT_INFO has not been + set. No default socket is used if this is NULL. */ +static char *default_gpg_agent_info; + + #ifndef HAVE_STPCPY @@ -154,9 +159,9 @@ ; if (n) { - break; /* at least one full line available - that's enough. + break; /* At least one full line available - that's enough. This function is just a simple implementation, so - it is okay to forget about pending bytes */ + it is okay to forget about pending bytes. */ } } @@ -305,6 +310,8 @@ *rfd = -1; infostr = getenv ( "GPG_AGENT_INFO" ); if ( !infostr || !*infostr ) + infostr = default_gpg_agent_info; + if ( !infostr || !*infostr ) { #ifdef SPWQ_USE_LOGGING log_error (_("gpg-agent is not available in this session\n")); @@ -322,6 +329,9 @@ { #ifdef SPWQ_USE_LOGGING log_error ( _("malformed GPG_AGENT_INFO environment variable\n")); + log_debug ( "a='%s'\n", infostr); + log_debug ( "a='%s'\n", strchr ( infostr, PATHSEP_C)); + log_debug ( "a=%td\n", (p-infostr)); #endif return SPWQ_NO_AGENT; } @@ -425,13 +435,34 @@ } +/* Set the name of the default socket to NAME. */ +int +simple_pw_set_socket (const char *name) +{ + spwq_free (default_gpg_agent_info); + if (name) + { + default_gpg_agent_info = spwq_malloc (strlen (name) + 4 + 1); + if (!default_gpg_agent_info) + return SPWQ_OUT_OF_CORE; + /* We don't know the PID thus we use 0. */ + strcpy (stpcpy (default_gpg_agent_info, name), + PATHSEP_S "0" PATHSEP_S "1"); + } + else + default_gpg_agent_info = NULL; + + return 0; +} + + /* Ask the gpg-agent for a passphrase and present the user with a DESCRIPTION, a PROMPT and optionally with a TRYAGAIN extra text. If a CACHEID is not NULL it is used to locate the passphrase in in the cache and store it under this ID. If OPT_CHECK is true gpg-agent is asked to apply some checks on the passphrase security. If ERRORCODE is not NULL it should point a variable receiving an - errorcode; this errocode might be 0 if the user canceled the + errorcode; this error code might be 0 if the user canceled the operation. The function returns NULL to indicate an error. */ char * simple_pwquery (const char *cacheid, @@ -530,8 +561,16 @@ #ifdef SPWQ_USE_LOGGING log_info (_("canceled by user\n") ); #endif - *errorcode = 0; /* canceled */ + *errorcode = 0; /* Special error code to indicate Cancel. */ } + else if (nread > 4 && !memcmp (pw, "ERR ", 4)) + { + switch ( (strtoul (pw+4, NULL, 0) & 0xffff) ) + { + case 85: rc = SPWQ_NO_PIN_ENTRY; break; + default: rc = SPWQ_GENERAL_ERROR; break; + } + } else { #ifdef SPWQ_USE_LOGGING Modified: trunk/common/simple-pwquery.h =================================================================== --- trunk/common/simple-pwquery.h 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/common/simple-pwquery.h 2007-06-14 17:05:07 UTC (rev 4512) @@ -41,7 +41,6 @@ #define spwq_secure_malloc(a) gcry_malloc_secure (a) #define spwq_secure_free(a) gcry_free (a) - #endif /*SIMPLE_PWQUERY_IMPLEMENTATION*/ /* End configuration stuff. */ @@ -67,6 +66,11 @@ terminated) and return the error code. */ int simple_query (const char *query); +/* Set the name of the standard socket to be used if GPG_AGENT_INFO is + not defined. The use of this function is optional but if it needs + to be called before any other function. Returns 0 on success. */ +int simple_pw_set_socket (const char *name); + #define SPWQ_OUT_OF_CORE 1 #define SPWQ_IO_ERROR 2 #define SPWQ_PROTOCOL_ERROR 3 @@ -74,5 +78,40 @@ #define SPWQ_NO_AGENT 5 #define SPWQ_SYS_ERROR 6 #define SPWQ_GENERAL_ERROR 7 +#define SPWQ_NO_PIN_ENTRY 8 + +/* We often need to map error codes to gpg-error style error codes. + To have a consistent mapping this macro may be used to implemt the + mapping function. */ +#define MAP_SPWQ_ERROR_IMPL \ + static gpg_error_t \ + map_spwq_error (int err) \ + { \ + switch (err) \ + { \ + case 0: \ + return 0; \ + case SPWQ_OUT_OF_CORE: \ + return gpg_error_from_errno (ENOMEM); \ + case SPWQ_IO_ERROR: \ + return gpg_error_from_errno (EIO); \ + case SPWQ_PROTOCOL_ERROR: \ + return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); \ + case SPWQ_ERR_RESPONSE: \ + return gpg_error (GPG_ERR_INV_RESPONSE); \ + case SPWQ_NO_AGENT: \ + return gpg_error (GPG_ERR_NO_AGENT); \ + case SPWQ_SYS_ERROR: \ + return gpg_error_from_syserror (); \ + case SPWQ_NO_PIN_ENTRY: \ + return gpg_error (GPG_ERR_NO_PIN_ENTRY); \ + case SPWQ_GENERAL_ERROR: \ + default: \ + return gpg_error (GPG_ERR_GENERAL); \ + } \ + } +/* End of MAP_SPWQ_ERROR_IMPL. */ + + #endif /*SIMPLE_PWQUERY_H*/ Modified: trunk/common/util.h =================================================================== --- trunk/common/util.h 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/common/util.h 2007-06-14 17:05:07 UTC (rev 4512) @@ -120,6 +120,8 @@ strcpy (d, s); } +/*-- init.c --*/ +void init_common_subsystems (void); /*-- signal.c --*/ void gnupg_init_signals (int mode, void (*fast_cleanup)(void)); @@ -170,7 +172,21 @@ /*-- homedir.c --*/ const char *default_homedir (void); +const char *gnupg_sysconfdir (void); +const char *gnupg_bindir (void); +const char *gnupg_libexecdir (void); +const char *gnupg_libdir (void); +const char *gnupg_datadir (void); +#define GNUPG_MODULE_NAME_AGENT 1 +#define GNUPG_MODULE_NAME_PINENTRY 2 +#define GNUPG_MODULE_NAME_SCDAEMON 3 +#define GNUPG_MODULE_NAME_DIRMNGR 4 +#define GNUPG_MODULE_NAME_PROTECT_TOOL 5 +const char *gnupg_module_name (int which); + + + /*-- gpgrlhelp.c --*/ void gnupg_rl_initialize (void); Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/configure.ac 2007-06-14 17:05:07 UTC (rev 4512) @@ -363,31 +363,15 @@ the values may be overridden by the make invocations; this is to comply with the GNU coding standards. */ #ifdef HAVE_DRIVE_LETTERS + /* FIXME: We need to use a function to determine these values depending + on the actual installation directory. */ #define GNUPG_BINDIR "c:\\gnupg" #define GNUPG_LIBEXECDIR "c:\\gnupg" #define GNUPG_LIBDIR "c:\\gnupg" #define GNUPG_DATADIR "c:\\gnupg" +#define GNUPG_SYSCONFDIR "c:\\gnupg" #endif -/* Setup the hardwired names of modules. */ -#ifndef GNUPG_DEFAULT_AGENT -#define GNUPG_DEFAULT_AGENT ( GNUPG_BINDIR DIRSEP_S "gpg-agent" EXEEXT_S ) -#endif -#ifndef GNUPG_DEFAULT_PINENTRY -#define GNUPG_DEFAULT_PINENTRY ( GNUPG_BINDIR DIRSEP_S "pinentry" EXEEXT_S ) -#endif -#ifndef GNUPG_DEFAULT_SCDAEMON -#define GNUPG_DEFAULT_SCDAEMON ( GNUPG_BINDIR DIRSEP_S "scdaemon" EXEEXT_S ) -#endif -#ifndef GNUPG_DEFAULT_DIRMNGR -#define GNUPG_DEFAULT_DIRMNGR ( GNUPG_BINDIR DIRSEP_S "dirmngr" EXEEXT_S ) -#endif -#ifndef GNUPG_DEFAULT_PROTECT_TOOL -#define GNUPG_DEFAULT_PROTECT_TOOL \ - ( GNUPG_LIBEXECDIR DIRSEP_S "gpg-protect-tool" EXEEXT_S ) -#endif - - /* Derive some other constants. */ #if !(defined(HAVE_FORK) && defined(HAVE_PIPE) && defined(HAVE_WAITPID)) #define EXEC_TEMPFILE_ONLY @@ -416,6 +400,11 @@ /* Our HTTP code is used in estream mode. */ #define HTTP_USE_ESTREAM 1 +/* Under W32 we do an explicit socket initialization, thus we need to + avoid the on-demand initialization which would also install an atexit + handler. */ +#define HTTP_NO_WSASTARTUP + /* We always include support for the OpenPGP card. */ #define ENABLE_CARD_SUPPORT 1 @@ -460,6 +449,7 @@ AC_PROG_RANLIB AC_CHECK_TOOL(AR, ar, :) AC_PATH_PROG(PERL,"perl") +AC_CHECK_TOOL(WINDRES, windres, :) AC_ISC_POSIX gl_EARLY AC_SYS_LARGEFILE Modified: trunk/doc/gpgsm.texi =================================================================== --- trunk/doc/gpgsm.texi 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/doc/gpgsm.texi 2007-06-14 17:05:07 UTC (rev 4512) @@ -746,6 +746,15 @@ random number generator accross invocations. The same file is used by other programs of this software too. + at item S.gpg-agent + at cindex S.gpg-agent +If this file exists and the environment variable @env{GPG_AGENT_INFO} is +not set, @command{gpgsm} will first try to connect to this socket for +accessing @command{gpg-agent} before starting a new @command{gpg-agent} +instance. Under Windows this socket (which in reality be a plain file +describing a regular TCP litening port) is the standard way of +connecting the @command{gpg-agent}. + @end table Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/g10/ChangeLog 2007-06-14 17:05:07 UTC (rev 4512) @@ -1,3 +1,24 @@ +2007-06-14 Werner Koch + + * call-agent.c (start_agent): Use gnupg_module_name. + +2007-06-12 Werner Koch + + * openfile.c (copy_options_file): Use gnupg_datadir. + * misc.c (get_libexecdir): Remove. Changed all callers to use + gnupg_libexecdir. + * gpg.c (check_permissions): Use gnupg_libdir. + + * gpg.c (main): Replace some calls by init_common_subsystems. + * gpgv.c (main): Ditto. + +2007-06-11 Werner Koch + + * Makefile.am (needed_libs): Use libcommonstd macro. + + * gpgv.c (main) [W32]: Call pth_init. + * gpg.c (main) [W32]: Call pth_init. + 2007-06-08 Werner Koch * Makefile.am (gpg2_LDADD): Syntax fix. Modified: trunk/g10/Makefile.am =================================================================== --- trunk/g10/Makefile.am 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/g10/Makefile.am 2007-06-14 17:05:07 UTC (rev 4512) @@ -29,7 +29,7 @@ AM_CFLAGS = $(LIBGCRYPT_CFLAGS) $(LIBASSUAN_CFLAGS) $(GPG_ERROR_CFLAGS) -needed_libs = ../common/libcommon.a ../jnlib/libjnlib.a ../gl/libgnu.a +needed_libs = $(libcommon) ../jnlib/libjnlib.a ../gl/libgnu.a bin_PROGRAMS = gpg2 gpgv2 Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/g10/call-agent.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -106,7 +106,7 @@ } if (!opt.agent_program || !*opt.agent_program) - opt.agent_program = GNUPG_DEFAULT_AGENT; + opt.agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); if ( !(pgmname = strrchr (opt.agent_program, '/'))) pgmname = opt.agent_program; else Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/g10/gpg.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -1147,7 +1147,7 @@ if(strchr(path,DIRSEP_C)) tmppath=make_filename(path,NULL); else - tmppath=make_filename(GNUPG_LIBDIR,path,NULL); + tmppath=make_filename(gnupg_libdir (),path,NULL); } else tmppath=xstrdup(path); @@ -1814,6 +1814,9 @@ gcry_control (GCRYCTL_DISABLE_INTERNAL_LOCKING); log_set_prefix ("gpg", 1); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); + /* Check that the libraries are suitable. Do it right here because the option parsing may need services of the library. */ if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) @@ -1939,8 +1942,6 @@ assuan_set_assuan_err_source (GPG_ERR_SOURCE_DEFAULT); - set_native_charset (NULL); /* Try to auto set the character set */ - /* Try for a version specific config file first */ if( default_config ) { Modified: trunk/g10/gpgv.c =================================================================== --- trunk/g10/gpgv.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/g10/gpgv.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -122,8 +122,13 @@ set_strusage (my_strusage); log_set_prefix ("gpgv", 1); + + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); + gnupg_init_signals (0, NULL); i18n_init(); + opt.command_fd = -1; /* no command fd */ opt.pgp2_workarounds = 1; opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE; @@ -136,8 +141,6 @@ tty_batchmode(1); disable_dotlock(); - set_native_charset (NULL); /* Try to auto set the character set */ - pargs.argc = &argc; pargs.argv = &argv; pargs.flags= 1; /* do not remove the args */ Modified: trunk/g10/keyserver.c =================================================================== --- trunk/g10/keyserver.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/g10/keyserver.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -970,7 +970,7 @@ byte *line=NULL; struct exec_info *spawn; const char *scheme; - const char *libexecdir = get_libexecdir (); + const char *libexecdir = gnupg_libexecdir (); assert(keyserver); @@ -996,7 +996,7 @@ After some more thinking about this we came to the conclusion that it is better to load the helpers from the directory where the program of this process lives. Fortunately Windows provides - a way to retrieve this and our get_libexecdir function has been + a way to retrieve this and our gnupg_libexecdir function has been modified to return just this. Setting the exec-path is not anymore required. set_exec_path(libexecdir); Modified: trunk/g10/misc.c =================================================================== --- trunk/g10/misc.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/g10/misc.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -1224,43 +1224,6 @@ } -/* Return the name of the libexec directory. The name is allocated in - a static area on the first use. This function won't fail. */ -const char * -get_libexecdir (void) -{ -#ifdef HAVE_W32_SYSTEM - static int got_dir; - static char dir[MAX_PATH+5]; - - if (!got_dir) - { - char *p; - - if ( !GetModuleFileName ( NULL, dir, MAX_PATH) ) - { - log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0)); - *dir = 0; - } - got_dir = 1; - p = strrchr (dir, DIRSEP_C); - if (p) - *p = 0; - else - { - log_debug ("bad filename `%s' returned for this process\n", dir); - *dir = 0; - } - } - - if (*dir) - return dir; - /* Fallback to the hardwired value. */ -#endif /*HAVE_W32_SYSTEM*/ - - return GNUPG_LIBEXECDIR; -} - /* Similar to access(2), but uses PATH to find the file. */ int path_access(const char *file,int mode) Modified: trunk/g10/openfile.c =================================================================== --- trunk/g10/openfile.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/g10/openfile.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -330,7 +330,7 @@ static void copy_options_file( const char *destdir ) { - const char *datadir = GNUPG_DATADIR; + const char *datadir = gnupg_datadir (); char *fname; FILE *src, *dst; int linefeeds=0; @@ -407,6 +407,9 @@ try_make_homedir( const char *fname ) { const char *defhome = GNUPG_DEFAULT_HOMEDIR; +#ifdef HAVE_W32_SYSTEM +#warning use a function and not a constant +#endif /* Create the directory only if the supplied directory name * is the same as the default one. This way we avoid to create Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/jnlib/ChangeLog 2007-06-14 17:05:07 UTC (rev 4512) @@ -1,3 +1,7 @@ +2007-06-11 Werner Koch + + * utf8conv.c (jnlib_iconv_open, jnlib_iconv, jnlib_iconv_close): New. + 2007-06-06 Werner Koch * w32help.h: New. Modified: trunk/jnlib/utf8conv.c =================================================================== --- trunk/jnlib/utf8conv.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/jnlib/utf8conv.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -150,6 +150,7 @@ } + int set_native_charset (const char *newset) { @@ -694,3 +695,49 @@ { return do_utf8_to_native (string, length, delim, use_iconv); } + + + + +/* Wrapper function for iconv_open, required for W32 as we dlopen that + library on that system. */ +jnlib_iconv_t +jnlib_iconv_open (const char *tocode, const char *fromcode) +{ +#ifdef HAVE_W32_SYSTEM + if (load_libiconv ()) + return (jnlib_iconv_t)(-1); +#endif /*HAVE_W32_SYSTEM*/ + + return (jnlib_iconv_t)iconv_open (tocode, fromcode); +} + + +/* Wrapper function for iconv, required for W32 as we dlopen that + library on that system. */ +size_t +jnlib_iconv (jnlib_iconv_t cd, + const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft) +{ + +#ifdef HAVE_W32_SYSTEM + if (load_libiconv ()) + return 0; +#endif /*HAVE_W32_SYSTEM*/ + + return iconv ((iconv_t)cd, inbuf, inbytesleft, outbuf, outbytesleft); +} + +/* Wrapper function for iconv_close, required for W32 as we dlopen that + library on that system. */ +int +jnlib_iconv_close (jnlib_iconv_t cd) +{ +#ifdef HAVE_W32_SYSTEM + if (load_libiconv ()) + return 0; +#endif /*HAVE_W32_SYSTEM*/ + + return iconv_close ((iconv_t)cd); +} Modified: trunk/jnlib/utf8conv.h =================================================================== --- trunk/jnlib/utf8conv.h 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/jnlib/utf8conv.h 2007-06-14 17:05:07 UTC (rev 4512) @@ -30,4 +30,14 @@ char *utf8_to_native (const char *string, size_t length, int delim); +/* Silly wrappers, required for W32 portability. */ +typedef void *jnlib_iconv_t; + +jnlib_iconv_t jnlib_iconv_open (const char *tocode, const char *fromcode); +size_t jnlib_iconv (jnlib_iconv_t cd, const char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft); +int jnlib_iconv_close (jnlib_iconv_t cd); + + + #endif /*LIBJNLIB_UTF8CONF_H*/ Modified: trunk/kbx/ChangeLog =================================================================== --- trunk/kbx/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/kbx/ChangeLog 2007-06-14 17:05:07 UTC (rev 4512) @@ -1,3 +1,7 @@ +2007-06-12 Werner Koch + + * kbxutil.c (main): Replace some calls by init_common_subsystems. + 2007-06-06 Werner Koch * kbxutil.c (i18n_init): Remove. Modified: trunk/kbx/kbxutil.c =================================================================== --- trunk/kbx/kbxutil.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/kbx/kbxutil.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -408,7 +408,10 @@ set_strusage( my_strusage ); gcry_control (GCRYCTL_DISABLE_SECMEM); log_set_prefix ("kbxutil", 1); - set_native_charset (NULL); + + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); + i18n_init (); /* Check that the libraries are suitable. Do it here because Modified: trunk/keyserver/ChangeLog =================================================================== --- trunk/keyserver/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/keyserver/ChangeLog 2007-06-14 17:05:07 UTC (rev 4512) @@ -1,3 +1,9 @@ +2007-06-11 Werner Koch + + * gpgkeys_hkp.c (send_key): Rename eof to r_eof as some Windows + header defines such a symbol. + (main): Likewise. + 2007-06-06 Werner Koch * gpgkeys_ldap.c (send_key, send_key_keyserver): Rename eof to Modified: trunk/keyserver/gpgkeys_hkp.c =================================================================== --- trunk/keyserver/gpgkeys_hkp.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/keyserver/gpgkeys_hkp.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -93,7 +93,7 @@ } int -send_key(int *eof) +send_key(int *r_eof) { CURLcode res; char request[MAX_URL+15]; @@ -117,7 +117,7 @@ { /* i.e. eof before the KEY BEGIN was found. This isn't an error. */ - *eof=1; + *r_eof=1; ret=KEYSERVER_OK; goto fail; } @@ -157,7 +157,7 @@ if(!end) { fprintf(console,"gpgkeys: no KEY %s END found\n",keyid); - *eof=1; + *r_eof=1; ret=KEYSERVER_KEY_INCOMPLETE; goto fail; } @@ -768,16 +768,16 @@ } else if(opt->action==KS_SEND) { - int eof=0; + int myeof=0; do { set_timeout(opt->timeout); - if(send_key(&eof)!=KEYSERVER_OK) + if(send_key(&myeof)!=KEYSERVER_OK) failed++; } - while(!eof); + while(!myeof); } else if(opt->action==KS_SEARCH) { Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/scd/ChangeLog 2007-06-14 17:05:07 UTC (rev 4512) @@ -1,3 +1,15 @@ +2007-06-12 Werner Koch + + * scdaemon.c (main): Replace some calls by init_common_subsystems. + +2007-06-11 Werner Koch + + * Makefile.am (scdaemon_LDADD): Use libcommonpth macro. + + * command.c (initialize_module_command): New. + * scdaemon.c (main) [W32]: Do not use sigpipe code. + (main): Call initialize_module_command. + 2007-06-06 Werner Koch * app-openpgp.c (do_sign): Fix arithmetic on void*. Modified: trunk/scd/Makefile.am =================================================================== --- trunk/scd/Makefile.am 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/scd/Makefile.am 2007-06-14 17:05:07 UTC (rev 4512) @@ -44,7 +44,7 @@ app.c app-common.h app-help.c $(card_apps) -scdaemon_LDADD = ../jnlib/libjnlib.a ../common/libcommonpth.a ../gl/libgnu.a \ +scdaemon_LDADD = ../jnlib/libjnlib.a $(libcommonpth) ../gl/libgnu.a \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_PTH_LIBS) $(PTH_LIBS) \ $(LIBUSB_LIBS) $(GPG_ERROR_LIBS) \ $(LIBINTL) $(DL_LIBS) $(NETLIBS) $(LIBICONV) Modified: trunk/scd/apdu.c =================================================================== --- trunk/scd/apdu.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/scd/apdu.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -1337,6 +1337,8 @@ int err; unsigned int dummy_status; int sw = SW_HOST_CARD_IO_ERROR; + /* Note that we use the constant and not the fucntion because this + code won't be be used under Windows. */ const char *wrapperpgm = GNUPG_LIBEXECDIR "/gnupg-pcsc-wrapper"; if (access (wrapperpgm, X_OK)) Modified: trunk/scd/command.c =================================================================== --- trunk/scd/command.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/scd/command.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -124,7 +124,7 @@ /* While doing a reset we need to make sure that the ticker does not call scd_update_reader_status_file while we are using it. */ -static pth_mutex_t status_file_update_lock = PTH_MUTEX_INIT; +static pth_mutex_t status_file_update_lock; /*-- Local prototypes --*/ @@ -132,6 +132,24 @@ + +/* This function must be called once to initialize this module. This + has to be done before a second thread is spawned. We can't do the + static initialization because Pth emulation code might not be able + to do a static init; in particular, it is not possible for W32. */ +void +initialize_module_command (void) +{ + static int initialized; + + if (!initialized) + { + if (pth_mutex_init (&status_file_update_lock)) + initialized = 1; + } +} + + /* Update the CARD_REMOVED element of all sessions using the reader given by SLOT to VALUE */ static void Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/scd/scdaemon.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -303,9 +303,10 @@ when adding any stuff between here and the call to INIT_SECMEM() somewhere after the option parsing */ log_set_prefix ("scdaemon", 1|4); - /* Try to auto set the character set. */ - set_native_charset (NULL); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); + i18n_init (); /* Libgcrypt requires us to register the threading model first. @@ -522,6 +523,8 @@ log_debug ("... okay\n"); } + initialize_module_command (); + if (gpgconf_list == 2) scd_exit (0); if (gpgconf_list) @@ -586,6 +589,7 @@ pth_attr_t tattr; int fd = -1; +#ifndef HAVE_W32_SYSTEM { struct sigaction sa; @@ -594,6 +598,7 @@ sa.sa_flags = 0; sigaction (SIGPIPE, &sa, NULL); } +#endif /* If --debug-allow-core-dump has been given we also need to switch the working directory to a place where we can actually Modified: trunk/scd/scdaemon.h =================================================================== --- trunk/scd/scdaemon.h 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/scd/scdaemon.h 2007-06-14 17:05:07 UTC (rev 4512) @@ -124,6 +124,7 @@ const char *scd_get_socket_name (void); /*-- command.c --*/ +void initialize_module_command (void); void scd_command_handler (ctrl_t, int); void send_status_info (ctrl_t ctrl, const char *keyword, ...) GNUPG_GCC_A_SENTINEL(1); Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/sm/ChangeLog 2007-06-14 17:05:07 UTC (rev 4512) @@ -1,3 +1,23 @@ +2007-06-14 Werner Koch + + * call-agent.c (start_agent): Use gnupg_module_name. + * call-dirmngr.c (start_dirmngr): Ditto. + * export.c (export_p12): Ditto. + * import.c (parse_p12): Ditto. + * gpgsm.c (run_protect_tool): Ditto. + +2007-06-12 Werner Koch + + * gpgsm.c (main): Replace some calls by init_common_subsystems. + (main): Use gnupg_datadir. + * qualified.c (read_list): Use gnupg-datadir. + +2007-06-11 Werner Koch + + * Makefile.am (common_libs): Use libcommaonstd macr. + + * gpgsm.c (main) [W32]: Call pth_init. + 2007-06-06 Werner Koch * qualified.c (gpgsm_not_qualified_warning) [!ENABLE_NLS]: Do not Modified: trunk/sm/Makefile.am =================================================================== --- trunk/sm/Makefile.am 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/sm/Makefile.am 2007-06-14 17:05:07 UTC (rev 4512) @@ -54,7 +54,7 @@ common_libs = ../jnlib/libjnlib.a ../kbx/libkeybox.a \ - ../common/libcommon.a ../gl/libgnu.a + $(libcommon) ../gl/libgnu.a gpgsm_LDADD = $(common_libs) \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) \ Modified: trunk/sm/call-agent.c =================================================================== --- trunk/sm/call-agent.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/sm/call-agent.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -94,6 +94,10 @@ sockname = make_filename (opt.homedir, "S.gpg-agent", NULL); rc = assuan_socket_connect (&ctx, sockname, 0); xfree (sockname); +#ifdef HAVE_W32_SYSTEM +# warning Print a warning if connecting is not possible + /* and offer to fire up the agent. */ +#endif if (rc) { @@ -112,7 +116,7 @@ } if (!opt.agent_program || !*opt.agent_program) - opt.agent_program = GNUPG_DEFAULT_AGENT; + opt.agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); if ( !(pgmname = strrchr (opt.agent_program, '/'))) pgmname = opt.agent_program; else Modified: trunk/sm/call-dirmngr.c =================================================================== --- trunk/sm/call-dirmngr.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/sm/call-dirmngr.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -172,7 +172,7 @@ int i; if (!opt.dirmngr_program || !*opt.dirmngr_program) - opt.dirmngr_program = GNUPG_DEFAULT_DIRMNGR; + opt.dirmngr_program = gnupg_module_name (GNUPG_MODULE_NAME_DIRMNGR); if ( !(pgmname = strrchr (opt.dirmngr_program, '/'))) pgmname = opt.dirmngr_program; else Modified: trunk/sm/export.c =================================================================== --- trunk/sm/export.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/sm/export.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -604,7 +604,7 @@ int bad_pass = 0; if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgmname = GNUPG_DEFAULT_PROTECT_TOOL; + pgmname = gnupg_module_name (GNUPG_MODULE_NAME_PROTECT_TOOL); else pgmname = opt.protect_tool_program; Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/sm/gpgsm.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -747,8 +747,8 @@ somewhere after the option parsing */ log_set_prefix ("gpgsm", 1); - /* Try to auto set the character set. */ - set_native_charset (NULL); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); /* Check that the libraries are suitable. Do it here because the option parse may need services of the library */ @@ -1310,7 +1310,7 @@ /* Import the standard certificates for a new default keybox. */ char *filelist[2]; - filelist[0] = make_filename (GNUPG_DATADIR, "com-certs.pem", NULL); + filelist[0] = make_filename (gnupg_datadir (),"com-certs.pem", NULL); filelist[1] = NULL; if (!access (filelist[0], F_OK)) { @@ -1853,7 +1853,7 @@ int i; if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgm = GNUPG_DEFAULT_PROTECT_TOOL; + pgm = gnupg_module_name (GNUPG_MODULE_NAME_PROTECT_TOOL); else pgm = opt.protect_tool_program; Modified: trunk/sm/import.c =================================================================== --- trunk/sm/import.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/sm/import.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -509,7 +509,7 @@ int bad_pass = 0; if (!opt.protect_tool_program || !*opt.protect_tool_program) - pgmname = GNUPG_DEFAULT_PROTECT_TOOL; + pgmname = gnupg_module_name (GNUPG_MODULE_NAME_PROTECT_TOOL); else pgmname = opt.protect_tool_program; Modified: trunk/sm/qualified.c =================================================================== --- trunk/sm/qualified.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/sm/qualified.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -66,7 +66,7 @@ if (!listname) { - listname = make_filename (GNUPG_DATADIR, "qualified.txt", NULL); + listname = make_filename (gnupg_datadir (), "qualified.txt", NULL); listfp = fopen (listname, "r"); if (!listfp && errno != ENOENT) { Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/tools/ChangeLog 2007-06-14 17:05:07 UTC (rev 4512) @@ -1,3 +1,25 @@ +2007-06-14 Werner Koch + + * symcryptrun.c (main): Setup default socket name for + simple-pwquery. + (MAP_SPWQ_ERROR_IMPL): New. Use it for all spwq error returns. + +2007-06-12 Werner Koch + + * gpgconf-comp.c (gc_process_gpgconf_conf): Replace + GNUPG_SYSCONFDIR by a function call. + + * gpg-connect-agent.c (main): Replace some calls by + init_common_subsystems. + * gpgconf.c (main): Ditto. + * symcryptrun.c (main): Ditto. + +2007-06-11 Werner Koch + + * symcryptrun.c (main) [W32]: Call pth_init. + * gpgconf.c (main) [W32]: Call pth_init + * gpg-connect-agent.c (main) [W32]: Call pth_init. + 2007-06-06 Werner Koch * Makefile.am (bin_PROGRAMS) [W32]: Do not build gpgparsemail. Modified: trunk/tools/Makefile.am =================================================================== --- trunk/tools/Makefile.am 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/tools/Makefile.am 2007-06-14 17:05:07 UTC (rev 4512) @@ -50,17 +50,19 @@ noinst_PROGRAMS = clean-sat mk-tdata make-dns-cert gpgsplit -common_libs = ../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a +common_libs = ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a pwquery_libs = ../common/libsimple-pwquery.a -gpgsplit_LDADD = $(common_libs) $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \ +gpgsplit_LDADD = $(common_libs) \ + $(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) \ $(ZLIBS) $(LIBINTL) $(LIBICONV) gpgconf_SOURCES = gpgconf.c gpgconf.h gpgconf-comp.c no-libgcrypt.c # jnlib/common sucks in gpg-error, will they, nil they (some compilers # do not eliminate the supposed-to-be-unused-inline-functions). -gpgconf_LDADD = $(common_libs) $(LIBINTL) $(GPG_ERROR_LIBS) $(LIBICONV) +gpgconf_LDADD = $(common_libs) \ + $(LIBINTL) $(GPG_ERROR_LIBS) $(LIBICONV) gpgparsemail_SOURCES = gpgparsemail.c rfc822parse.c rfc822parse.h gpgparsemail_LDADD = @@ -73,7 +75,8 @@ watchgnupg_LDADD = $(NETLIBS) gpg_connect_agent_SOURCES = gpg-connect-agent.c no-libgcrypt.c -gpg_connect_agent_LDADD = $(common_libs) $(LIBASSUAN_LIBS) \ +# FIXME: remove PTH_LIBS (why do we need them at all?) +gpg_connect_agent_LDADD = $(common_libs) $(LIBASSUAN_LIBS) $(PTH_LIBS) \ $(GPG_ERROR_LIBS) $(LIBINTL) $(NETLIBS) $(LIBICONV) gpgkey2ssh_SOURCES = gpgkey2ssh.c Modified: trunk/tools/gpg-connect-agent.c =================================================================== --- trunk/tools/gpg-connect-agent.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/tools/gpg-connect-agent.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -274,6 +274,10 @@ set_strusage (my_strusage); log_set_prefix ("gpg-connect-agent", 1); + + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); + assuan_set_assuan_err_source (0); i18n_init(); Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/tools/gpgconf-comp.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -2676,9 +2676,13 @@ int runtime[GC_BACKEND_NR]; int used_components[GC_COMPONENT_NR]; int backend_id, component_id; + char *fname_buffer = NULL; if (!fname) - fname = GNUPG_SYSCONFDIR "/gpgconf.conf"; + { + fname_buffer = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL); + fname = fname_buffer; + } for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++) runtime[backend_id] = 0; @@ -2695,6 +2699,7 @@ gc_error (0, errno, "can not open global config file `%s'", fname); result = -1; } + xfree (fname_buffer); return result; } @@ -2931,5 +2936,6 @@ } } + xfree (fname_buffer); return result; } Modified: trunk/tools/gpgconf.c =================================================================== --- trunk/tools/gpgconf.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/tools/gpgconf.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -116,6 +116,9 @@ set_strusage (my_strusage); log_set_prefix ("gpgconf", 1); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); + i18n_init(); /* Parse the command line. */ Modified: trunk/tools/symcryptrun.c =================================================================== --- trunk/tools/symcryptrun.c 2007-06-13 15:28:11 UTC (rev 4511) +++ trunk/tools/symcryptrun.c 2007-06-14 17:05:07 UTC (rev 4512) @@ -238,6 +238,8 @@ __result; })) #endif +/* Include the implementation of map_spwq_error. */ +MAP_SPWQ_ERROR_IMPL /* Unlink a file, and shred it if SHRED is true. */ int @@ -455,6 +457,7 @@ pw = simple_pwquery (cacheid, again ? _("does not match - try again"):NULL, _("Passphrase:"), NULL, 0, &err); + err = map_spwq_error (err); #ifdef ENABLE_NLS if (orig_codeset) @@ -911,8 +914,8 @@ set_strusage (my_strusage); log_set_prefix ("symcryptrun", 1); - /* Try to auto set the character set. */ - set_native_charset (NULL); + /* Make sure that our subsystems are ready. */ + init_common_subsystems (); i18n_init(); @@ -1028,13 +1031,22 @@ setup_libgcrypt_logging (); gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); + /* 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); + } + if (!opt.class) { log_error (_("no class provided\n")); res = 1; } else if (!strcmp (opt.class, "confucius")) - res = confucius_main (mode, argc, argv); + { + res = confucius_main (mode, argc, argv); + } else { log_error (_("class %s is not supported\n"), opt.class); From cvs at cvs.gnupg.org Fri Jun 15 13:06:02 2007 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 15 Jun 2007 13:06:02 +0200 Subject: [svn] assuan - r239 - trunk Message-ID: Author: marcus Date: 2007-06-15 13:05:31 +0200 (Fri, 15 Jun 2007) New Revision: 239 Modified: trunk/ChangeLog trunk/autogen.sh Log: 2007-06-15 Marcus Brinkmann * autogen.sh: Require bash. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-06-12 13:39:37 UTC (rev 238) +++ trunk/ChangeLog 2007-06-15 11:05:31 UTC (rev 239) @@ -1,3 +1,7 @@ +2007-06-15 Marcus Brinkmann + + * autogen.sh: Require bash. + 2007-05-30 Werner Koch * autogen.sh <--build-w32>: Modernize. Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2007-06-12 13:39:37 UTC (rev 238) +++ trunk/autogen.sh 2007-06-15 11:05:31 UTC (rev 239) @@ -1,4 +1,4 @@ -#! /bin/sh +#! /bin/bash # Run this to generate all the initial makefiles, etc. # # Copyright (C) 2003 g10 Code GmbH From cvs at cvs.gnupg.org Fri Jun 15 13:26:51 2007 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 15 Jun 2007 13:26:51 +0200 Subject: [svn] GnuPG - r4513 - trunk/m4 Message-ID: Author: marcus Date: 2007-06-15 13:26:21 +0200 (Fri, 15 Jun 2007) New Revision: 4513 Modified: trunk/m4/ChangeLog trunk/m4/Makefile.am Log: 2007-06-15 Marcus Brinkmann * Makefile.am (EXTRA_DIST): Remove inttypes-h.m4. Modified: trunk/m4/ChangeLog =================================================================== --- trunk/m4/ChangeLog 2007-06-14 17:05:07 UTC (rev 4512) +++ trunk/m4/ChangeLog 2007-06-15 11:26:21 UTC (rev 4513) @@ -1,3 +1,7 @@ +2007-06-15 Marcus Brinkmann + + * Makefile.am (EXTRA_DIST): Remove inttypes-h.m4. + 2007-05-30 Werner Koch * gnupg-pth.m4: Remove W32 kludge. Modified: trunk/m4/Makefile.am =================================================================== --- trunk/m4/Makefile.am 2007-06-14 17:05:07 UTC (rev 4512) +++ trunk/m4/Makefile.am 2007-06-15 11:26:21 UTC (rev 4513) @@ -1,4 +1,4 @@ -EXTRA_DIST = intl.m4 intldir.m4 glibc2.m4 inttypes-h.m4 lock.m4 visibility.m4 intmax.m4 longdouble.m4 longlong.m4 printf-posix.m4 signed.m4 size_max.m4 wchar_t.m4 wint_t.m4 xsize.m4 codeset.m4 gettext.m4 glibc21.m4 iconv.m4 intdiv0.m4 inttypes.m4 inttypes_h.m4 inttypes-pri.m4 isc-posix.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 progtest.m4 stdint_h.m4 uintmax_t.m4 ulonglong.m4 +EXTRA_DIST = intl.m4 intldir.m4 glibc2.m4 lock.m4 visibility.m4 intmax.m4 longdouble.m4 longlong.m4 printf-posix.m4 signed.m4 size_max.m4 wchar_t.m4 wint_t.m4 xsize.m4 codeset.m4 gettext.m4 glibc21.m4 iconv.m4 intdiv0.m4 inttypes.m4 inttypes_h.m4 inttypes-pri.m4 isc-posix.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 progtest.m4 stdint_h.m4 uintmax_t.m4 ulonglong.m4 EXTRA_DIST += ldap.m4 libcurl.m4 libusb.m4 tar-ustar.m4 readline.m4 From cvs at cvs.gnupg.org Fri Jun 15 13:33:53 2007 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 15 Jun 2007 13:33:53 +0200 Subject: [svn] GnuPG - r4514 - trunk/m4 Message-ID: Author: marcus Date: 2007-06-15 13:33:25 +0200 (Fri, 15 Jun 2007) New Revision: 4514 Modified: trunk/m4/ChangeLog trunk/m4/Makefile.am Log: 2007-06-15 Marcus Brinkmann * Makefile.am (EXTRA_DIST): Remove inttypes-h.m4, longlong.m4 and ulonglong.m4. Modified: trunk/m4/ChangeLog =================================================================== --- trunk/m4/ChangeLog 2007-06-15 11:26:21 UTC (rev 4513) +++ trunk/m4/ChangeLog 2007-06-15 11:33:25 UTC (rev 4514) @@ -1,6 +1,7 @@ 2007-06-15 Marcus Brinkmann - * Makefile.am (EXTRA_DIST): Remove inttypes-h.m4. + * Makefile.am (EXTRA_DIST): Remove inttypes-h.m4, longlong.m4 and + ulonglong.m4. 2007-05-30 Werner Koch Modified: trunk/m4/Makefile.am =================================================================== --- trunk/m4/Makefile.am 2007-06-15 11:26:21 UTC (rev 4513) +++ trunk/m4/Makefile.am 2007-06-15 11:33:25 UTC (rev 4514) @@ -1,4 +1,4 @@ -EXTRA_DIST = intl.m4 intldir.m4 glibc2.m4 lock.m4 visibility.m4 intmax.m4 longdouble.m4 longlong.m4 printf-posix.m4 signed.m4 size_max.m4 wchar_t.m4 wint_t.m4 xsize.m4 codeset.m4 gettext.m4 glibc21.m4 iconv.m4 intdiv0.m4 inttypes.m4 inttypes_h.m4 inttypes-pri.m4 isc-posix.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 progtest.m4 stdint_h.m4 uintmax_t.m4 ulonglong.m4 +EXTRA_DIST = intl.m4 intldir.m4 glibc2.m4 lock.m4 visibility.m4 intmax.m4 longdouble.m4 printf-posix.m4 signed.m4 size_max.m4 wchar_t.m4 wint_t.m4 xsize.m4 codeset.m4 gettext.m4 glibc21.m4 iconv.m4 intdiv0.m4 inttypes.m4 inttypes_h.m4 inttypes-pri.m4 isc-posix.m4 lcmessage.m4 lib-ld.m4 lib-link.m4 lib-prefix.m4 progtest.m4 stdint_h.m4 uintmax_t.m4 EXTRA_DIST += ldap.m4 libcurl.m4 libusb.m4 tar-ustar.m4 readline.m4 From cvs at cvs.gnupg.org Fri Jun 15 14:32:00 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 15 Jun 2007 14:32:00 +0200 Subject: [svn] ksba - r275 - trunk/src Message-ID: Author: wk Date: 2007-06-15 14:31:31 +0200 (Fri, 15 Jun 2007) New Revision: 275 Modified: trunk/src/ChangeLog trunk/src/Makefile.am Log: Take builded gnulib header in account. Modified: trunk/src/ChangeLog =================================================================== --- trunk/src/ChangeLog 2007-05-29 17:36:24 UTC (rev 274) +++ trunk/src/ChangeLog 2007-06-15 12:31:31 UTC (rev 275) @@ -1,3 +1,8 @@ +2007-06-15 Werner Koch + + * Makefile.am (AM_CPPFLAGS): Add top_builddir/gl as gnulib may + create a header. + 2007-05-29 Werner Koch * versioninfo.rc.in: New. Modified: trunk/src/Makefile.am =================================================================== --- trunk/src/Makefile.am 2007-05-29 17:36:24 UTC (rev 274) +++ trunk/src/Makefile.am 2007-06-15 12:31:31 UTC (rev 275) @@ -36,7 +36,7 @@ m4datadir = $(datadir)/aclocal m4data_DATA = ksba.m4 -AM_CPPFLAGS = -I$(top_srcdir)/gl +AM_CPPFLAGS = -I$(top_builddir)/gl -I$(top_srcdir)/gl AM_CFLAGS = $(GPG_ERROR_CFLAGS) From cvs at cvs.gnupg.org Fri Jun 15 15:24:52 2007 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 15 Jun 2007 15:24:52 +0200 Subject: [svn] gcry - r1256 - trunk Message-ID: Author: marcus Date: 2007-06-15 15:24:23 +0200 (Fri, 15 Jun 2007) New Revision: 1256 Modified: trunk/ChangeLog trunk/autogen.sh Log: 2007-06-15 Marcus Brinkmann * autogen.sh: Use = instead of == in test. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-06-06 17:01:56 UTC (rev 1255) +++ trunk/ChangeLog 2007-06-15 13:24:23 UTC (rev 1256) @@ -1,3 +1,7 @@ +2007-06-15 Marcus Brinkmann + + * autogen.sh: Use = instead of == in test. + 2007-05-30 Werner Koch * configure.ac: Camellia is no longer GPL. Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2007-06-06 17:01:56 UTC (rev 1255) +++ trunk/autogen.sh 2007-06-15 13:24:23 UTC (rev 1256) @@ -31,7 +31,7 @@ DIE=no FORCE= -if test "$1" == "--force"; then +if test "$1" = "--force"; then FORCE=" --force" shift fi From cvs at cvs.gnupg.org Fri Jun 15 16:46:52 2007 From: cvs at cvs.gnupg.org (svn author marcus) Date: Fri, 15 Jun 2007 16:46:52 +0200 Subject: [svn] GnuPG - r4516 - trunk/tools Message-ID: Author: marcus Date: 2007-06-15 16:46:23 +0200 (Fri, 15 Jun 2007) New Revision: 4516 Modified: trunk/tools/ChangeLog trunk/tools/gpgconf-comp.c Log: 2007-06-15 Marcus Brinkmann * gpgconf-comp.c (copy_file) [HAVE_W32_SYSTEM]: New function. (change_options_file, change_options_program) [HAVE_W32_SYSTEM]: Copy backup file. (gc_component_change_options) [HAVE_W32_SYSTEM]: Non-atomic replace. (gc_process_gpgconf_conf): Rename fname to fname_arg and fname_buffer to fname, initialize fname with fname_arg, discarding const qualifier. Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2007-06-15 14:27:31 UTC (rev 4515) +++ trunk/tools/ChangeLog 2007-06-15 14:46:23 UTC (rev 4516) @@ -1,3 +1,13 @@ +2007-06-15 Marcus Brinkmann + + * gpgconf-comp.c (copy_file) [HAVE_W32_SYSTEM]: New function. + (change_options_file, change_options_program) [HAVE_W32_SYSTEM]: + Copy backup file. + (gc_component_change_options) [HAVE_W32_SYSTEM]: Non-atomic replace. + (gc_process_gpgconf_conf): Rename fname to fname_arg and + fname_buffer to fname, initialize fname with fname_arg, discarding + const qualifier. + 2007-06-15 Werner Koch * Makefile.am (symcryptrun_LDADD): It is LIBICONV and not LIBINCONV. Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2007-06-15 14:27:31 UTC (rev 4515) +++ trunk/tools/gpgconf-comp.c 2007-06-15 14:46:23 UTC (rev 4516) @@ -1,5 +1,5 @@ /* gpgconf-comp.c - Configuration utility for GnuPG. - * Copyright (C) 2004 Free Software Foundation, Inc. + * Copyright (C) 2004, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1725,7 +1725,52 @@ while (arg && *arg); } +#ifdef HAVE_W32_SYSTEM +int +copy_file (const char *src_name, const char *dst_name) +{ +#define BUF_LEN 4096 + char buffer[BUF_LEN]; + int len; + FILE *src; + FILE *dst; + src = fopen (src_name, "r"); + if (src == NULL) + return -1; + + dst = fopen (dst_name, "w"); + if (dst == NULL) + { + int saved_err = errno; + fclose (src); + errno = saved_err; + return -1; + } + + do + { + int written; + + len = fread (buffer, 1, BUF_LEN, src); + if (len == 0) + break; + written = fwrite (buffer, 1, len, dst); + if (written != len) + break; + } + while (!feof (src) && !ferror (src) && !ferror (dst)); + + if (ferror (src) || ferror (dst) || !feof (src)) + { + unlink (dst_name); + return -1; + } + + return 0; +} +#endif /* HAVE_W32_SYSTEM */ + /* Create and verify the new configuration file for the specified backend and component. Returns 0 on success and -1 on error. */ static int @@ -1785,9 +1830,8 @@ arg = NULL; } -#if HAVE_W32_SYSTEM - res = 0; -#warning no backups for W32 yet - need to write a copy function +#ifdef HAVE_W32_SYSTEM + res = copy_file (dest_filename, orig_filename); #else res = link (dest_filename, orig_filename); #endif @@ -2054,9 +2098,8 @@ src_filename = xasprintf ("%s.gpgconf.%i.new", dest_filename, getpid ()); orig_filename = xasprintf ("%s.gpgconf.%i.bak", dest_filename, getpid ()); -#if HAVE_W32_SYSTEM - res = 0; -#warning no backups for W32 yet - need to write a copy function +#ifdef HAVE_W32_SYSTEM + res = copy_file (dest_filename, orig_filename); #else res = link (dest_filename, orig_filename); #endif @@ -2492,22 +2535,27 @@ assert (dest_pathname[i]); if (orig_pathname[i]) - err = rename (src_pathname[i], dest_pathname[i]); + { +#ifdef HAVE_W32_SYSTEM + /* There is no atomic update on W32. */ + unlink (dest_pathname[i]); +#endif /* HAVE_W32_SYSTEM */ + err = rename (src_pathname[i], dest_pathname[i]); + } else { #ifdef HAVE_W32_SYSTEM - /* FIXME: Won't work becuase W32 doesn't silently - overwrite. Fix it by creating a backup copy and - deliting the orginal file first. */ + /* We skip the unlink if we do not expect the file + to be there. */ err = rename (src_pathname[i], dest_pathname[i]); -#else /*!HAVE_W32_SYSTEM*/ +#else /* HAVE_W32_SYSTEM */ /* This is a bit safer than rename() because we expect DEST_PATHNAME not to be there. If it happens to be there, this will fail. */ err = link (src_pathname[i], dest_pathname[i]); if (!err) unlink (src_pathname[i]); -#endif /*!HAVE_W32_SYSTEM*/ +#endif /* !HAVE_W32_SYSTEM */ } if (err) break; @@ -2538,7 +2586,13 @@ a version of the file that is even newer than the one we just installed. */ if (orig_pathname[i]) - rename (orig_pathname[i], dest_pathname[i]); + { +#ifdef HAVE_W32_SYSTEM + /* There is no atomic update on W32. */ + unlink (dest_pathname[i]); +#endif /* HAVE_W32_SYSTEM */ + rename (orig_pathname[i], dest_pathname[i]); + } else unlink (dest_pathname[i]); } @@ -2663,7 +2717,7 @@ Returns 0 on success or if the config file is not present; -1 is returned on error. */ int -gc_process_gpgconf_conf (const char *fname, int update, int defaults) +gc_process_gpgconf_conf (const char *fname_arg, int update, int defaults) { int result = 0; char *line = NULL; @@ -2676,13 +2730,10 @@ int runtime[GC_BACKEND_NR]; int used_components[GC_COMPONENT_NR]; int backend_id, component_id; - char *fname_buffer = NULL; + char *fname = (char *) fname_arg; if (!fname) - { - fname_buffer = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL); - fname = fname_buffer; - } + fname = make_filename (gnupg_sysconfdir (), "gpgconf.conf", NULL); for (backend_id = 0; backend_id < GC_BACKEND_NR; backend_id++) runtime[backend_id] = 0; @@ -2699,7 +2750,7 @@ gc_error (0, errno, "can not open global config file `%s'", fname); result = -1; } - xfree (fname_buffer); + xfree (fname); return result; } @@ -2936,6 +2987,6 @@ } } - xfree (fname_buffer); + xfree (fname); return result; } From cvs at cvs.gnupg.org Fri Jun 15 17:39:14 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 15 Jun 2007 17:39:14 +0200 Subject: [svn] GnuPG - r4517 - trunk Message-ID: Author: wk Date: 2007-06-15 17:38:44 +0200 (Fri, 15 Jun 2007) New Revision: 4517 Modified: trunk/ChangeLog trunk/configure.ac Log: PO fixes for W32 Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-06-15 14:46:23 UTC (rev 4516) +++ trunk/ChangeLog 2007-06-15 15:38:44 UTC (rev 4517) @@ -1,6 +1,7 @@ 2007-06-15 Werner Koch - * configure.ac (W32SOCKLIBS): New. + * configure.ac: Call AM_PO_SUBDIRS. + (W32SOCKLIBS): New. * autogen.sh: Use = and not == in test to be POSIXly correct. : Disable use of regex. Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2007-06-15 14:46:23 UTC (rev 4516) +++ trunk/configure.ac 2007-06-15 15:38:44 UTC (rev 4517) @@ -873,6 +873,7 @@ # Check for gettext # AC_MSG_NOTICE([checking for gettext]) +AM_PO_SUBDIRS AM_GNU_GETTEXT_VERSION([0.16.1]) if test "$try_gettext" = yes; then AM_GNU_GETTEXT(,[need-ngettext]) @@ -886,9 +887,11 @@ USE_NLS=no USE_INCLUDED_LIBINTL=no BUILD_INCLUDED_LIBINTL=no + POSUB=po AC_SUBST(USE_NLS) AC_SUBST(USE_INCLUDED_LIBINTL) AC_SUBST(BUILD_INCLUDED_LIBINTL) + AC_SUBST(POSUB) fi From cvs at cvs.gnupg.org Mon Jun 18 12:33:43 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 18 Jun 2007 12:33:43 +0200 Subject: [svn] GnuPG - r4518 - in trunk: agent doc Message-ID: Author: wk Date: 2007-06-18 12:33:12 +0200 (Mon, 18 Jun 2007) New Revision: 4518 Added: trunk/agent/w32main.c trunk/agent/w32main.h Modified: trunk/agent/ChangeLog trunk/agent/Makefile.am trunk/agent/agent.h trunk/agent/command.c trunk/agent/gpg-agent.c trunk/doc/ChangeLog trunk/doc/gpg-agent.texi Log: Add missing fiels for W32. New agent commands: GETINFO and KILLAGENT (w32 only). Agent does now detach from the console. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2007-06-15 15:38:44 UTC (rev 4517) +++ trunk/agent/ChangeLog 2007-06-18 10:33:12 UTC (rev 4518) @@ -1,3 +1,11 @@ +2007-06-18 Werner Koch + + * command.c (cmd_killagent) [W32]: New. + (cmd_getinfo): New. + * gpg-agent.c (get_agent_ssh_socket_name): New. + + * Makefile.am (gpg_agent_res_ldflags): Pass windows option to ld. + 2007-06-14 Werner Koch * protect-tool.c (main): Setup default socket name for Modified: trunk/agent/Makefile.am =================================================================== --- trunk/agent/Makefile.am 2007-06-15 15:38:44 UTC (rev 4517) +++ trunk/agent/Makefile.am 2007-06-18 10:33:12 UTC (rev 4518) @@ -60,7 +60,7 @@ $(WINDRES) `echo $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) | \ sed -e 's/-I/--include-dir /g;s/-D/--define /g'` -i $< -o $@ -gpg_agent_res_ldflags = -Wl,gpg-agent-resource.o +gpg_agent_res_ldflags = -Wl,gpg-agent-resource.o -Wl,--subsystem,windows gpg_agent_res_deps = gpg-agent-resource.o else gpg_agent_res_ldflags = Modified: trunk/agent/agent.h =================================================================== --- trunk/agent/agent.h 2007-06-15 15:38:44 UTC (rev 4517) +++ trunk/agent/agent.h 2007-06-18 10:33:12 UTC (rev 4518) @@ -191,6 +191,7 @@ /*-- gpg-agent.c --*/ void agent_exit (int rc) JNLIB_GCC_A_NR; /* Also implemented in other tools */ const char *get_agent_socket_name (void); +const char *get_agent_ssh_socket_name (void); /*-- command.c --*/ gpg_error_t agent_write_status (ctrl_t ctrl, const char *keyword, ...); Modified: trunk/agent/command.c =================================================================== --- trunk/agent/command.c 2007-06-15 15:38:44 UTC (rev 4517) +++ trunk/agent/command.c 2007-06-18 10:33:12 UTC (rev 4518) @@ -58,6 +58,10 @@ char *keydesc; /* Allocated description for the next key operation. */ int pause_io_logging; /* Used to suppress I/O logging during a command */ +#ifdef HAVE_W32_SYSTEM + int stopme; /* If set to true the agent will be terminated after + the end of this session. */ +#endif }; @@ -1307,7 +1311,68 @@ +#ifdef HAVE_W32_SYSTEM +/* KILLAGENT + + Under Windows we start the agent on the fly. Thus it also make + sense to allow a client to stop the agent. */ static int +cmd_killagent (assuan_context_t ctx, char *line) +{ + ctrl_t ctrl = assuan_get_pointer (ctx); + ctrl->server_local->stopme = 1; + return 0; +} +#endif /*HAVE_W32_SYSTEM*/ + + + +/* GETINFO + + Multipurpose function to return a variety of information. + Supported values for WHAT are: + + version - Return the version of the program. + socket_name - Return the name of the socket. + ssh_socket_name - Return the name of the ssh socket. + + */ +static int +cmd_getinfo (assuan_context_t ctx, char *line) +{ + int rc = 0; + + if (!strcmp (line, "version")) + { + const char *s = VERSION; + rc = assuan_send_data (ctx, s, strlen (s)); + } + else if (!strcmp (line, "socket_name")) + { + const char *s = get_agent_socket_name (); + + if (s) + rc = assuan_send_data (ctx, s, strlen (s)); + else + rc = gpg_error (GPG_ERR_NO_DATA); + } + else if (!strcmp (line, "ssh_socket_name")) + { + const char *s = get_agent_ssh_socket_name (); + + if (s) + rc = assuan_send_data (ctx, s, strlen (s)); + else + rc = gpg_error (GPG_ERR_NO_DATA); + } + else + rc = set_error (GPG_ERR_ASS_PARAMETER, "unknown value for WHAT"); + return rc; +} + + + +static int option_handler (assuan_context_t ctx, const char *key, const char *value) { ctrl_t ctrl = assuan_get_pointer (ctx); @@ -1439,6 +1504,10 @@ { "GETVAL", cmd_getval }, { "PUTVAL", cmd_putval }, { "UPDATESTARTUPTTY", cmd_updatestartuptty }, +#ifdef HAVE_W32_SYSTEM + { "KILLAGENT", cmd_killagent }, +#endif + { "GETINFO", cmd_getinfo }, { NULL } }; int i, rc; @@ -1542,6 +1611,10 @@ /* Cleanup. */ assuan_deinit_server (ctx); +#ifdef HAVE_W32_SYSTEM + if (ctrl->server_local->stopme) + agent_exit (0); +#endif xfree (ctrl->server_local); ctrl->server_local = NULL; } Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2007-06-15 15:38:44 UTC (rev 4517) +++ trunk/agent/gpg-agent.c 2007-06-18 10:33:12 UTC (rev 4518) @@ -1162,8 +1162,18 @@ return (s && *s)? s : NULL; } +/* Return the file name of the socket we are using for SSH + requests. */ +const char * +get_agent_ssh_socket_name (void) +{ + const char *s = socket_name_ssh; + return (s && *s)? s : NULL; +} + + /* Create a name for the socket. With USE_STANDARD_SOCKET given as true using STANDARD_NAME in the home directory or if given as false from the mkdir type name TEMPLATE. In the latter case a Added: trunk/agent/w32main.c =================================================================== --- trunk/agent/w32main.c 2007-06-15 15:38:44 UTC (rev 4517) +++ trunk/agent/w32main.c 2007-06-18 10:33:12 UTC (rev 4518) @@ -0,0 +1,178 @@ +/* w32main.c - W32 main entry pint and taskbar support for the GnuPG Agent + * Copyright (C) 2007 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include +#ifndef HAVE_W32_SYSTEM +#error This module is only useful for the W32 version of gpg-agent +#endif + +#include +#include +#include +#include + +#include "util.h" +#include "w32main.h" + +/* The instance handle has received by WinMain. */ +static HINSTANCE glob_hinst; +static HWND glob_hwnd; + + +/* Our window message processing function. */ +static LRESULT CALLBACK +wndw_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + + switch (msg) + { + case WM_USER: + fprintf (stderr,"%s: received WM_%s\n", __func__, "USER" ); + break; + + } + + return DefWindowProc (hwnd, msg, wparam, lparam); +} + + +/* This function is called to do some fast event polling and + processing. */ +void +w32_poll_events (void) +{ +/* MSG msg; */ + +/* fprintf (stderr,"%s: enter\n", __func__); */ +/* while (PeekMessage (&msg, glob_hwnd, 0, 0, PM_REMOVE)) */ +/* { */ +/* DispatchMessage (&msg); */ +/* } */ +/* fprintf (stderr,"%s: leave\n", __func__); */ +} + + + +static void * +handle_taskbar (void *ctx) +{ + WNDCLASS wndwclass = {0, wndw_proc, 0, 0, glob_hinst, + 0, 0, 0, 0, "gpg-agent"}; + NOTIFYICONDATA nid; + HWND hwnd; + MSG msg; + int rc; + + if (!RegisterClass (&wndwclass)) + { + log_error ("error registering window class\n"); + ExitThread (0); + } + hwnd = CreateWindow ("gpg-agent", "gpg-agent", + 0, 0, 0, 0, 0, + NULL, NULL, glob_hinst, NULL); + if (!hwnd) + { + log_error ("error creating main window\n"); + ExitThread (0); + } + glob_hwnd = hwnd; + UpdateWindow (hwnd); + + memset (&nid, 0, sizeof nid); + nid.cbSize = sizeof (nid); + nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; + nid.uCallbackMessage = WM_USER; + nid.hWnd = glob_hwnd; + nid.uID = 1; + nid.hIcon = LoadIcon (glob_hinst, MAKEINTRESOURCE (1)); + mem2str (nid.szTip, "GnuPG Agent version "PACKAGE_VERSION, + sizeof nid.szTip); + Shell_NotifyIcon (NIM_ADD, &nid); + DestroyIcon (nid.hIcon); + + fprintf (stderr, "%s: enter\n", __func__); + while ( (rc=GetMessage (&msg, hwnd, 0, 0)) ) + { + if (rc == -1) + { + log_error ("getMessage failed: %s\n", w32_strerror (-1)); + break; + } + TranslateMessage (&msg); + DispatchMessage (&msg); + } + fprintf (stderr,"%s: leave\n", __func__); + ExitThread (0); + return NULL; +} + + + +/* This function initializes the Window system and sets up the taskbar + icon. We only have very limited GUI support just to give the + taskbar icon a little bit of life. This fucntion is called once to + fire up the icon. */ +int +w32_setup_taskbar (void) +{ + SECURITY_ATTRIBUTES sa; + DWORD tid; + HANDLE th; + + memset (&sa, 0, sizeof sa); + sa.nLength = sizeof sa; + sa.bInheritHandle = FALSE; + + fprintf (stderr,"creating thread for the taskbar_event_loop...\n"); + th = CreateThread (&sa, 128*1024, + (LPTHREAD_START_ROUTINE)handle_taskbar, + NULL, 0, &tid); + fprintf (stderr,"created thread %p tid=%d\n", th, (int)tid); + + CloseHandle (th); + + return 0; +} + + +/* The main entry point for the Windows version. We save away all GUI + related stuff, parse the commandline and finally call the real + main. */ +int WINAPI +WinMain (HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int showcmd) +{ + /* Fixme: We need a parser for the command line. Should be + available in some CRT code - need to see whether we can find a + GNU version. For nopw we call gpg-agent with a couple of fixed arguments + */ + char *argv[] = { "gpg-agent.exe", "--daemon", "-v", "--debug-all", NULL }; + + + glob_hinst = hinst; + + return w32_main (DIM(argv)-1, argv); +} + + + + + Added: trunk/agent/w32main.h =================================================================== --- trunk/agent/w32main.h 2007-06-15 15:38:44 UTC (rev 4517) +++ trunk/agent/w32main.h 2007-06-18 10:33:12 UTC (rev 4518) @@ -0,0 +1,34 @@ +/* w32main.h - W32 main entry point and support functions + * Copyright (C) 2007 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifndef AGENT_W32MAIN_H +#define AGENT_W32MAIN_H + +/* This is the actual entry point as called by w32main.c. */ +int w32_main (int argc, char **argv ); + +/* Fire up the icon for the taskbar. */ +int w32_setup_taskbar (void); + +void w32_poll_events (void); + + +#endif /*AGENT_W32MAIN_H*/ Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2007-06-15 15:38:44 UTC (rev 4517) +++ trunk/doc/ChangeLog 2007-06-18 10:33:12 UTC (rev 4518) @@ -1,3 +1,7 @@ +2007-06-18 Werner Koch + + * gpg-agent.texi (Agent GETINFO): New. + 2007-06-06 Werner Koch * Makefile.am (yat2m): Use a plain rule to build it for the sake Modified: trunk/doc/gpg-agent.texi =================================================================== --- trunk/doc/gpg-agent.texi 2007-06-15 15:38:44 UTC (rev 4517) +++ trunk/doc/gpg-agent.texi 2007-06-18 10:33:12 UTC (rev 4518) @@ -674,6 +674,7 @@ * Agent PASSWD:: Change a Passphrase * Agent UPDATESTARTUPTTY:: Change the Standard Display * Agent GETEVENTCOUNTER:: Get the Event Counters +* Agent GETINFO:: Return information about the process @end menu @node Agent PKDECRYPT @@ -1121,7 +1122,27 @@ Incremented for changes of the card readers stati. @end table + at node Agent GETINFO + at subsection Return information about the process +This is a multipurpose function to return a variety of information. + + at example +GETINFO @var{what} + at end example + +The value of @var{what} specifies the kind of information returned: + at table @code + at item version +Return the version of the program. + at item socket_name +Return the name of the socket used to connect the agent. + at item ssh_socket_name +Return the name of the socket used for SSH connections. If SSH support +has not been enabled the error @code{GPG_ERR_NO_DATA} will be returned. + at end table + + @mansect see also @ifset isman @command{gpg2}(1), From cvs at cvs.gnupg.org Mon Jun 18 22:15:35 2007 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 18 Jun 2007 22:15:35 +0200 Subject: [svn] GnuPG - r4520 - in trunk: agent g10 jnlib scd sm Message-ID: Author: marcus Date: 2007-06-18 22:15:01 +0200 (Mon, 18 Jun 2007) New Revision: 4520 Modified: trunk/agent/ChangeLog trunk/agent/gpg-agent.c trunk/g10/ChangeLog trunk/g10/gpg.c trunk/jnlib/ChangeLog trunk/jnlib/stringhelp.c trunk/jnlib/stringhelp.h trunk/scd/ChangeLog trunk/scd/scdaemon.c trunk/sm/ChangeLog trunk/sm/gpgsm.c Log: jnlib/ 2007-06-18 Marcus Brinkmann * stringhelp.h (percent_escape): New prototype. * stringhelp.c (percent_escape): New function. agent/ 2007-06-18 Marcus Brinkmann * gpg-agent.c (main): Percent escape pathname in --gpgconf-list output. g10/ 2007-06-18 Marcus Brinkmann * gpg.c (gpgconf_list): Percent escape output of --gpgconf-list. scdaemon/ 2007-06-18 Marcus Brinkmann * scdaemon.c (main): Percent escape output of --gpgconf-list. sm/ 2007-06-18 Marcus Brinkmann * gpgsm.c (main): Percent escape output of --gpgconf-list. Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2007-06-18 20:07:33 UTC (rev 4519) +++ trunk/agent/ChangeLog 2007-06-18 20:15:01 UTC (rev 4520) @@ -1,3 +1,8 @@ +2007-06-18 Marcus Brinkmann + + * gpg-agent.c (main): Percent escape pathname in --gpgconf-list + output. + 2007-06-18 Werner Koch * command.c (cmd_killagent) [W32]: New. Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2007-06-18 20:07:33 UTC (rev 4519) +++ trunk/agent/gpg-agent.c 2007-06-18 20:15:01 UTC (rev 4520) @@ -693,6 +693,7 @@ if (gpgconf_list) { char *filename; + char *filename_esc; /* List options and default values in the GPG Conf format. */ @@ -714,9 +715,12 @@ #define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) filename = make_filename (opt.homedir, "gpg-agent.conf", NULL ); + filename_esc = percent_escape (filename); + printf ("gpgconf-gpg-agent.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, filename); + GC_OPT_FLAG_DEFAULT, filename_esc); xfree (filename); + xfree (filename_esc); printf ("verbose:%lu:\n" "quiet:%lu:\n" Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2007-06-18 20:07:33 UTC (rev 4519) +++ trunk/g10/ChangeLog 2007-06-18 20:15:01 UTC (rev 4520) @@ -1,3 +1,7 @@ +2007-06-18 Marcus Brinkmann + + * gpg.c (gpgconf_list): Percent escape output of --gpgconf-list. + 2007-06-14 Werner Koch * call-agent.c (start_agent): Use gnupg_module_name. Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2007-06-18 20:07:33 UTC (rev 4519) +++ trunk/g10/gpg.c 2007-06-18 20:15:01 UTC (rev 4520) @@ -1456,16 +1456,20 @@ static void gpgconf_list (const char *configfile) { + char *configfile_esc = percent_escape (configfile); + /* The following definitions are taken from gnupg/tools/gpgconf-comp.c. */ #define GC_OPT_FLAG_NONE 0UL #define GC_OPT_FLAG_DEFAULT (1UL << 4) printf ("gpgconf-gpg.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT,configfile?configfile:"/dev/null"); + GC_OPT_FLAG_DEFAULT, configfile_esc ? configfile_esc : "/dev/null"); printf ("verbose:%lu:\n", GC_OPT_FLAG_NONE); printf ("quiet:%lu:\n", GC_OPT_FLAG_NONE); printf ("keyserver:%lu:\n", GC_OPT_FLAG_NONE); printf ("reader-port:%lu:\n", GC_OPT_FLAG_NONE); + + xfree (configfile_esc); } Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2007-06-18 20:07:33 UTC (rev 4519) +++ trunk/jnlib/ChangeLog 2007-06-18 20:15:01 UTC (rev 4520) @@ -1,3 +1,8 @@ +2007-06-18 Marcus Brinkmann + + * stringhelp.h (percent_escape): New prototype. + * stringhelp.c (percent_escape): New function. + 2007-06-11 Werner Koch * utf8conv.c (jnlib_iconv_open, jnlib_iconv, jnlib_iconv_close): New. @@ -470,7 +475,7 @@ *********************************************************** Copyright 2000, 2001, 2002, 2003, 2004, - 2005, 2006 Free Software Foundation, Inc. + 2005, 2006, 2007 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/jnlib/stringhelp.c =================================================================== --- trunk/jnlib/stringhelp.c 2007-06-18 20:07:33 UTC (rev 4519) +++ trunk/jnlib/stringhelp.c 2007-06-18 20:15:01 UTC (rev 4520) @@ -1,6 +1,6 @@ /* stringhelp.c - standard string helper functions * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2005, - * 2006 Free Software Foundation, Inc. + * 2006, 2007 Free Software Foundation, Inc. * * This file is part of JNLIB. * @@ -825,3 +825,37 @@ return NULL; } #endif /*HAVE_MEMRCHR*/ + + +/* Percent-escape the string STR by replacing colons with '%3a'. */ +char * +percent_escape (const char *str) +{ + int i = 0; + int j = 0; + char *ptr; + + if (!str) + return NULL; + + while (str[i]) + if (str[i++] == ':') + j++; + ptr = jnlib_xmalloc (i + 2 * j + 1); + i = 0; + while (*str) + { + if (*str == ':') + { + ptr[i++] = '%'; + ptr[i++] = '3'; + ptr[i++] = 'a'; + } + else + ptr[i++] = *str; + str++; + } + ptr[i] = '\0'; + + return ptr; +} Modified: trunk/jnlib/stringhelp.h =================================================================== --- trunk/jnlib/stringhelp.h 2007-06-18 20:07:33 UTC (rev 4519) +++ trunk/jnlib/stringhelp.h 2007-06-18 20:15:01 UTC (rev 4520) @@ -1,6 +1,6 @@ /* stringhelp.h * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2006 Free Software Foundation, Inc. + * 2006, 2007 Free Software Foundation, Inc. * * This file is part of JNLIB. * @@ -117,5 +117,8 @@ #endif #define STR2(v) STR(v) +/* Percent-escape the string STR by replacing colons with '%3a'. */ +char *percent_escape (const char *str); + #endif /*LIBJNLIB_STRINGHELP_H*/ Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2007-06-18 20:07:33 UTC (rev 4519) +++ trunk/scd/ChangeLog 2007-06-18 20:15:01 UTC (rev 4520) @@ -1,3 +1,7 @@ +2007-06-18 Marcus Brinkmann + + * scdaemon.c (main): Percent escape output of --gpgconf-list. + 2007-06-12 Werner Koch * scdaemon.c (main): Replace some calls by init_common_subsystems. @@ -1635,7 +1639,7 @@ the gpg-agent. - Copyright 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright 2002, 2003, 2004, 2005, 2007 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2007-06-18 20:07:33 UTC (rev 4519) +++ trunk/scd/scdaemon.c 2007-06-18 20:15:01 UTC (rev 4520) @@ -1,5 +1,5 @@ /* scdaemon.c - The GnuPG Smartcard Daemon - * Copyright (C) 2001, 2002, 2004, 2005 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2004, 2005, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -530,6 +530,8 @@ if (gpgconf_list) { /* List options and default values in the GPG Conf format. */ + char *filename = NULL; + char *filename_esc; /* The following list is taken from gnupg/tools/gpgconf-comp.c. */ /* Option flags. YOU MUST NOT CHANGE THE NUMBERS OF THE EXISTING @@ -548,11 +550,14 @@ a default, which is described by the value of the ARGDEF field. */ #define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) if (!config_filename) - config_filename = make_filename (opt.homedir, "scdaemon.conf", NULL ); + filename = make_filename (opt.homedir, "scdaemon.conf", NULL ); + filename_esc = percent_escape (filename); printf ("gpgconf-scdaemon.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, config_filename); - + GC_OPT_FLAG_DEFAULT, filename_esc); + xfree (filename_esc); + xfree (filename); + printf ("verbose:%lu:\n" "quiet:%lu:\n" "debug-level:%lu:\"none:\n" Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2007-06-18 20:07:33 UTC (rev 4519) +++ trunk/sm/ChangeLog 2007-06-18 20:15:01 UTC (rev 4520) @@ -1,3 +1,7 @@ +2007-06-18 Marcus Brinkmann + + * gpgsm.c (main): Percent escape output of --gpgconf-list. + 2007-06-14 Werner Koch * call-agent.c (start_agent): Use gnupg_module_name. @@ -1931,7 +1935,7 @@ Copyright 2001, 2002, 2003, 2004, 2005, - 2006 Free Software Foundation, Inc. + 2006, 2007 Free Software Foundation, Inc. This file is free software; as a special exception the author gives unlimited permission to copy and/or distribute it, with or without Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2007-06-18 20:07:33 UTC (rev 4519) +++ trunk/sm/gpgsm.c 2007-06-18 20:15:01 UTC (rev 4520) @@ -1,6 +1,6 @@ /* gpgsm.c - GnuPG for S/MIME * Copyright (C) 2001, 2002, 2003, 2004, 2005, - * 2006 Free Software Foundation, Inc. + * 2006, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -1393,9 +1393,12 @@ a default, which is described by the value of the ARGDEF field. */ #define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) + char *config_filename_esc = percent_escape (opt.config_filename); + printf ("gpgconf-gpgsm.conf:%lu:\"%s\n", - GC_OPT_FLAG_DEFAULT, opt.config_filename); - + GC_OPT_FLAG_DEFAULT, config_filename_esc); + xfree (config_filename_esc); + printf ("verbose:%lu:\n" "quiet:%lu:\n" "debug-level:%lu:\"none:\n" From cvs at cvs.gnupg.org Mon Jun 18 22:08:02 2007 From: cvs at cvs.gnupg.org (svn author marcus) Date: Mon, 18 Jun 2007 22:08:02 +0200 Subject: [svn] GnuPG - r4519 - trunk/tools Message-ID: Author: marcus Date: 2007-06-18 22:07:33 +0200 (Mon, 18 Jun 2007) New Revision: 4519 Modified: trunk/tools/ChangeLog trunk/tools/gpgconf-comp.c Log: 2007-06-18 Marcus Brinkmann * gpgconf-comp.c (retrieve_options_from_file): Close LIST_FILE. (copy_file): In error case, save/restore errno. Close SRC and DST. (gc_component_change_options): Catch error from unlink(). Remove target backup file before rename(). Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2007-06-18 10:33:12 UTC (rev 4518) +++ trunk/tools/ChangeLog 2007-06-18 20:07:33 UTC (rev 4519) @@ -1,3 +1,10 @@ +2007-06-18 Marcus Brinkmann + + * gpgconf-comp.c (retrieve_options_from_file): Close LIST_FILE. + (copy_file): In error case, save/restore errno. Close SRC and DST. + (gc_component_change_options): Catch error from unlink(). Remove + target backup file before rename(). + 2007-06-15 Marcus Brinkmann * gpgconf-comp.c (copy_file) [HAVE_W32_SYSTEM]: New function. Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2007-06-18 10:33:12 UTC (rev 4518) +++ trunk/tools/gpgconf-comp.c 2007-06-18 20:07:33 UTC (rev 4519) @@ -1563,6 +1563,8 @@ list_option->active = 1; list_option->value = list; + if (fclose (list_file) && ferror (list_file)) + gc_error (1, errno, "error closing %s", list_pathname); xfree (line); } @@ -1763,14 +1765,24 @@ if (ferror (src) || ferror (dst) || !feof (src)) { + int saved_errno = errno; + fclose (src); + fclose (dst); unlink (dst_name); + errno = saved_errno; return -1; } + if (fclose (dst) && ferror (dst)) + gc_error (1, errno, "error closing %s", dst_name); + if (fclose (src) && ferror (src)) + gc_error (1, errno, "error closing %s", src_name); + return 0; } #endif /* HAVE_W32_SYSTEM */ + /* Create and verify the new configuration file for the specified backend and component. Returns 0 on success and -1 on error. */ static int @@ -2538,15 +2550,16 @@ { #ifdef HAVE_W32_SYSTEM /* There is no atomic update on W32. */ - unlink (dest_pathname[i]); + err = unlink (dest_pathname[i]); #endif /* HAVE_W32_SYSTEM */ - err = rename (src_pathname[i], dest_pathname[i]); + if (!err) + err = rename (src_pathname[i], dest_pathname[i]); } else { #ifdef HAVE_W32_SYSTEM - /* We skip the unlink if we do not expect the file - to be there. */ + /* We skip the unlink if we expect the file not to + be there. */ err = rename (src_pathname[i], dest_pathname[i]); #else /* HAVE_W32_SYSTEM */ /* This is a bit safer than rename() because we @@ -2554,7 +2567,7 @@ happens to be there, this will fail. */ err = link (src_pathname[i], dest_pathname[i]); if (!err) - unlink (src_pathname[i]); + err = unlink (src_pathname[i]); #endif /* !HAVE_W32_SYSTEM */ } if (err) @@ -2617,6 +2630,11 @@ assert (dest_pathname[backend]); backup_pathname = xasprintf ("%s.gpgconf.bak", dest_pathname[backend]); + +#ifdef HAVE_W32_SYSTEM + /* There is no atomic update on W32. */ + unlink (backup_pathname); +#endif /* HAVE_W32_SYSTEM */ rename (orig_pathname[backend], backup_pathname); } From cvs at cvs.gnupg.org Tue Jun 19 11:11:43 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 19 Jun 2007 11:11:43 +0200 Subject: [svn] GnuPG - r4521 - in trunk: . agent doc g10 jnlib scd sm tools Message-ID: Author: wk Date: 2007-06-19 11:11:11 +0200 (Tue, 19 Jun 2007) New Revision: 4521 Added: trunk/jnlib/t-stringhelp.c trunk/jnlib/t-support.c trunk/jnlib/t-support.h Modified: trunk/AUTHORS trunk/agent/ChangeLog trunk/agent/gpg-agent.c trunk/agent/w32main.c trunk/doc/gpg-agent.texi trunk/g10/gpg.c trunk/jnlib/ChangeLog trunk/jnlib/Makefile.am trunk/jnlib/stringhelp.c trunk/jnlib/stringhelp.h trunk/jnlib/w32-afunix.c trunk/scd/scdaemon.c trunk/sm/gpgsm.c trunk/tools/ChangeLog trunk/tools/gpgconf-comp.c Log: Made percent_escape more general. Added regression tests support to jnlib. W32 changes. Modified: trunk/AUTHORS =================================================================== --- trunk/AUTHORS 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/AUTHORS 2007-06-19 09:11:11 UTC (rev 4521) @@ -128,7 +128,10 @@ The RPM specs file scripts/gnupg.spec has been contributed by several people. +The function build_argv in agent/w32main.c is based on code from +Alexandre Julliard. + Copyright ========= Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/agent/ChangeLog 2007-06-19 09:11:11 UTC (rev 4521) @@ -5,10 +5,14 @@ 2007-06-18 Werner Koch + * w32main.c (build_argv): New. + (WinMain): Use it. + * command.c (cmd_killagent) [W32]: New. (cmd_getinfo): New. * gpg-agent.c (get_agent_ssh_socket_name): New. - + (no_force_standard_socket) New. + (create_server_socket): Use it. * Makefile.am (gpg_agent_res_ldflags): Pass windows option to ld. 2007-06-14 Werner Koch Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/agent/gpg-agent.c 2007-06-19 09:11:11 UTC (rev 4521) @@ -93,6 +93,7 @@ oMinPassphraseLen, oUseStandardSocket, oNoUseStandardSocket, + oNoReuseStandardSocket, oIgnoreCacheForSigning, oAllowMarkTrusted, @@ -130,6 +131,7 @@ { oUseStandardSocket, "use-standard-socket", 0, N_("use a standard location for the socket")}, { oNoUseStandardSocket, "no-use-standard-socket", 0, "@"}, + { oNoReuseStandardSocket, "no-reuse-standard-socket", 0, "@"}, { oPinentryProgram, "pinentry-program", 2 , N_("|PGM|use PGM as the PIN-Entry program") }, @@ -186,6 +188,10 @@ /* Name of the communication socket used for ssh-agent-emulation. */ static char *socket_name_ssh; +/* If set to true and a standard socket is requested, we won't try to + bind to a socket which is already in use. */ +static int no_reuse_standard_socket; + /* Default values for options passed to the pinentry. */ static char *default_display; static char *default_ttyname; @@ -215,7 +221,7 @@ static char *create_socket_name (int use_standard_socket, char *standard_name, char *template); -static int create_server_socket (int is_standard_name, const char *name); +static int create_server_socket (int is_standard_name, char *name); static void create_directories (void); static void agent_init_default_ctrl (ctrl_t ctrl); @@ -621,6 +627,7 @@ case oUseStandardSocket: standard_socket = 1; break; case oNoUseStandardSocket: standard_socket = 0; break; + case oNoReuseStandardSocket: no_reuse_standard_socket = 1; break; case oKeepTTY: opt.keep_tty = 1; break; case oKeepDISPLAY: opt.keep_display = 1; break; @@ -715,7 +722,7 @@ #define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) filename = make_filename (opt.homedir, "gpg-agent.conf", NULL ); - filename_esc = percent_escape (filename); + filename_esc = percent_escape (filename, NULL); printf ("gpgconf-gpg-agent.conf:%lu:\"%s\n", GC_OPT_FLAG_DEFAULT, filename_esc); @@ -1226,10 +1233,10 @@ /* Create a Unix domain socket with NAME. IS_STANDARD_NAME indicates - whether a non-random socket is used. Returns the filedescriptor or + whether a non-random socket is used. Returns the file descriptor or terminates the process in case of an error. */ static int -create_server_socket (int is_standard_name, const char *name) +create_server_socket (int is_standard_name, char *name) { struct sockaddr_un *serv_addr; socklen_t len; @@ -1257,14 +1264,16 @@ #ifdef HAVE_W32_SYSTEM rc = _w32_sock_bind (fd, (struct sockaddr*) serv_addr, len); - if (is_standard_name && rc == -1 ) + if (is_standard_name && rc == -1 && errno == WSAEADDRINUSE + && !no_reuse_standard_socket) { remove (name); - rc = bind (fd, (struct sockaddr*) serv_addr, len); + rc = _w32_sock_bind (fd, (struct sockaddr*) serv_addr, len); } #else rc = bind (fd, (struct sockaddr*) serv_addr, len); - if (is_standard_name && rc == -1 && errno == EADDRINUSE) + if (is_standard_name && rc == -1 && errno == EADDRINUSE + && !no_reuse_standard_socket) { remove (name); rc = bind (fd, (struct sockaddr*) serv_addr, len); @@ -1272,9 +1281,15 @@ #endif if (rc == -1) { + /* We use gpg_strerror here because it allows us to get strings + for some W32 socket error codes. */ log_error (_("error binding socket to `%s': %s\n"), - serv_addr->sun_path, strerror (errno)); + serv_addr->sun_path, + gpg_strerror (gpg_error_from_errno (errno))); + close (fd); + if (is_standard_name && no_reuse_standard_socket) + *name = 0; /* Inhibit removal of the socket by cleanup(). */ agent_exit (2); } Modified: trunk/agent/w32main.c =================================================================== --- trunk/agent/w32main.c 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/agent/w32main.c 2007-06-19 09:11:11 UTC (rev 4521) @@ -1,5 +1,6 @@ /* w32main.c - W32 main entry pint and taskbar support for the GnuPG Agent * Copyright (C) 2007 Free Software Foundation, Inc. + * Copyright 1996, 1998 Alexandre Julliard * * This file is part of GnuPG. * @@ -37,6 +38,136 @@ static HWND glob_hwnd; +/* Build an argv array from the command in CMDLINE. RESERVED is the + number of args to reserve before the first one. This code is based + on Alexandre Julliard's LGPLed wine-0.9.34/dlls/kernel32/process.c + and modified to fit into our framework. The function returns NULL + on error; on success an arry with the argiments is returned. This + array has been allocaqted using a plain malloc (and not the usual + xtrymalloc). */ +static char ** +build_argv (char *cmdline_arg, int reserved) +{ + int argc; + char **argv; + char *cmdline, *s, *arg, *d; + int in_quotes, bs_count; + + cmdline = malloc (strlen (cmdline_arg) + 1); + if (!cmdline) + return NULL; + strcpy (cmdline, cmdline_arg); + + /* First determine the required size of the array. */ + argc = reserved + 1; + bs_count = 0; + in_quotes = 0; + s = cmdline; + for (;;) + { + if ( !*s || ((*s==' ' || *s=='\t') && !in_quotes)) /* A space. */ + { + argc++; + /* Skip the remaining spaces. */ + while (*s==' ' || *s=='\t') + s++; + if (!*s) + break; + bs_count = 0; + } + else if (*s=='\\') + { + bs_count++; + s++; + } + else if ( (*s == '\"') && !(bs_count & 1)) + { + /* Unescaped '\"' */ + in_quotes = !in_quotes; + bs_count=0; + s++; + } + else /* A regular character. */ + { + bs_count = 0; + s++; + } + } + + argv = malloc (argc * sizeof *argv); + if (!argv) + { + free (cmdline); + return NULL; + } + + /* Now actually parse the command line. */ + argc = reserved; + bs_count = 0; + in_quotes=0; + arg = d = s = cmdline; + while (*s) + { + if ((*s==' ' || *s=='\t') && !in_quotes) + { + /* Close the argument and copy it. */ + *d = 0; + argv[argc++] = arg; + + /* Skip the remaining spaces. */ + do + s++; + while (*s==' ' || *s=='\t'); + + /* Start with a new argument */ + arg = d = s; + bs_count = 0; + } + else if (*s=='\\') + { + *d++ = *s++; + bs_count++; + } + else if (*s=='\"') + { + if ( !(bs_count & 1) ) + { + /* Preceded by an even number of backslashes, this is + half that number of backslashes, plus a '\"' which we + discard. */ + d -= bs_count/2; + s++; + in_quotes = !in_quotes; + } + else + { + /* Preceded by an odd number of backslashes, this is + half that number of backslashes followed by a '\"'. */ + d = d - bs_count/2 - 1; + *d++ ='\"'; + s++; + } + bs_count=0; + } + else /* A regular character. */ + { + *d++ = *s++; + bs_count = 0; + } + } + + if (*arg) + { + *d = 0; + argv[argc++] = arg; + } + argv[argc] = NULL; + + return argv; +} + + + /* Our window message processing function. */ static LRESULT CALLBACK wndw_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) @@ -155,24 +286,23 @@ /* The main entry point for the Windows version. We save away all GUI - related stuff, parse the commandline and finally call the real + related stuff, parse the command line and finally call the real main. */ int WINAPI WinMain (HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int showcmd) { - /* Fixme: We need a parser for the command line. Should be - available in some CRT code - need to see whether we can find a - GNU version. For nopw we call gpg-agent with a couple of fixed arguments - */ - char *argv[] = { "gpg-agent.exe", "--daemon", "-v", "--debug-all", NULL }; + char **argv; + int argc; + /* We use the GetCommandLine function because that also includes the + program name in contrast to the CMDLINE arg. */ + argv = build_argv (GetCommandLineA (), 0); + if (!argv) + return 2; /* Can't do much about a malloc failure. */ + for (argc=0; argv[argc]; argc++) + ; glob_hinst = hinst; - return w32_main (DIM(argv)-1, argv); + return w32_main (argc, argv); } - - - - - Modified: trunk/doc/gpg-agent.texi =================================================================== --- trunk/doc/gpg-agent.texi 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/doc/gpg-agent.texi 2007-06-19 09:11:11 UTC (rev 4521) @@ -369,20 +369,22 @@ @item --use-standard-socket @itemx --no-use-standard-socket + at itemx --no-reuse-standard-socket @opindex use-standard-socket @opindex no-use-standard-socket + at opindex no-reuse-standard-socket By enabling this option @command{gpg-agent} will listen on the socket named @file{S.gpg-agent}, located in the home directory, and not create a random socket below a temporary directory. Tools connecting to @command{gpg-agent} should first try to connect to the socket given in environment variable @var{GPG_AGENT_INFO} and the fall back to this socket. This option may not be used if the home directory is mounted as -a remote file system. +a remote file system. If @option{--no-reuse-standard-socket} is used, + at command{gpg-agent} will not try to reuse a socket which is already in +use. Note, that @option{--use-standard-socket} is the default on +Windows systems. - at noindent -Note, that as of now, W32 systems default to this option. - @item --display @var{string} @itemx --ttyname @var{string} @itemx --ttytype @var{string} Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/g10/gpg.c 2007-06-19 09:11:11 UTC (rev 4521) @@ -1456,7 +1456,7 @@ static void gpgconf_list (const char *configfile) { - char *configfile_esc = percent_escape (configfile); + char *configfile_esc = percent_escape (configfile, NULL); /* The following definitions are taken from gnupg/tools/gpgconf-comp.c. */ #define GC_OPT_FLAG_NONE 0UL Modified: trunk/jnlib/ChangeLog =================================================================== --- trunk/jnlib/ChangeLog 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/jnlib/ChangeLog 2007-06-19 09:11:11 UTC (rev 4521) @@ -1,3 +1,17 @@ +2007-06-19 Werner Koch + + * Makefile.am: Add support for regression tests. + * t-support.h, t-support.c: New. + * t-stringhelp.c: New. + + * stringhelp.c (percent_escape): Add arg EXTRA to make it a more + general function. Changed all callers. + +2007-06-18 Werner Koch + + * w32-afunix.c (_w32_sock_bind): Changed to properly detect an + already used socket. + 2007-06-18 Marcus Brinkmann * stringhelp.h (percent_escape): New prototype. Modified: trunk/jnlib/Makefile.am =================================================================== --- trunk/jnlib/Makefile.am 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/jnlib/Makefile.am 2007-06-19 09:11:11 UTC (rev 4521) @@ -23,6 +23,8 @@ ## Process this file with automake to produce Makefile.in EXTRA_DIST = README +noinst_PROGRAMS = $(module_tests) +TESTS = $(module_tests) AM_CPPFLAGS = -I$(top_srcdir)/intl @@ -51,3 +53,20 @@ # For GnuPG we don't need the xmalloc stuff. # xmalloc.c xmalloc.h + +# +# Module tests. +# +# These tests should only be used at the canonical location of jnlib +# which is the GnuPG package. The reason for this is that t-support.c +# defines replacements for the actual used memory allocation functions +# so that there is no dependency on libgcrypt. +# +module_tests = t-stringhelp + +t_jnlib_src = t-support.c t-support.h +t_jnlib_ldadd = libjnlib.a $(LIBINTL) $(LIBICONV) + +t_stringhelp_SOURCES = t-stringhelp.c $(t_jnlib_src) +t_stringhelp_LDADD = $(t_jnlib_ldadd) + Modified: trunk/jnlib/stringhelp.c =================================================================== --- trunk/jnlib/stringhelp.c 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/jnlib/stringhelp.c 2007-06-19 09:11:11 UTC (rev 4521) @@ -34,6 +34,8 @@ #include "stringhelp.h" +#define tohex_lower(n) ((n) < 10 ? ((n) + '0') : (((n) - 10) + 'a')) + /* * Look for the substring SUB in buffer and return a pointer to that * substring in BUFFER or NULL if not found. @@ -827,19 +829,19 @@ #endif /*HAVE_MEMRCHR*/ -/* Percent-escape the string STR by replacing colons with '%3a'. */ +/* Percent-escape the string STR by replacing colons with '%3a'. If + EXTRA is not NULL all characters in it are also escaped. */ char * -percent_escape (const char *str) +percent_escape (const char *str, const char *extra) { - int i = 0; - int j = 0; + int i, j; char *ptr; if (!str) return NULL; - while (str[i]) - if (str[i++] == ':') + for (i=j=0; str[i]; i++) + if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i]))) j++; ptr = jnlib_xmalloc (i + 2 * j + 1); i = 0; @@ -851,6 +853,18 @@ ptr[i++] = '3'; ptr[i++] = 'a'; } + else if (*str == '%') + { + ptr[i++] = '%'; + ptr[i++] = '2'; + ptr[i++] = '5'; + } + else if (extra && strchr (extra, *str)) + { + ptr[i++] = '%'; + ptr[i++] = tohex_lower ((*str>>4)&15); + ptr[i++] = tohex_lower (*str&15); + } else ptr[i++] = *str; str++; Modified: trunk/jnlib/stringhelp.h =================================================================== --- trunk/jnlib/stringhelp.h 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/jnlib/stringhelp.h 2007-06-19 09:11:11 UTC (rev 4521) @@ -117,8 +117,9 @@ #endif #define STR2(v) STR(v) -/* Percent-escape the string STR by replacing colons with '%3a'. */ -char *percent_escape (const char *str); +/* Percent-escape the string STR by replacing colons with '%3a'. If + EXTRA is not NULL, also replace all characters given in EXTRA. */ +char *percent_escape (const char *str, const char *extra); #endif /*LIBJNLIB_STRINGHELP_H*/ Added: trunk/jnlib/t-stringhelp.c =================================================================== --- trunk/jnlib/t-stringhelp.c 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/jnlib/t-stringhelp.c 2007-06-19 09:11:11 UTC (rev 4521) @@ -0,0 +1,94 @@ +/* t-stringhelp.c - Regression tests for stringhelp.c + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * This file is part of JNLIB. + * + * JNLIB 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. + * + * JNLIB 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include +#include +#include +#include + +#include "stringhelp.h" + +#include "t-support.h" + + + +static void +test_percent_escape (void) +{ + char *result; + static struct { + const char *extra; + const char *value; + const char *expected; + } tests[] = + { + { NULL, "", "" }, + { NULL, "%", "%25" }, + { NULL, "%%", "%25%25" }, + { NULL, " %", " %25" }, + { NULL, ":", "%3a" }, + { NULL, " :", " %3a" }, + { NULL, ": ", "%3a " }, + { NULL, " : ", " %3a " }, + { NULL, "::", "%3a%3a" }, + { NULL, ": :", "%3a %3a" }, + { NULL, "%:", "%25%3a" }, + { NULL, ":%", "%3a%25" }, + { "\\\n:", ":%", "%3a%25" }, + { "\\\n:", "\\:%", "%5c%3a%25" }, + { "\\\n:", "\n:%", "%0a%3a%25" }, + { "\\\n:", "\xff:%", "\xff%3a%25" }, + { "\\\n:", "\xfe:%", "\xfe%3a%25" }, + { "\\\n:", "\x01:%", "\x01%3a%25" }, + { "\x01", "\x01:%", "%01%3a%25" }, + { "\xfe", "\xfe:%", "%fe%3a%25" }, + { "\xfe", "\xff:%", "\xff%3a%25" }, + + { NULL, NULL, NULL } + }; + int testno; + + result = percent_escape (NULL, NULL); + if (result) + fail (0); + for (testno=0; tests[testno].value; testno++) + { + result = percent_escape (tests[testno].value, tests[testno].extra); + if (!result) + fail (testno); + if (strcmp (result, tests[testno].expected)) + fail (testno); + xfree (result); + } + +} + + + + +int +main (int argc, char **argv) +{ + test_percent_escape (); + + return 0; +} + Added: trunk/jnlib/t-support.c =================================================================== --- trunk/jnlib/t-support.c 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/jnlib/t-support.c 2007-06-19 09:11:11 UTC (rev 4521) @@ -0,0 +1,111 @@ +/* t-support.c - helper functions for the regression tests. + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * This file is part of JNLIB. + * + * JNLIB 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. + * + * JNLIB 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include "t-support.h" + +/* Replacements for the malloc functions as used here. */ + +static void +out_of_memory (void) +{ + fprintf (stderr,"error: out of core in regression tests: %s\n", + strerror (errno)); + exit (2); +} + + +void * +gcry_malloc (size_t n) +{ + return malloc (n); +} + +void * +gcry_xmalloc (size_t n) +{ + void *p = malloc (n); + if (!p) + out_of_memory (); + return p; +} + +char * +gcry_strdup (const char *string) +{ + return malloc (strlen (string)+1); +} + + +void * +gcry_realloc (void *a, size_t n) +{ + return realloc (a, n); +} + +void * +gcry_xrealloc (void *a, size_t n) +{ + void *p = realloc (a, n); + if (!p) + out_of_memory (); + return p; +} + + + +void * +gcry_calloc (size_t n, size_t m) +{ + return calloc (n, m); +} + +void * +gcry_xcalloc (size_t n, size_t m) +{ + void *p = calloc (n, m); + if (!p) + out_of_memory (); + return p; +} + + +char * +gcry_xstrdup (const char *string) +{ + void *p = malloc (strlen (string)+1); + if (!p) + out_of_memory (); + strcpy (p, string); + return p; +} + +void +gcry_free (void *a) +{ + if (a) + free (a); +} Added: trunk/jnlib/t-support.h =================================================================== --- trunk/jnlib/t-support.h 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/jnlib/t-support.h 2007-06-19 09:11:11 UTC (rev 4521) @@ -0,0 +1,52 @@ +/* t-support.h - Helper for the regression tests + * Copyright (C) 2007 Free Software Foundation, Inc. + * + * This file is part of JNLIB. + * + * JNLIB 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. + * + * JNLIB 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., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +#ifndef LIBJNLIB_T_SUPPORT_H +#define LIBJNLIB_T_SUPPORT_H 1 + +#ifdef GCRYPT_VERSION +#error The regression tests should not include with gcrypt.h +#endif + +/* Repalcement prototypes. */ +void *gcry_xmalloc (size_t n); +void *gcry_xcalloc (size_t n, size_t m); +void *gcry_xrealloc (void *a, size_t n); +char *gcry_xstrdup (const char * a); +void gcry_free (void *a); + +/* Map the used xmalloc functions to those implemented by t-support.c */ +#define xmalloc(a) gcry_xmalloc ( (a) ) +#define xcalloc(a,b) gcry_xcalloc ( (a), (b) ) +#define xrealloc(a,n) gcry_xrealloc ( (a), (n) ) +#define xstrdup(a) gcry_xstrdup ( (a) ) +#define xfree(a) gcry_free ( (a) ) + + +/* Macros to print the result of a test. */ +#define pass() do { ; } while(0) +#define fail(a) do { fprintf (stderr, "%s:%d: test %d failed\n",\ + __FILE__,__LINE__, (a)); \ + exit (1); \ + } while(0) + + +#endif /*LIBJNLIB_T_SUPPORT_H*/ Modified: trunk/jnlib/w32-afunix.c =================================================================== --- trunk/jnlib/w32-afunix.c 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/jnlib/w32-afunix.c 2007-06-19 09:11:11 UTC (rev 4521) @@ -22,11 +22,19 @@ #ifdef _WIN32 #include #include +#include +#include #include #include #include "w32-afunix.h" +#ifndef S_IRGRP +# define S_IRGRP 0 +# define S_IWGRP 0 +#endif + + int _w32_close (int fd) { @@ -81,34 +89,56 @@ int -_w32_sock_bind (int sockfd, struct sockaddr * addr, int addrlen) +_w32_sock_bind (int sockfd, struct sockaddr *addr, int addrlen) { if (addr->sa_family == AF_LOCAL || addr->sa_family == AF_UNIX) { struct sockaddr_in myaddr; - struct sockaddr_un * unaddr; - FILE * fp; + struct sockaddr_un *unaddr; + int filefd; + FILE *fp; int len = sizeof myaddr; int rc; + unaddr = (struct sockaddr_un *)addr; + myaddr.sin_port = 0; myaddr.sin_family = AF_INET; myaddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK); + filefd = open (unaddr->sun_path, + (O_WRONLY|O_CREAT|O_EXCL|O_BINARY), + (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)); + if (filefd == -1) + { + if (errno == EEXIST) + errno = WSAEADDRINUSE; + return -1; + } + fp = fdopen (filefd, "wb"); + if (!fp) + { + int save_e = errno; + close (filefd); + errno = save_e; + return -1; + } + rc = bind (sockfd, (struct sockaddr *)&myaddr, len); + if (!rc) + rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len); if (rc) - return rc; - rc = getsockname (sockfd, (struct sockaddr *)&myaddr, &len); - if (rc) - return rc; - unaddr = (struct sockaddr_un *)addr; - fp = fopen (unaddr->sun_path, "wb"); - if (!fp) - return -1; + { + int save_e = errno; + fclose (fp); + remove (unaddr->sun_path); + errno = save_e; + return rc; + } fprintf (fp, "%d", myaddr.sin_port); fclose (fp); - /* we need this later. */ + /* The caller expects these values. */ unaddr->sun_family = myaddr.sin_family; unaddr->sun_port = myaddr.sin_port; unaddr->sun_addr.s_addr = myaddr.sin_addr.s_addr; Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/scd/scdaemon.c 2007-06-19 09:11:11 UTC (rev 4521) @@ -551,7 +551,7 @@ #define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) if (!config_filename) filename = make_filename (opt.homedir, "scdaemon.conf", NULL ); - filename_esc = percent_escape (filename); + filename_esc = percent_escape (filename, NULL); printf ("gpgconf-scdaemon.conf:%lu:\"%s\n", GC_OPT_FLAG_DEFAULT, filename_esc); Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/sm/gpgsm.c 2007-06-19 09:11:11 UTC (rev 4521) @@ -1393,7 +1393,7 @@ a default, which is described by the value of the ARGDEF field. */ #define GC_OPT_FLAG_NO_ARG_DESC (1UL << 6) - char *config_filename_esc = percent_escape (opt.config_filename); + char *config_filename_esc = percent_escape (opt.config_filename, NULL); printf ("gpgconf-gpgsm.conf:%lu:\"%s\n", GC_OPT_FLAG_DEFAULT, config_filename_esc); Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/tools/ChangeLog 2007-06-19 09:11:11 UTC (rev 4521) @@ -1,3 +1,8 @@ +2007-06-19 Werner Koch + + * gpgconf-comp.c (percent_escape): Rename to my_percent_escape. + Changed all callers. + 2007-06-18 Marcus Brinkmann * gpgconf-comp.c (retrieve_options_from_file): Close LIST_FILE. Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2007-06-18 20:15:01 UTC (rev 4520) +++ trunk/tools/gpgconf-comp.c 2007-06-19 09:11:11 UTC (rev 4521) @@ -984,7 +984,7 @@ /* Percent-Escape special characters. The string is valid until the next invocation of the function. */ static char * -percent_escape (const char *src) +my_percent_escape (const char *src) { static char *esc_str; static int esc_str_len; @@ -1083,7 +1083,8 @@ { const char *desc = gc_component[idx].desc; desc = my_dgettext (gc_component[idx].desc_domain, desc); - fprintf (out, "%s:%s\n", gc_component[idx].name, percent_escape (desc)); + fprintf (out, "%s:%s\n", + gc_component[idx].name, my_percent_escape (desc)); } } @@ -1174,7 +1175,7 @@ fprintf (out, " %s", gc_level[option->level].name); /* The description field. */ - fprintf (out, ":%s", desc ? percent_escape (desc) : ""); + fprintf (out, ":%s", desc ? my_percent_escape (desc) : ""); /* The type field. */ fprintf (out, ":%u", option->arg_type); @@ -1188,7 +1189,7 @@ gc_arg_type[gc_arg_type[option->arg_type].fallback].name); /* The argument name field. */ - fprintf (out, ":%s", arg_name ? percent_escape (arg_name) : ""); + fprintf (out, ":%s", arg_name ? my_percent_escape (arg_name) : ""); if (arg_name) xfree (arg_name); @@ -1458,7 +1459,7 @@ } else if (gc_arg_type[option->arg_type].fallback == GC_ARG_TYPE_STRING) - opt_value = xasprintf ("\"%s", percent_escape (value)); + opt_value = xasprintf ("\"%s", my_percent_escape (value)); else { /* FIXME: Verify that the number is sane. */ @@ -1549,12 +1550,12 @@ really append. */ if (list) { - new_list = xasprintf ("%s,\"%s", list, percent_escape (start)); + new_list = xasprintf ("%s,\"%s", list, my_percent_escape (start)); xfree (list); list = new_list; } else - list = xasprintf ("\"%s", percent_escape (start)); + list = xasprintf ("\"%s", my_percent_escape (start)); } if (length < 0 || ferror (list_file)) gc_error (1, errno, "can not read list file %s", list_pathname); From cvs at cvs.gnupg.org Wed Jun 20 13:17:13 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 20 Jun 2007 13:17:13 +0200 Subject: [svn] GnuPG - r4522 - in trunk: agent common doc g10 scd sm Message-ID: Author: wk Date: 2007-06-20 13:16:42 +0200 (Wed, 20 Jun 2007) New Revision: 4522 Modified: trunk/agent/gpg-agent.c trunk/common/ChangeLog trunk/common/exechelp.c trunk/common/sysutils.c trunk/common/sysutils.h trunk/doc/ChangeLog trunk/doc/glossary.texi trunk/doc/gpg-agent.texi trunk/g10/ChangeLog trunk/g10/misc.c trunk/g10/sign.c trunk/scd/scdaemon.c trunk/sm/ChangeLog trunk/sm/call-agent.c trunk/sm/gpgsm.c Log: [w32] gpg-agent is now started automagically by gpgsm. Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/agent/gpg-agent.c 2007-06-20 11:16:42 UTC (rev 4522) @@ -691,7 +691,7 @@ { log_debug ("waiting for debugger - my pid is %u .....\n", (unsigned int)getpid()); - sleep (debug_wait); + gnupg_sleep (debug_wait); log_debug ("... okay\n"); } Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/common/ChangeLog 2007-06-20 11:16:42 UTC (rev 4522) @@ -1,3 +1,14 @@ +2007-06-20 Werner Koch + + * sysutils.c (gnupg_sleep): New. + * sysutils.h [W32]: Remove _sleep wrapper. Changed all callers to + use gnupg_sleep. + + * exechelp.c (build_w32_commandline_copy): New. + (build_w32_commandline): Factored some code out to new function + and correctly process a PGMNAME with spaces. + (gnupg_spawn_process_detached) [W32]: Implement. + 2007-06-14 Werner Koch * simple-pwquery.h (MAP_SPWQ_ERROR_IMPL): New. Modified: trunk/common/exechelp.c =================================================================== --- trunk/common/exechelp.c 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/common/exechelp.c 2007-06-20 11:16:42 UTC (rev 4522) @@ -80,17 +80,51 @@ #ifdef HAVE_W32_SYSTEM +/* Helper function to build_w32_commandline. */ +static char * +build_w32_commandline_copy (char *buffer, const char *string) +{ + char *p = buffer; + const char *s; + + if (!*string) /* Empty string. */ + p = stpcpy (p, "\"\""); + else if (strpbrk (string, " \t\n\v\f\"")) + { + /* Need top do some kind of quoting. */ + p = stpcpy (p, "\""); + for (s=string; *s; s++) + { + *p++ = *s; + if (*s == '\"') + *p++ = *s; + } + *p++ = '\"'; + *p = 0; + } + else + p = stpcpy (p, string); + + return p; +} + /* Build a command line for use with W32's CreateProcess. On success CMDLINE gets the address of a newly allocated string. */ static gpg_error_t -build_w32_commandline (const char *pgmname, const char **argv, char **cmdline) +build_w32_commandline (const char *pgmname, const char * const *argv, + char **cmdline) { int i, n; const char *s; char *buf, *p; *cmdline = NULL; - n = strlen (pgmname); + n = 0; + s = pgmname; + n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */ + for (; *s; s++) + if (*s == '\"') + n++; /* Need to double inner quotes. */ for (i=0; (s=argv[i]); i++) { n += strlen (s) + 1 + 2; /* (1 space, 2 quoting */ @@ -104,26 +138,11 @@ if (!buf) return gpg_error_from_syserror (); - /* fixme: PGMNAME may not contain spaces etc. */ - p = stpcpy (p, pgmname); + p = build_w32_commandline_copy (p, pgmname); for (i=0; argv[i]; i++) { - if (!*argv[i]) /* Empty string. */ - p = stpcpy (p, " \"\""); - else if (strpbrk (argv[i], " \t\n\v\f\"")) - { - p = stpcpy (p, " \""); - for (s=argv[i]; *s; s++) - { - *p++ = *s; - if (*s == '\"') - *p++ = *s; - } - *p++ = '\"'; - *p = 0; - } - else - p = stpcpy (stpcpy (p, " "), argv[i]); + *p++ = ' '; + p = build_w32_commandline_copy (p, argv[i]); } *cmdline= buf; @@ -330,7 +349,7 @@ pi.hProcess, pi.hThread, (int) pi.dwProcessId, (int) pi.dwThreadId); - /* Process ha been created suspended; resume it now. */ + /* Process has been created suspended; resume it now. */ ResumeThread (pi.hThread); CloseHandle (pi.hThread); @@ -525,7 +544,79 @@ const char *envp[] ) { #ifdef HAVE_W32_SYSTEM - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); + gpg_error_t err; + SECURITY_ATTRIBUTES sec_attr; + PROCESS_INFORMATION pi = + { + NULL, /* Returns process handle. */ + 0, /* Returns primary thread handle. */ + 0, /* Returns pid. */ + 0 /* Returns tid. */ + }; + STARTUPINFO si; + int cr_flags; + char *cmdline; + + + /* FIXME: We don't make use of ENVP yet. It is currently only used + to pass the GPG_AGENT_INFO variable to gpg-agent. As the default + on windows is to use a standard socket, this does not really + matter. */ + + + if (access (pgmname, X_OK)) + return gpg_error_from_syserror (); + + /* Prepare security attributes. */ + memset (&sec_attr, 0, sizeof sec_attr ); + sec_attr.nLength = sizeof sec_attr; + sec_attr.bInheritHandle = FALSE; + + /* Build the command line. */ + err = build_w32_commandline (pgmname, argv, &cmdline); + if (err) + return err; + + /* Start the process. */ + memset (&si, 0, sizeof si); + si.cb = sizeof (si); + si.dwFlags = STARTF_USESHOWWINDOW; + si.wShowWindow = DEBUG_W32_SPAWN? SW_SHOW : SW_MINIMIZE; + + cr_flags = (CREATE_DEFAULT_ERROR_MODE + | GetPriorityClass (GetCurrentProcess ()) + | CREATE_NEW_PROCESS_GROUP + | DETACHED_PROCESS); + log_debug ("CreateProcess(detached), path=`%s' cmdline=`%s'\n", + pgmname, cmdline); + if (!CreateProcess (pgmname, /* Program to start. */ + cmdline, /* Command line arguments. */ + &sec_attr, /* Process security attributes. */ + &sec_attr, /* Thread security attributes. */ + FALSE, /* Inherit handles. */ + cr_flags, /* Creation flags. */ + NULL, /* Environment. */ + NULL, /* Use current drive/directory. */ + &si, /* Startup information. */ + &pi /* Returns process information. */ + )) + { + log_error ("CreateProcess(detached) failed: %s\n", w32_strerror (-1)); + xfree (cmdline); + return gpg_error (GPG_ERR_GENERAL); + } + xfree (cmdline); + cmdline = NULL; + + log_debug ("CreateProcess(detached) ready: hProcess=%p hThread=%p" + " dwProcessID=%d dwThreadId=%d\n", + pi.hProcess, pi.hThread, + (int) pi.dwProcessId, (int) pi.dwThreadId); + + CloseHandle (pi.hThread); + + return 0; + #else pid_t pid; int i; Modified: trunk/common/sysutils.c =================================================================== --- trunk/common/sysutils.c 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/common/sysutils.c 2007-06-20 11:16:42 UTC (rev 4522) @@ -20,23 +20,36 @@ */ #include + +#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */ +# undef HAVE_PTH +# undef USE_GNU_PTH +#endif + #include #include #include #include #include #ifdef HAVE_STAT -#include +# include #endif #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 - #include - #include +# include +# include #endif #ifdef HAVE_SETRLIMIT - #include - #include - #include +# include +# include +# include #endif +#ifdef HAVE_W32_SYSTEM +# include +#endif +#ifdef HAVE_PTH +# include +#endif + #include "util.h" #include "i18n.h" @@ -229,3 +242,33 @@ return 0; } #endif + + +/* Wrapper around the usual sleep fucntion. This one won't wake up + before the sleep time has really elapsed. When build with Pth it + merely calls pth_sleep and thus suspends only the current + thread. */ +void +gnupg_sleep (unsigned int seconds) +{ +#ifdef HAVE_PTH + /* With Pth we force a regular sleep for seconds == 0 so that also + the process will give up its timeslot. */ + if (!seconds) + { +# ifdef HAVE_W32_SYSTEM + Sleep (0); +# else + sleep (0); +# endif + } + pth_sleep (seconds); +#else + /* Fixme: make sure that a sleep won't wake up to early. */ +# ifdef HAVE_W32_SYSTEM + Sleep (seconds*1000); +# else + sleep (seconds); +# endif +#endif +} Modified: trunk/common/sysutils.h =================================================================== --- trunk/common/sysutils.h 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/common/sysutils.h 2007-06-20 11:16:42 UTC (rev 4522) @@ -27,11 +27,9 @@ int enable_core_dumps (void); const unsigned char *get_session_marker (size_t *rlen); int check_permissions (const char *path,int extension,int checkonly); +void gnupg_sleep (unsigned int seconds); #ifdef HAVE_W32_SYSTEM -/* Windows declares sleep as obsolete, but provides a definition for - _sleep but non for the still existing sleep. */ -#define sleep(a) _sleep ((a)) #include "../jnlib/w32help.h" Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/doc/ChangeLog 2007-06-20 11:16:42 UTC (rev 4522) @@ -1,3 +1,7 @@ +2007-06-19 Werner Koch + + * glossary.texi (Glossary): Describe PSE. + 2007-06-18 Werner Koch * gpg-agent.texi (Agent GETINFO): New. Modified: trunk/doc/glossary.texi =================================================================== --- trunk/doc/glossary.texi 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/doc/glossary.texi 2007-06-20 11:16:42 UTC (rev 4522) @@ -26,5 +26,10 @@ The @emph{Online Certificate Status Protocol} is used as an alternative to a @acronym{CRL}. It is described in @code{RFC 2560}. + at item PSE + The @emph{Personal Security Environment} describes a database to +store private keys. This is either a smartcard or a collection of files +on a disk; the latter is often called a Soft-PSE. + @end table Modified: trunk/doc/gpg-agent.texi =================================================================== --- trunk/doc/gpg-agent.texi 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/doc/gpg-agent.texi 2007-06-20 11:16:42 UTC (rev 4522) @@ -832,7 +832,7 @@ @subsection Generating a Key This is used to create a new keypair and store the secret key inside the -active PSE -w which is in most cases a Soft-PSE. An not yet defined +active PSE --- which is in most cases a Soft-PSE. An not yet defined option allows to choose the storage location. To get the secret key out of the PSE, a special export tool has to be used. Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/g10/ChangeLog 2007-06-20 11:16:42 UTC (rev 4522) @@ -1,3 +1,11 @@ +2007-06-20 Werner Koch + + * misc.c (setsysinfo, trap_unaligned): Remove. It is also in + common/sysutils.c. + (disable_core_dumps, get_session_marker): + + * sign.c (sleep): Remove sleep wrapper. + 2007-06-18 Marcus Brinkmann * gpg.c (gpgconf_list): Percent escape output of --gpgconf-list. Modified: trunk/g10/misc.c =================================================================== --- trunk/g10/misc.c 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/g10/misc.c 2007-06-20 11:16:42 UTC (rev 4522) @@ -94,52 +94,7 @@ -#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2 -static int -setsysinfo(unsigned long op, void *buffer, unsigned long size, - int *start, void *arg, unsigned long flag) -{ - return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag); -} -void -trap_unaligned(void) -{ - unsigned int buf[2]; - - buf[0] = SSIN_UACPROC; - buf[1] = UAC_SIGBUS | UAC_NOPRINT; - setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0); -} -#else -void -trap_unaligned(void) -{ /* dummy */ -} -#endif - - -int -disable_core_dumps() -{ -#ifdef HAVE_DOSISH_SYSTEM - return 0; -#else -#ifdef HAVE_SETRLIMIT - struct rlimit limit; - - limit.rlim_cur = 0; - limit.rlim_max = 0; - if( !setrlimit( RLIMIT_CORE, &limit ) ) - return 0; - if( errno != EINVAL && errno != ENOSYS ) - log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) ); -#endif - return 1; -#endif -} - - /* For the sake of SELinux we want to restrict access through gpg to certain files we keep under our own control. This function registers such a file and is_secured_file may then be used to @@ -371,34 +326,6 @@ gcry_md_algo_name (algo)); } -/* Return a string which is used as a kind of process ID */ -const byte * -get_session_marker( size_t *rlen ) -{ - static byte marker[SIZEOF_UNSIGNED_LONG*2]; - static int initialized; - - if ( !initialized ) - { - volatile ulong aa, bb; /* We really want the uninitialized value. */ - ulong a, b; - - initialized = 1; - /* Although this marker is guessable it is not easy to use this - * for a faked control packet because an attacker does not have - * enough control about the time the verification takes place. - * Of course, we could add just more random but than we need the - * random generator even for verification tasks - which does not - * make sense. */ - a = aa ^ (ulong)getpid(); - b = bb ^ (ulong)time(NULL); - memcpy ( marker, &a, SIZEOF_UNSIGNED_LONG ); - memcpy ( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG ); - } - *rlen = sizeof(marker); - return marker; -} - /**************** * Wrapper around the libgcrypt function with additonal checks on * the OpenPGP contraints for the algo ID. Modified: trunk/g10/sign.c =================================================================== --- trunk/g10/sign.c 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/g10/sign.c 2007-06-20 11:16:42 UTC (rev 4522) @@ -26,7 +26,6 @@ #include #include #include -#include /* need sleep() */ #include "gpg.h" #include "options.h" @@ -47,8 +46,6 @@ #ifdef HAVE_DOSISH_SYSTEM #define LF "\r\n" -void __stdcall Sleep(ulong); -#define sleep(a) Sleep((a)*1000) #else #define LF "\n" #endif @@ -1563,7 +1560,7 @@ one. */ while(sig->timestamp<=orig_sig->timestamp) { - sleep(1); + gnupg_sleep (1); sig->timestamp=make_timestamp(); } Modified: trunk/scd/scdaemon.c =================================================================== --- trunk/scd/scdaemon.c 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/scd/scdaemon.c 2007-06-20 11:16:42 UTC (rev 4522) @@ -519,7 +519,7 @@ { log_debug ("waiting for debugger - my pid is %u .....\n", (unsigned int)getpid()); - sleep (debug_wait); + gnupg_sleep (debug_wait); log_debug ("... okay\n"); } Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/sm/ChangeLog 2007-06-20 11:16:42 UTC (rev 4522) @@ -1,3 +1,7 @@ +2007-06-20 Werner Koch + + * call-agent.c (start_agent) [W32]: Start the agent on the fly. + 2007-06-18 Marcus Brinkmann * gpgsm.c (main): Percent escape output of --gpgconf-list. Modified: trunk/sm/call-agent.c =================================================================== --- trunk/sm/call-agent.c 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/sm/call-agent.c 2007-06-20 11:16:42 UTC (rev 4522) @@ -37,7 +37,8 @@ #include "i18n.h" #include "asshelp.h" #include "keydb.h" /* fixme: Move this to import.c */ -#include "../common/membuf.h" +#include "membuf.h" +#include "exechelp.h" static assuan_context_t agent_ctx = NULL; @@ -83,21 +84,12 @@ infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO"); if (!infostr || !*infostr) { - const char *pgmname; - const char *argv[3]; char *sockname; - int no_close_list[3]; - int i; /* First check whether we can connect at the standard socket. */ sockname = make_filename (opt.homedir, "S.gpg-agent", NULL); rc = assuan_socket_connect (&ctx, sockname, 0); - xfree (sockname); -#ifdef HAVE_W32_SYSTEM -# warning Print a warning if connecting is not possible - /* and offer to fire up the agent. */ -#endif if (rc) { @@ -112,30 +104,71 @@ gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); log_error ("error flushing pending output: %s\n", strerror (errno)); + xfree (sockname); return tmperr; } if (!opt.agent_program || !*opt.agent_program) opt.agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); - if ( !(pgmname = strrchr (opt.agent_program, '/'))) - pgmname = opt.agent_program; - else - pgmname++; - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; +#ifdef HAVE_W32_SYSTEM + { + /* Under Windows we start the server in daemon mode. This + is because the default is to use the standard socket + and thus there is no need for the GPG_AGENT_INFO + envvar. This is possible as we don't have a real unix + domain socket but use a plain file and thus there is no + need to care about non-local file systems. */ + const char *argv[3]; - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = log_get_fd (); - no_close_list[i++] = fileno (stderr); - no_close_list[i] = -1; + /* The --no-reuse-standard option makes sure that we don't + start a second instance of a agent in case another + process has started one in the meantime. */ + argv[0] = "--daemon"; + argv[1] = "--no-reuse-standard-socket"; + argv[2] = NULL; - /* Connect to the agent and perform initial handshaking. */ - rc = assuan_pipe_connect (&ctx, opt.agent_program, argv, - no_close_list); + rc = gnupg_spawn_process_detached (opt.agent_program, argv, NULL); + if (rc) + log_debug ("failed to start agent `%s': %s\n", + opt.agent_program, gpg_strerror (rc)); + else + { + /* Give the agent some time to prepare itself. */ + gnupg_sleep (3); + /* Now try again to connect the agent. */ + rc = assuan_socket_connect (&ctx, sockname, 0); + } + } +#else /*!HAVE_W32_SYSTEM*/ + { + const char *pgmname; + const char *argv[3]; + int no_close_list[3]; + int i; + + if ( !(pgmname = strrchr (opt.agent_program, '/'))) + pgmname = opt.agent_program; + else + pgmname++; + + argv[0] = pgmname; + argv[1] = "--server"; + argv[2] = NULL; + + i=0; + if (log_get_fd () != -1) + no_close_list[i++] = log_get_fd (); + no_close_list[i++] = fileno (stderr); + no_close_list[i] = -1; + + /* Connect to the agent and perform initial handshaking. */ + rc = assuan_pipe_connect (&ctx, opt.agent_program, argv, + no_close_list); + } +#endif /*!HAVE_W32_SYSTEM*/ } + xfree (sockname); } else { Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2007-06-19 09:11:11 UTC (rev 4521) +++ trunk/sm/gpgsm.c 2007-06-20 11:16:42 UTC (rev 4522) @@ -1438,7 +1438,7 @@ { log_debug ("waiting for debugger - my pid is %u .....\n", (unsigned int)getpid()); - sleep (debug_wait); + gnupg_sleep (debug_wait); log_debug ("... okay\n"); } gpgsm_server (recplist); From cvs at cvs.gnupg.org Wed Jun 20 16:29:53 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 20 Jun 2007 16:29:53 +0200 Subject: [svn] pinentry - r159 - in trunk: . secmem w32 Message-ID: Author: wk Date: 2007-06-20 16:29:22 +0200 (Wed, 20 Jun 2007) New Revision: 159 Added: trunk/README.SVN Removed: trunk/README.CVS Modified: trunk/ChangeLog trunk/Makefile.am trunk/NEWS trunk/autogen.sh trunk/secmem/secmem.c trunk/w32/Makefile.am trunk/w32/main.c Log: Made W32 version work. There are still some glitches but it works with gpg-agent. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-05-10 17:37:07 UTC (rev 158) +++ trunk/ChangeLog 2007-06-20 14:29:22 UTC (rev 159) @@ -1,3 +1,25 @@ +2007-06-20 Werner Koch + + * w32/main.c (wchar_to_utf8): New. + (ok_button_clicked): Use it. + (utf8_to_wchar): New. + (set_dlg_item_text): New. + (dlg_proc): Use new function so that we are able to correctly + display all prompts. + (main): Load LockSetForegroundWindow. + (dlg_proc): Call LockSetForegroundWindow via its fnc ptr. + (center_window): New. Taken from GPGol. + (dlg_proc): Call it. + (w32_cmd_handler): Revamped the confirm mode. + +2007-06-18 Werner Koch + + * w32/main.c (dlg_proc): Call LockSetForegroundWindow. + + * Makefile.am (signed-dist, %.sig): Remove. + + * autogen.sh: Modernized. + 2007-05-10 Marcus Brinkmann * pinentry/pinentry.h (pinentry_color_t): New type. Modified: trunk/Makefile.am =================================================================== --- trunk/Makefile.am 2007-05-10 17:37:07 UTC (rev 158) +++ trunk/Makefile.am 2007-06-20 14:29:22 UTC (rev 159) @@ -21,7 +21,7 @@ ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = autogen.sh README.CVS Manifest +EXTRA_DIST = autogen.sh README.SVN Manifest if BUILD_PINENTRY_CURSES pinentry_curses = curses @@ -56,11 +56,7 @@ SUBDIRS = assuan secmem pinentry ${pinentry_curses} \ ${pinentry_gtk} ${pinentry_gtk_2} ${pinentry_qt} ${pinentry_w32} doc -signed-dist: $(distdir).tar.gz.sig -%.sig: % - gpg -sbav -u 0x57548DCD $@ $< - install-exec-local: @list='$(bin_PROGRAMS)'; for p in $$list; do \ echo " $(SETCAP) cap_ipc_lock+p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \ Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2007-05-10 17:37:07 UTC (rev 158) +++ trunk/NEWS 2007-06-20 14:29:22 UTC (rev 159) @@ -10,7 +10,9 @@ * New option --colors=FG,BG,SO to set the colors for the curses pinentry. + * Pinentry-w32 does now work. + Noteworthy changes in version 0.7.2 (2005-01-27) ------------------------------------------------ Deleted: trunk/README.CVS Added: trunk/README.SVN =================================================================== --- trunk/README.SVN 2007-05-10 17:37:07 UTC (rev 158) +++ trunk/README.SVN 2007-06-20 14:29:22 UTC (rev 159) @@ -0,0 +1,51 @@ +If you are building from Subversion, run the script + +./autogen.sh + +first, to make sure that you have all the necessary maintainer tools +are installed and to build the actual configuration files. If you +have just updated from SVN, you should add the option "--force" to +autogen.sh so that meta data from SVN is noticed. Then run + +./configure --enable-maintainer-mode + +followed by the usual make. + +If autogen.sh complains about insufficient versions of the required +tools, or the tools are not installed, you may use environment +variables to override the default tool names: + + AUTOMAKE_SUFFIX is used as a suffix for all tools from the automake + package. For example + AUTOMAKE_SUFFIX="-1.7" ./autogen.sh + uses "automake-1.7" and "aclocal-1.7. + AUTOMAKE_PREFIX is used as a prefix for all tools from the automake + page and may be combined with AUTOMAKE_SUFFIX. e.g.: + AUTOMAKE_PREFIX=/usr/foo/bin ./autogen.sh + uses "automake" and "aclocal" in the /usr/foo/bin + directory. + AUTOCONF_SUFFIX is used as a suffix for all tools from the automake + package + AUTOCONF_PREFIX is used as a prefix for all tools from the automake + package + GETTEXT_SUFFIX is used as a suffix for all tools from the gettext + package + GETTEXT_PREFIX is used as a prefix for all tools from the gettext + package + +It is also possible to use the variable name AUTOMAKE, AUTOCONF, +ACLOCAL, AUTOHEADER, GETTEXT and MSGMERGE to directly specify the name +of the programs to run. It is however better to use the suffix and +prefix forms as described above because that does not require +knowledge about the actual tools used by autgen.sh. + + +Please don't use autopoint, libtoolize or autoreconf unless you are +the current maintainer and want to update the standard configuration +files. All those files should be in the SVN and only updated manually +if the maintainer decides that newer versions are required. The +maintainer should also make sure that the required version of automake +et al. are properly indicated at the top of configure.ac and take care +to copy the files and not merely use symlinks. + + Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2007-05-10 17:37:07 UTC (rev 158) +++ trunk/autogen.sh 2007-06-20 14:29:22 UTC (rev 159) @@ -28,7 +28,24 @@ return 1 } +# Allow to override the default tool names +AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX} +AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX} +AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX} +ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX} + +GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX} +MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX} + +DIE=no +FORCE= +if test x"$1" = x"--force"; then + FORCE=" --force" + shift +fi + + # ***** W32 build script ******* # Used to cross-compile for Windows. if test "$1" = "--build-w32"; then @@ -44,25 +61,22 @@ [ -z "$w32root" ] && w32root="$HOME/w32root" echo "Using $w32root as standard install directory" >&2 - # See whether we have the Debian cross compiler package or the - # old mingw32/cpd system - if i586-mingw32msvc-gcc --version >/dev/null 2>&1 ; then - host=i586-mingw32msvc - crossbindir=/usr/$host/bin - else - host=i386--mingw32 - if ! mingw32 --version >/dev/null; then - echo "We need at least version 0.3 of MingW32/CPD" >&2 - exit 1 - fi - crossbindir=`mingw32 --install-dir`/bin - # Old autoconf version required us to setup the environment - # with the proper tool names. - CC=`mingw32 --get-path gcc` - CPP=`mingw32 --get-path cpp` - AR=`mingw32 --get-path ar` - RANLIB=`mingw32 --get-path ranlib` - export CC CPP AR RANLIB + + # Locate the cross compiler + crossbindir= + for host in i586-mingw32msvc i386-mingw32msvc mingw32; do + if ${host}-gcc --version >/dev/null 2>&1 ; then + crossbindir=/usr/${host}/bin + conf_CC="CC=${host}-gcc" + break; + fi + done + if [ -z "$crossbindir" ]; then + echo "Cross compiler kit not installed" >&2 + echo "Under Debian GNU/Linux, you may install it using" >&2 + echo " apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2 + echo "Stop." >&2 + exit 1 fi if [ -f "$tsdir/config.log" ]; then @@ -73,16 +87,12 @@ fi ./configure --enable-maintainer-mode --prefix=${w32root} \ - --host=i586-mingw32msvc --build=${build} \ + --host=${host} --build=${build} \ --disable-pinentry-gtk \ --disable-pinentry-gtk2 \ --disable-pinentry-qt rc=$? - # Ugly hack to overcome a gettext problem. Someone should look into - # gettext to figure out why the po directory is not ignored as it used - # to be. - [ $rc = 0 ] && touch $tsdir/po/all exit $rc fi # ***** end W32 build script ******* @@ -116,19 +126,6 @@ exit 1 fi -# Allow to override the default tool names -AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX} -AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX} - -AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX} -ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX} - -#GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX} -#MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX} - -DIE=no - - if check_version $AUTOCONF $autoconf_vers_num $autoconf_vers ; then check_version $AUTOHEADER $autoconf_vers_num $autoconf_vers autoconf fi @@ -143,7 +140,7 @@ cat < wscreen) + xnew = wscreen - wchild; + ynew = rparent.top + ((hparent - hchild) / 2); + if (ynew < 0) + ynew = 0; + else if ((ynew+hchild) > hscreen) + ynew = hscreen - hchild; + if (style == HWND_TOPMOST || style == HWND_NOTOPMOST) + flags = SWP_NOMOVE | SWP_NOSIZE; + SetWindowPos (childwnd, style? style : NULL, xnew, ynew, 0, 0, flags); +} + + + + + +/* Call SetDlgItemTextW with an UTF8 string. */ +static void +set_dlg_item_text (HWND dlg, int item, const char *string) +{ + if (!string || !*string) + SetDlgItemText (dlg, item, ""); + else + { + wchar_t *wbuf; + + wbuf = utf8_to_wchar (string); + if (!wbuf) + SetDlgItemText (dlg, item, "[out of core]"); + else + { + SetDlgItemTextW (dlg, item, wbuf); + free (wbuf); + } + } +} + + /* Dialog processing loop. */ static BOOL CALLBACK dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam) @@ -57,24 +192,40 @@ pe = (pinentry_t)lparam; if (!pe) abort (); - SetDlgItemText (dlg, IDC_PINENT_PROMPT, pe->prompt); - SetDlgItemText (dlg, IDC_PINENT_DESC, pe->description); - SetDlgItemText (dlg, IDC_PINENT_TEXT, ""); + set_dlg_item_text (dlg, IDC_PINENT_PROMPT, pe->prompt); + set_dlg_item_text (dlg, IDC_PINENT_DESC, pe->description); + set_dlg_item_text (dlg, IDC_PINENT_TEXT, ""); if (pe->ok) - SetDlgItemText (dlg, IDOK, pe->ok); + set_dlg_item_text (dlg, IDOK, pe->ok); if (pe->cancel) - SetDlgItemText (dlg, IDCANCEL, pe->cancel); + set_dlg_item_text (dlg, IDCANCEL, pe->cancel); if (pe->error) - SetDlgItemText (dlg, IDC_PINENT_ERR, pe->error); + set_dlg_item_text (dlg, IDC_PINENT_ERR, pe->error); + + if (confirm_mode) + { + EnableWindow (GetDlgItem (dlg, IDC_PINENT_TEXT), FALSE); + SetWindowPos (GetDlgItem (dlg, IDC_PINENT_TEXT), NULL, 0, 0, 0, 0, + (SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_HIDEWINDOW)); + } + dialog_handle = dlg; - SetForegroundWindow (dlg); + center_window (dlg, HWND_TOP); + /* Fixme: There are two problems: A race condition between the + two calls and more important that SetForegroundWindow will + fail if a Menu is somewhere open. */ + if (SetForegroundWindow (dlg) && lock_set_foreground_window) + lock_set_foreground_window (LSFW_LOCK); break; case WM_COMMAND: switch (LOWORD (wparam)) { case IDOK: - ok_button_clicked (dlg, pe); + if (confirm_mode) + confirm_yes = 1; + else + ok_button_clicked (dlg, pe); EndDialog (dlg, TRUE); break; @@ -95,27 +246,27 @@ ok_button_clicked (HWND dlg, pinentry_t pe) { char *s_utf8; - char *s_buffer; - size_t s_buffer_size = 256; + wchar_t *w_buffer; + size_t w_buffer_size = 255; + unsigned int nchar; pe->locale_err = 1; - s_buffer = secmem_malloc (s_buffer_size + 1); - if (!s_buffer) + w_buffer = secmem_malloc ((w_buffer_size + 1) * sizeof *w_buffer); + if (!w_buffer) return; - pe->result = GetDlgItemText (dlg, IDC_PINENT_TEXT, s_buffer, s_buffer_size); -/* s_utf8 = pinentry_local_to_utf8 (pe->lc_ctype, s_buffer, 1); */ -/* secmem_free (s_buffer); */ - s_utf8 = s_buffer; /* FIXME */ + nchar = GetDlgItemTextW (dlg, IDC_PINENT_TEXT, w_buffer, w_buffer_size); + s_utf8 = wchar_to_utf8 (w_buffer, nchar, 1); + secmem_free (w_buffer); if (s_utf8) { passphrase_ok = 1; pinentry_setbufferlen (pe, strlen (s_utf8) + 1); if (pe->pin) strcpy (pe->pin, s_utf8); -/* secmem_free (s_utf8); */ + secmem_free (s_utf8); pe->locale_err = 0; - pe->result = strlen (pe->pin); + pe->result = pe->pin? strlen (pe->pin) : 0; } } @@ -123,37 +274,31 @@ static int w32_cmd_handler (pinentry_t pe) { - int want_pass = !!pe->pin; + confirm_mode = !pe->pin; - passphrase_ok = 0; + passphrase_ok = confirm_yes = 0; - if (want_pass) - { - DialogBoxParam (NULL, (LPCTSTR) IDD_PINENT, - GetDesktopWindow (), dlg_proc, (LPARAM)pe); - ShowWindow (dialog_handle, SW_SHOWNORMAL); - return pe->result; - } - else /* Confirmation mode. */ - { - int ret; - - if (pe->error) - ret = MessageBox (NULL, pe->error, "Error", MB_YESNO | MB_ICONERROR); - else - ret = MessageBox (NULL, pe->description?pe->description:"", - "Information", MB_YESNO | MB_ICONINFORMATION); - if (ret == IDYES) - return 1; - else - return 0; - } + DialogBoxParam (NULL, (LPCTSTR) IDD_PINENT, + GetDesktopWindow (), dlg_proc, (LPARAM)pe); + ShowWindow (dialog_handle, SW_SHOWNORMAL); + if (lock_set_foreground_window) + lock_set_foreground_window (LSFW_UNLOCK); + DestroyWindow (dialog_handle); + dialog_handle = NULL; + if (confirm_mode) + return confirm_yes; + else if (passphrase_ok && pe->pin) + return strlen (pe->pin); + else + return -1; } int main (int argc, char **argv) { + void *handle; + pinentry_init (PGMNAME); /* Consumes all arguments. */ @@ -163,6 +308,19 @@ exit (EXIT_SUCCESS); } + /* We need to load a functuion because that one is only available + since W2000 but not in older NTs. */ + handle = LoadLibrary ("user32.dll"); + if (handle) + { + void *foo; + foo = GetProcAddress (handle, "LockSetForegroundWindow"); + if (foo) + lock_set_foreground_window = foo; + else + CloseHandle (handle); + } + if (pinentry_loop ()) return 1; From cvs at cvs.gnupg.org Wed Jun 20 19:02:54 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 20 Jun 2007 19:02:54 +0200 Subject: [svn] gcry - r1257 - trunk/tests Message-ID: Author: wk Date: 2007-06-20 19:02:25 +0200 (Wed, 20 Jun 2007) New Revision: 1257 Modified: trunk/tests/ChangeLog trunk/tests/benchmark.c Log: Add an RSA benchmark. Modified: trunk/tests/ChangeLog =================================================================== --- trunk/tests/ChangeLog 2007-06-15 13:24:23 UTC (rev 1256) +++ trunk/tests/ChangeLog 2007-06-20 17:02:25 UTC (rev 1257) @@ -1,3 +1,8 @@ +2007-06-20 Werner Koch + + * benchmark.c (rsa_bench): New. + (main): New command "rsa". + 2007-05-03 Werner Koch * Makefile.am (EXTRA_DIST): Do not build pkbench.c Modified: trunk/tests/benchmark.c =================================================================== --- trunk/tests/benchmark.c 2007-06-15 13:24:23 UTC (rev 1256) +++ trunk/tests/benchmark.c 2007-06-20 17:02:25 UTC (rev 1257) @@ -551,6 +551,97 @@ static void +rsa_bench (int iterations, int print_header) +{ + gpg_error_t err; + int p_sizes[] = { 1024, 2048, 3072, 4096 }; + int testno; + + if (print_header) + printf ("Algorithm generate %4d*sign %4d*verify\n" + "----------------------------------------------\n", + iterations, iterations ); + for (testno=0; testno < DIM (p_sizes); testno++) + { + gcry_sexp_t key_spec, key_pair, pub_key, sec_key; + gcry_mpi_t x; + gcry_sexp_t data; + gcry_sexp_t sig = NULL; + int count; + + printf ("RSA %3d bit ", p_sizes[testno]); + fflush (stdout); + + err = gcry_sexp_build (&key_spec, NULL, + "(genkey (RSA (nbits %d)))", p_sizes[testno]); + if (err) + die ("creating S-expression failed: %s\n", gcry_strerror (err)); + + start_timer (); + err = gcry_pk_genkey (&key_pair, key_spec); + if (err) + die ("creating %d bit RSA key failed: %s\n", + p_sizes[testno], gcry_strerror (err)); + + pub_key = gcry_sexp_find_token (key_pair, "public-key", 0); + if (! pub_key) + die ("public part missing in key\n"); + sec_key = gcry_sexp_find_token (key_pair, "private-key", 0); + if (! sec_key) + die ("private part missing in key\n"); + gcry_sexp_release (key_pair); + gcry_sexp_release (key_spec); + + stop_timer (); + printf (" %s", elapsed_time ()); + fflush (stdout); + + x = gcry_mpi_new (p_sizes[testno]); + gcry_mpi_randomize (x, p_sizes[testno], GCRY_WEAK_RANDOM); + err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); + gcry_mpi_release (x); + if (err) + die ("converting data failed: %s\n", gcry_strerror (err)); + + start_timer (); + for (count=0; count < iterations; count++) + { + gcry_sexp_release (sig); + err = gcry_pk_sign (&sig, data, sec_key); + if (err) + die ("signing failed: %s\n", gpg_strerror (err)); + } + stop_timer (); + printf (" %s", elapsed_time ()); + fflush (stdout); + + start_timer (); + for (count=0; count < iterations; count++) + { + err = gcry_pk_verify (sig, data, pub_key); + if (err) + { + putchar ('\n'); + show_sexp ("seckey:\n", sec_key); + show_sexp ("data:\n", data); + show_sexp ("sig:\n", sig); + die ("verify failed: %s\n", gpg_strerror (err)); + } + } + stop_timer (); + printf (" %s\n", elapsed_time ()); + fflush (stdout); + + gcry_sexp_release (sig); + gcry_sexp_release (data); + gcry_sexp_release (sec_key); + gcry_sexp_release (pub_key); + } +} + + + +static void dsa_bench (int iterations, int print_header) { gpg_error_t err; @@ -843,7 +934,8 @@ random_bench (0); } else if ( !strcmp (*argv, "--help")) - fputs ("usage: benchmark [md|cipher|random|mpi|dsa|ecc [algonames]]\n", + fputs ("usage: benchmark " + "[md|cipher|random|mpi|rsa|dsa|ecc [algonames]]\n", stdout); else if ( !strcmp (*argv, "random") || !strcmp (*argv, "strongrandom")) { @@ -878,6 +970,11 @@ { mpi_bench (); } + else if ( !strcmp (*argv, "rsa")) + { + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + rsa_bench (100, 1); + } else if ( !strcmp (*argv, "dsa")) { gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); From cvs at cvs.gnupg.org Wed Jun 20 20:08:21 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 20 Jun 2007 20:08:21 +0200 Subject: [svn] gcry - r1258 - trunk/tests Message-ID: Author: wk Date: 2007-06-20 20:07:52 +0200 (Wed, 20 Jun 2007) New Revision: 1258 Modified: trunk/tests/benchmark.c Log: Add an RSA benchmark (fix) Modified: trunk/tests/benchmark.c =================================================================== --- trunk/tests/benchmark.c 2007-06-20 17:02:25 UTC (rev 1257) +++ trunk/tests/benchmark.c 2007-06-20 18:07:52 UTC (rev 1258) @@ -597,7 +597,7 @@ fflush (stdout); x = gcry_mpi_new (p_sizes[testno]); - gcry_mpi_randomize (x, p_sizes[testno], GCRY_WEAK_RANDOM); + gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM); err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); gcry_mpi_release (x); if (err) @@ -609,7 +609,7 @@ gcry_sexp_release (sig); err = gcry_pk_sign (&sig, data, sec_key); if (err) - die ("signing failed: %s\n", gpg_strerror (err)); + die ("signing failed (%d): %s\n", count, gpg_strerror (err)); } stop_timer (); printf (" %s", elapsed_time ()); @@ -625,7 +625,7 @@ show_sexp ("seckey:\n", sec_key); show_sexp ("data:\n", data); show_sexp ("sig:\n", sig); - die ("verify failed: %s\n", gpg_strerror (err)); + die ("verify failed (%d): %s\n", count, gpg_strerror (err)); } } stop_timer (); From cvs at cvs.gnupg.org Thu Jun 21 20:45:27 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Thu, 21 Jun 2007 20:45:27 +0200 Subject: [svn] GnuPG - r4523 - in trunk: . agent common doc g10 scd sm Message-ID: Author: wk Date: 2007-06-21 20:44:48 +0200 (Thu, 21 Jun 2007) New Revision: 4523 Added: trunk/sm/certreqgen-ui.c Modified: trunk/NEWS trunk/TODO trunk/agent/ChangeLog trunk/agent/agent.h trunk/agent/gpg-agent.c trunk/common/ChangeLog trunk/common/asshelp.c trunk/common/asshelp.h trunk/common/exechelp.c trunk/common/membuf.c trunk/common/membuf.h trunk/common/ttyio.c trunk/common/ttyio.h trunk/common/util.h trunk/doc/ChangeLog trunk/doc/glossary.texi trunk/doc/gpg-agent.texi trunk/doc/gpgsm.texi trunk/g10/ChangeLog trunk/g10/call-agent.c trunk/g10/gpg.h trunk/g10/main.h trunk/g10/sign.c trunk/scd/ChangeLog trunk/scd/scdaemon.h trunk/sm/ChangeLog trunk/sm/Makefile.am trunk/sm/call-agent.c trunk/sm/certreqgen.c trunk/sm/gpgsm.c trunk/sm/gpgsm.h trunk/sm/server.c Log: Implemented the --gen-key command as we can't use the gpgsm-gencert.sh under Windows. Modified: trunk/NEWS =================================================================== --- trunk/NEWS 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/NEWS 2007-06-21 18:44:48 UTC (rev 4523) @@ -5,7 +5,10 @@ * Changes required for a port to Windows. + * The command --gen-key may now be used instead of the + gpgsm-gencert.sh script. + Noteworthy changes in version 2.0.4 (2007-05-09) ------------------------------------------------ Modified: trunk/TODO =================================================================== --- trunk/TODO 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/TODO 2007-06-21 18:44:48 UTC (rev 4523) @@ -95,7 +95,7 @@ * When requiring libksba 1.0.1 ** Remove the extra GPG_ERR_NO_VALUE tests - They have need added on 2006-10-18 to fix a libksba problem. + They have been added on 2006-10-18 to fix a libksba problem. * When switching to libgcrypt 1.3 ** scd#encode_md_for_card, g10#encode_md_value, sm at do_encode_md Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/agent/ChangeLog 2007-06-21 18:44:48 UTC (rev 4523) @@ -1,3 +1,12 @@ +2007-06-21 Werner Koch + + * agent.h (ctrl_t): Remove. It is now declared in ../common/util.h. + + * gpg-agent.c (check_for_running_agent): New arg SILENT. Changed + all callers. + (create_server_socket): If the standard socket is in use check + whether a agent is running and avoid starting another one. + 2007-06-18 Marcus Brinkmann * gpg-agent.c (main): Percent escape pathname in --gpgconf-list Modified: trunk/agent/agent.h =================================================================== --- trunk/agent/agent.h 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/agent/agent.h 2007-06-21 18:44:48 UTC (rev 4523) @@ -150,9 +150,7 @@ PKSIGN command to the scdaemon. */ }; -typedef struct server_control_s *ctrl_t; - struct pin_entry_info_s { int min_digits; /* min. number of digits required or 0 for freeform entry */ Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/agent/gpg-agent.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -1,6 +1,6 @@ /* gpg-agent.c - The GnuPG Agent - * Copyright (C) 2000, 2001, 2002, 2003, 2004, - * 2005 Free Software Foundation, Inc. + * Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, + * 2006, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -93,7 +93,6 @@ oMinPassphraseLen, oUseStandardSocket, oNoUseStandardSocket, - oNoReuseStandardSocket, oIgnoreCacheForSigning, oAllowMarkTrusted, @@ -131,8 +130,6 @@ { oUseStandardSocket, "use-standard-socket", 0, N_("use a standard location for the socket")}, { oNoUseStandardSocket, "no-use-standard-socket", 0, "@"}, - { oNoReuseStandardSocket, "no-reuse-standard-socket", 0, "@"}, - { oPinentryProgram, "pinentry-program", 2 , N_("|PGM|use PGM as the PIN-Entry program") }, { oPinentryTouchFile, "pinentry-touch-file", 2 , "@" }, @@ -188,10 +185,6 @@ /* Name of the communication socket used for ssh-agent-emulation. */ static char *socket_name_ssh; -/* If set to true and a standard socket is requested, we won't try to - bind to a socket which is already in use. */ -static int no_reuse_standard_socket; - /* Default values for options passed to the pinentry. */ static char *default_display; static char *default_ttyname; @@ -228,7 +221,7 @@ static void agent_deinit_default_ctrl (ctrl_t ctrl); static void handle_connections (int listen_fd, int listen_fd_ssh); -static int check_for_running_agent (int); +static int check_for_running_agent (int silent, int mode); /* Pth wrapper function definitions. */ GCRY_THREAD_OPTION_PTH_IMPL; @@ -627,7 +620,6 @@ case oUseStandardSocket: standard_socket = 1; break; case oNoUseStandardSocket: standard_socket = 0; break; - case oNoReuseStandardSocket: no_reuse_standard_socket = 1; break; case oKeepTTY: opt.keep_tty = 1; break; case oKeepDISPLAY: opt.keep_display = 1; break; @@ -765,7 +757,7 @@ if (!pipe_server && !is_daemon) { log_set_prefix (NULL, JNLIB_LOG_WITH_PREFIX); - check_for_running_agent (0); + check_for_running_agent (0, 0); agent_exit (0); } @@ -1264,17 +1256,32 @@ #ifdef HAVE_W32_SYSTEM rc = _w32_sock_bind (fd, (struct sockaddr*) serv_addr, len); - if (is_standard_name && rc == -1 && errno == WSAEADDRINUSE - && !no_reuse_standard_socket) + if (is_standard_name && rc == -1 && errno == WSAEADDRINUSE) { + if (!check_for_running_agent (1, 1)) + { + log_error (_("a gpg-agent is already running - " + "not starting a new one\n")); + *name = 0; /* Inhibit removal of the socket by cleanup(). */ + close (fd); + agent_exit (2); + } + remove (name); rc = _w32_sock_bind (fd, (struct sockaddr*) serv_addr, len); } #else rc = bind (fd, (struct sockaddr*) serv_addr, len); - if (is_standard_name && rc == -1 && errno == EADDRINUSE - && !no_reuse_standard_socket) + if (is_standard_name && rc == -1 && errno == EADDRINUSE) { + if (!check_for_running_agent (1, 1)) + { + log_error (_("a gpg-agent is already running - " + "not starting a new one\n")); + *name = 0; /* Inhibit removal of the socket by cleanup(). */ + close (fd); + agent_exit (2); + } remove (name); rc = bind (fd, (struct sockaddr*) serv_addr, len); } @@ -1288,7 +1295,7 @@ gpg_strerror (gpg_error_from_errno (errno))); close (fd); - if (is_standard_name && no_reuse_standard_socket) + if (is_standard_name) *name = 0; /* Inhibit removal of the socket by cleanup(). */ agent_exit (2); } @@ -1725,9 +1732,10 @@ /* Figure out whether an agent is available and running. Prints an - error if not. Usually started with MODE 0. */ + error if not. If SILENT is true, no mesdsages are printed. Usually + started with MODE 0. Returns 0 if the agent is running. */ static int -check_for_running_agent (int mode) +check_for_running_agent (int silent, int mode) { int rc; char *infostr, *p; @@ -1739,9 +1747,10 @@ infostr = getenv ("GPG_AGENT_INFO"); if (!infostr || !*infostr) { - if (!check_for_running_agent (1)) + if (!check_for_running_agent (silent, 1)) return 0; /* Okay, its running on the standard socket. */ - log_error (_("no gpg-agent running in this session\n")); + if (!silent) + log_error (_("no gpg-agent running in this session\n")); return -1; } @@ -1749,9 +1758,10 @@ if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr) { xfree (infostr); - if (!check_for_running_agent (1)) + if (!check_for_running_agent (silent, 1)) return 0; /* Okay, its running on the standard socket. */ - log_error (_("malformed GPG_AGENT_INFO environment variable\n")); + if (!silent) + log_error (_("malformed GPG_AGENT_INFO environment variable\n")); return -1; } @@ -1763,9 +1773,10 @@ if (prot != 1) { xfree (infostr); - log_error (_("gpg-agent protocol version %d is not supported\n"), - prot); - if (!check_for_running_agent (1)) + if (!silent) + log_error (_("gpg-agent protocol version %d is not supported\n"), + prot); + if (!check_for_running_agent (silent, 1)) return 0; /* Okay, its running on the standard socket. */ return -1; } @@ -1781,15 +1792,15 @@ xfree (infostr); if (rc) { - if (!mode && !check_for_running_agent (1)) + if (!mode && !check_for_running_agent (silent, 1)) return 0; /* Okay, its running on the standard socket. */ - if (!mode) + if (!mode && !silent) log_error ("can't connect to the agent: %s\n", gpg_strerror (rc)); return -1; } - if (!opt.quiet) + if (!opt.quiet && !silent) log_info ("gpg-agent running and available\n"); assuan_disconnect (ctx); Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/common/ChangeLog 2007-06-21 18:44:48 UTC (rev 4523) @@ -1,3 +1,17 @@ +2007-06-21 Werner Koch + + * membuf.h (get_membuf_len): New. + + * membuf.c (init_membuf_secure): Really allocate in secure memory. + (put_membuf_str): New. + + * ttyio.c (tty_getf): New. + + * util.h (ctrl_t): Declare it here. + + * asshelp.c (start_new_gpg_agent): New. Based on code from + ../sm/call-agent.c + 2007-06-20 Werner Koch * sysutils.c (gnupg_sleep): New. Modified: trunk/common/asshelp.c =================================================================== --- trunk/common/asshelp.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/common/asshelp.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -29,8 +29,11 @@ #include #endif +#include "i18n.h" #include "util.h" - +#include "exechelp.h" +#include "sysutils.h" +#include "errors.h" /* FIXME: This one conatisn only status code - rename it*/ #include "asshelp.h" @@ -164,3 +167,182 @@ return 0; } + +/* Try to connect to the agent via socket or fork it off and work by + pipes. Handle the server's initial greeting. Returns a new assuan + context at R_CTX or an error code. */ +gpg_error_t +start_new_gpg_agent (assuan_context_t *r_ctx, + gpg_err_source_t errsource, + const char *homedir, + const char *agent_program, + const char *opt_display, + const char *opt_ttyname, + const char *opt_ttytype, + const char *opt_lc_ctype, + const char *opt_lc_messages, + int verbose, int debug, + gpg_error_t (*status_cb)(ctrl_t, int, ...), + ctrl_t status_cb_arg) +{ + /* If we ever failed to connect via a socket we will force the use + of the pipe based server for the lifetime of the process. */ + static int force_pipe_server = 0; + + gpg_error_t rc = 0; + char *infostr, *p; + assuan_context_t ctx; + + *r_ctx = NULL; + + restart: + infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO"); + if (!infostr || !*infostr) + { + char *sockname; + + /* First check whether we can connect at the standard + socket. */ + sockname = make_filename (homedir, "S.gpg-agent", NULL); + rc = assuan_socket_connect (&ctx, sockname, 0); + + if (rc) + { + /* With no success start a new server. */ + if (verbose) + log_info (_("no running gpg-agent - starting one\n")); + + if (status_cb) + status_cb (status_cb_arg, STATUS_PROGRESS, + "starting_agent ? 0 0", NULL); + + if (fflush (NULL)) + { + gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); + log_error ("error flushing pending output: %s\n", + strerror (errno)); + xfree (sockname); + return tmperr; + } + + if (!agent_program || !*agent_program) + agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); + +#ifdef HAVE_W32_SYSTEM + { + /* Under Windows we start the server in daemon mode. This + is because the default is to use the standard socket + and thus there is no need for the GPG_AGENT_INFO + envvar. This is possible as we don't have a real unix + domain socket but use a plain file and thus there is no + need to care about non-local file systems. */ + const char *argv[3]; + + argv[0] = "--daemon"; + argv[1] = "--use-standard-socket"; + argv[2] = NULL; + + rc = gnupg_spawn_process_detached (agent_program, argv, NULL); + if (rc) + log_debug ("failed to start agent `%s': %s\n", + agent_program, gpg_strerror (rc)); + else + { + /* Give the agent some time to prepare itself. */ + gnupg_sleep (3); + /* Now try again to connect the agent. */ + rc = assuan_socket_connect (&ctx, sockname, 0); + } + } +#else /*!HAVE_W32_SYSTEM*/ + { + const char *pgmname; + const char *argv[3]; + int no_close_list[3]; + int i; + + if ( !(pgmname = strrchr (agent_program, '/'))) + pgmname = agent_program; + else + pgmname++; + + argv[0] = pgmname; + argv[1] = "--server"; + argv[2] = NULL; + + i=0; + if (log_get_fd () != -1) + no_close_list[i++] = log_get_fd (); + no_close_list[i++] = fileno (stderr); + no_close_list[i] = -1; + + /* Connect to the agent and perform initial handshaking. */ + rc = assuan_pipe_connect (&ctx, agent_program, argv, + no_close_list); + } +#endif /*!HAVE_W32_SYSTEM*/ + } + xfree (sockname); + } + else + { + int prot; + int pid; + + infostr = xstrdup (infostr); + if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr) + { + log_error (_("malformed GPG_AGENT_INFO environment variable\n")); + xfree (infostr); + force_pipe_server = 1; + goto restart; + } + *p++ = 0; + pid = atoi (p); + while (*p && *p != PATHSEP_C) + p++; + prot = *p? atoi (p+1) : 0; + if (prot != 1) + { + log_error (_("gpg-agent protocol version %d is not supported\n"), + prot); + xfree (infostr); + force_pipe_server = 1; + goto restart; + } + + rc = assuan_socket_connect (&ctx, infostr, pid); + xfree (infostr); + if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED) + { + log_info (_("can't connect to the agent - trying fall back\n")); + force_pipe_server = 1; + goto restart; + } + } + + if (rc) + { + log_error ("can't connect to the agent: %s\n", gpg_strerror (rc)); + return gpg_error (GPG_ERR_NO_AGENT); + } + + if (debug) + log_debug ("connection to agent established\n"); + + rc = assuan_transact (ctx, "RESET", + NULL, NULL, NULL, NULL, NULL, NULL); + if (!rc) + rc = send_pinentry_environment (ctx, errsource, + opt_display, opt_ttyname, opt_ttytype, + opt_lc_ctype, opt_lc_messages); + if (rc) + { + assuan_disconnect (ctx); + return rc; + } + + *r_ctx = ctx; + return 0; +} + Modified: trunk/common/asshelp.h =================================================================== --- trunk/common/asshelp.h 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/common/asshelp.h 2007-06-21 18:44:48 UTC (rev 4523) @@ -34,5 +34,21 @@ const char *opt_lc_ctype, const char *opt_lc_messages); +/* This fucntion is used by the call-agent.c modules to fire up a new + agent. What a parameter list ;-). */ +gpg_error_t +start_new_gpg_agent (assuan_context_t *r_ctx, + gpg_err_source_t errsource, + const char *homedir, + const char *agent_program, + const char *opt_display, + const char *opt_ttyname, + const char *opt_ttytype, + const char *opt_lc_ctype, + const char *opt_lc_messages, + int verbose, int debug, + gpg_error_t (*status_cb)(ctrl_t, int, ...), + ctrl_t status_cb_arg); + #endif /*GNUPG_COMMON_ASSHELP_H*/ Modified: trunk/common/exechelp.c =================================================================== --- trunk/common/exechelp.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/common/exechelp.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -593,7 +593,7 @@ cmdline, /* Command line arguments. */ &sec_attr, /* Process security attributes. */ &sec_attr, /* Thread security attributes. */ - FALSE, /* Inherit handles. */ + FALSE, /* Inherit handles. */ cr_flags, /* Creation flags. */ NULL, /* Environment. */ NULL, /* Use current drive/directory. */ Modified: trunk/common/membuf.c =================================================================== --- trunk/common/membuf.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/common/membuf.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -52,7 +52,7 @@ mb->len = 0; mb->size = initiallen; mb->out_of_core = 0; - mb->buf = xtrymalloc (initiallen); + mb->buf = xtrymalloc_secure (initiallen); if (!mb->buf) mb->out_of_core = errno; } @@ -87,6 +87,13 @@ } +void +put_membuf_str (membuf_t *mb, const char *string) +{ + put_membuf (mb, string, strlen (string)); +} + + void * get_membuf (membuf_t *mb, size_t *len) { Modified: trunk/common/membuf.h =================================================================== --- trunk/common/membuf.h 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/common/membuf.h 2007-06-21 18:44:48 UTC (rev 4523) @@ -34,10 +34,13 @@ typedef struct private_membuf_s membuf_t; +/* Return the current length of the membuf. */ +#define get_membuf_len(a) ((a)->len) void init_membuf (membuf_t *mb, int initiallen); void init_membuf_secure (membuf_t *mb, int initiallen); void put_membuf (membuf_t *mb, const void *buf, size_t len); +void put_membuf_str (membuf_t *mb, const char *string); void *get_membuf (membuf_t *mb, size_t *len); Modified: trunk/common/ttyio.c =================================================================== --- trunk/common/ttyio.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/common/ttyio.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -50,6 +50,7 @@ #include "util.h" #include "ttyio.h" +#include "estream-printf.h" #include "common-defs.h" #define CONTROL_D ('D' - 'A' + 1) @@ -243,7 +244,7 @@ } -/* Same as tty_printf but if FP is not NULL, behave like a regualr +/* Same as tty_printf but if FP is not NULL, behave like a regular fprintf. */ void tty_fprintf (FILE *fp, const char *fmt, ... ) @@ -563,7 +564,27 @@ return do_get ( prompt, 0 ); } +/* Variable argument version of tty_get. The prompt is is actually a + format string with arguments. */ char * +tty_getf (const char *promptfmt, ... ) +{ + va_list arg_ptr; + char *prompt; + char *answer; + + va_start (arg_ptr, promptfmt); + if (estream_vasprintf (&prompt, promptfmt, arg_ptr) < 0) + log_fatal ("estream_vasprintf failed: %s\n", strerror (errno)); + va_end (arg_ptr); + answer = tty_get (prompt); + xfree (prompt); + return answer; +} + + + +char * tty_get_hidden( const char *prompt ) { return do_get( prompt, 1 ); Modified: trunk/common/ttyio.h =================================================================== --- trunk/common/ttyio.h 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/common/ttyio.h 2007-06-21 18:44:48 UTC (rev 4523) @@ -31,9 +31,12 @@ __attribute__ ((format (printf,1,2))); void tty_fprintf (FILE *fp, const char *fmt, ... ) __attribute__ ((format (printf,2,3))); +char *tty_getf (const char *promptfmt, ... ) + __attribute__ ((format (printf,1,2))); #else void tty_printf (const char *fmt, ... ); void tty_fprintf (FILE *fp, const char *fmt, ... ); +char *tty_getf (const char *promptfmt, ... ); #endif void tty_print_string (const unsigned char *p, size_t n); void tty_print_utf8_string (const unsigned char *p, size_t n); Modified: trunk/common/util.h =================================================================== --- trunk/common/util.h 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/common/util.h 2007-06-21 18:44:48 UTC (rev 4523) @@ -46,7 +46,6 @@ #define asprintf estream_asprintf #define vasprintf estream_vasprintf - /* GCC attributes. */ #if __GNUC__ >= 4 # define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a))) @@ -246,5 +245,10 @@ #define xtoi_4(p) ((xtoi_2(p) * 256) + xtoi_2((p)+2)) +/*-- Forward declaration of the commonly used server control structure. */ +/* (We need it here as it is used by some callback prototypes.) */ +struct server_control_s; +typedef struct server_control_s *ctrl_t; + #endif /*GNUPG_COMMON_UTIL_H*/ Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/doc/ChangeLog 2007-06-21 18:44:48 UTC (rev 4523) @@ -1,3 +1,8 @@ +2007-06-21 Werner Koch + + * gpgsm.texi (Certificate Management): Changed description of + --gen-key. + 2007-06-19 Werner Koch * glossary.texi (Glossary): Describe PSE. Modified: trunk/doc/glossary.texi =================================================================== --- trunk/doc/glossary.texi 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/doc/glossary.texi 2007-06-21 18:44:48 UTC (rev 4523) @@ -16,6 +16,11 @@ The @emph{Certificate Revocation List} is a list containing certificates revoked by the issuer. + at item CSR + The @emph{Certificate Signing Request} is a message send to a CA to +ask them to issue a new certificate. The data format of such a signing +request is called PCKS#10. + @item Keygrip This term is used by GnuPG to describe a 20 byte hash value used to identify a certain key without referencing to a concrete protocol. Modified: trunk/doc/gpg-agent.texi =================================================================== --- trunk/doc/gpg-agent.texi 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/doc/gpg-agent.texi 2007-06-21 18:44:48 UTC (rev 4523) @@ -369,20 +369,16 @@ @item --use-standard-socket @itemx --no-use-standard-socket - at itemx --no-reuse-standard-socket @opindex use-standard-socket @opindex no-use-standard-socket - at opindex no-reuse-standard-socket By enabling this option @command{gpg-agent} will listen on the socket named @file{S.gpg-agent}, located in the home directory, and not create a random socket below a temporary directory. Tools connecting to @command{gpg-agent} should first try to connect to the socket given in environment variable @var{GPG_AGENT_INFO} and the fall back to this socket. This option may not be used if the home directory is mounted as -a remote file system. If @option{--no-reuse-standard-socket} is used, - at command{gpg-agent} will not try to reuse a socket which is already in -use. Note, that @option{--use-standard-socket} is the default on -Windows systems. +a remote file system. Note, that @option{--use-standard-socket} is the +default on Windows systems. @item --display @var{string} Modified: trunk/doc/gpgsm.texi =================================================================== --- trunk/doc/gpgsm.texi 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/doc/gpgsm.texi 2007-06-21 18:44:48 UTC (rev 4523) @@ -164,8 +164,9 @@ @table @gnupgtabopt @item --gen-key @opindex gen-key -This command will only print an error message and direct the user to the - at command{gpgsm-gencert.sh} script. +This command allows the interactive creation of a certifcate signing +request. It is commonly used along with the @option{--output} option to +save the created CSR into a file. @item --list-keys @itemx -k Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/g10/ChangeLog 2007-06-21 18:44:48 UTC (rev 4523) @@ -1,3 +1,12 @@ +2007-06-21 Werner Koch + + * main.h: Include util.h. + + * call-agent.c (start_agent): Factored almost all code out to + ../common/asshelp.c. + + * gpg.h (ctrl_t): Remove. It is now declared in ../common/util.h. + 2007-06-20 Werner Koch * misc.c (setsysinfo, trap_unaligned): Remove. It is also in Modified: trunk/g10/call-agent.c =================================================================== --- trunk/g10/call-agent.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/g10/call-agent.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -19,10 +19,6 @@ * USA. */ -#if 0 /* let Emacs display a red warning */ -#error fixme: this shares a lot of code with the file in ../sm -#endif - #include #include #include @@ -49,7 +45,6 @@ #endif static assuan_context_t agent_ctx = NULL; -static int force_pipe_server; struct cipher_parm_s { @@ -79,107 +74,18 @@ static int start_agent (void) { - int rc = 0; - char *infostr, *p; - assuan_context_t ctx; - if (agent_ctx) - return 0; /* fixme: We need a context for each thread or serialize + return 0; /* Fixme: We need a context for each thread or serialize the access to the agent. */ - infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO"); - if (!infostr || !*infostr) - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; - - if (opt.verbose) - log_info (_("no running gpg-agent - starting one\n")); - - if (fflush (NULL)) - { - gpg_error_t tmperr = gpg_error_from_syserror (); - log_error ("error flushing pending output: %s\n", strerror (errno)); - return tmperr; - } - - if (!opt.agent_program || !*opt.agent_program) - opt.agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); - if ( !(pgmname = strrchr (opt.agent_program, '/'))) - pgmname = opt.agent_program; - else - pgmname++; - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = log_get_fd (); - no_close_list[i++] = fileno (stderr); - no_close_list[i] = -1; - - /* connect to the agent and perform initial handshaking */ - rc = assuan_pipe_connect (&ctx, opt.agent_program, argv, - no_close_list); - } - else - { - int prot; - int pid; - - infostr = xstrdup (infostr); - if ( !(p = strchr (infostr, ':')) || p == infostr) - { - log_error (_("malformed GPG_AGENT_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_agent (); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != ':') - p++; - prot = *p? atoi (p+1) : 0; - if (prot != 1) - { - log_error (_("gpg-agent protocol version %d is not supported\n"), - prot); - xfree (infostr); - force_pipe_server = 1; - return start_agent (); - } - - rc = assuan_socket_connect (&ctx, infostr, pid); - xfree (infostr); - if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED) - { - log_info (_("can't connect to the agent - trying fall back\n")); - force_pipe_server = 1; - return start_agent (); - } - } - - if (rc) - { - log_error ("can't connect to the agent: %s\n", gpg_strerror (rc)); - return gpg_error (GPG_ERR_NO_AGENT); - } - agent_ctx = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to agent established\n"); - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL,NULL); - if (rc) - return rc; - - return send_pinentry_environment (agent_ctx, GPG_ERR_SOURCE_DEFAULT, - opt.display, opt.ttyname, opt.ttytype, - opt.lc_ctype, opt.lc_messages); + return start_new_gpg_agent (&agent_ctx, + GPG_ERR_SOURCE_DEFAULT, + opt.homedir, + opt.agent_program, + opt.display, opt.ttyname, opt.ttytype, + opt.lc_ctype, opt.lc_messages, + opt.verbose, DBG_ASSUAN, + NULL, NULL); } Modified: trunk/g10/gpg.h =================================================================== --- trunk/g10/gpg.h 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/g10/gpg.h 2007-06-21 18:44:48 UTC (rev 4523) @@ -64,19 +64,11 @@ { struct server_local_s *server_local; }; -typedef struct server_control_s *ctrl_t; -/*-- server.c --*/ -int gpg_server (ctrl_t); - - - - - /* Compatibility stuff to be faded out over time. */ Modified: trunk/g10/main.h =================================================================== --- trunk/g10/main.h 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/g10/main.h 2007-06-21 18:44:48 UTC (rev 4523) @@ -23,10 +23,12 @@ #define G10_MAIN_H #include "types.h" -#include "../common/iobuf.h" +#include "iobuf.h" #include "cipher.h" #include "keydb.h" +#include "util.h" + /* It could be argued that the default cipher should be 3DES rather than CAST5, and the default compression should be 0 (i.e. uncompressed) rather than 1 (zip). However, the real world @@ -300,6 +302,9 @@ void unblock_all_signals(void); +/*-- server.c --*/ +int gpg_server (ctrl_t); + #ifdef ENABLE_CARD_SUPPORT /*-- card-util.c --*/ void change_pin (int no, int allow_admin); Modified: trunk/g10/sign.c =================================================================== --- trunk/g10/sign.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/g10/sign.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -41,6 +41,7 @@ #include "status.h" #include "i18n.h" #include "pkglue.h" +#include "sysutils.h" #include "call-agent.h" Modified: trunk/scd/ChangeLog =================================================================== --- trunk/scd/ChangeLog 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/scd/ChangeLog 2007-06-21 18:44:48 UTC (rev 4523) @@ -1,3 +1,7 @@ +2007-06-21 Werner Koch + + * scdaemon.h (ctrl_t): Remove. It is now declared in ../common/util.h. + 2007-06-18 Marcus Brinkmann * scdaemon.c (main): Percent escape output of --gpgconf-list. Modified: trunk/scd/scdaemon.h =================================================================== --- trunk/scd/scdaemon.h 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/scd/scdaemon.h 2007-06-21 18:44:48 UTC (rev 4523) @@ -116,7 +116,6 @@ } in_data; }; -typedef struct server_control_s *ctrl_t; typedef struct app_ctx_s *app_t; /*-- scdaemon.c --*/ Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/sm/ChangeLog 2007-06-21 18:44:48 UTC (rev 4523) @@ -1,3 +1,15 @@ +2007-06-21 Werner Koch + + * certreqgen-ui.c: New. + * gpgsm.c (main): Let --gen-key call it. + * certreqgen.c (gpgsm_genkey): Add optional IN_STREAM arg and + adjusted caller. + + * gpgsm.h (ctrl_t): Remove. It is now declared in ../common/util.h. + + * call-agent.c (start_agent): Factored almost all code out to + ../common/asshelp.c. + 2007-06-20 Werner Koch * call-agent.c (start_agent) [W32]: Start the agent on the fly. Modified: trunk/sm/Makefile.am =================================================================== --- trunk/sm/Makefile.am 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/sm/Makefile.am 2007-06-21 18:44:48 UTC (rev 4523) @@ -50,6 +50,7 @@ export.c \ delete.c \ certreqgen.c \ + certreqgen-ui.c \ qualified.c Modified: trunk/sm/call-agent.c =================================================================== --- trunk/sm/call-agent.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/sm/call-agent.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -38,12 +38,11 @@ #include "asshelp.h" #include "keydb.h" /* fixme: Move this to import.c */ #include "membuf.h" -#include "exechelp.h" static assuan_context_t agent_ctx = NULL; -static int force_pipe_server = 0; + struct cipher_parm_s { assuan_context_t ctx; @@ -72,161 +71,25 @@ static int start_agent (ctrl_t ctrl) { - int rc = 0; - char *infostr, *p; - assuan_context_t ctx; - if (agent_ctx) return 0; /* fixme: We need a context for each thread or serialize the access to the agent (which is suitable given that the agent is not MT. */ - infostr = force_pipe_server? NULL : getenv ("GPG_AGENT_INFO"); - if (!infostr || !*infostr) - { - char *sockname; - /* First check whether we can connect at the standard - socket. */ - sockname = make_filename (opt.homedir, "S.gpg-agent", NULL); - rc = assuan_socket_connect (&ctx, sockname, 0); + return start_new_gpg_agent (&agent_ctx, + GPG_ERR_SOURCE_DEFAULT, + opt.homedir, + opt.agent_program, + opt.display, opt.ttyname, opt.ttytype, + opt.lc_ctype, opt.lc_messages, + opt.verbose, DBG_ASSUAN, + gpgsm_status2, ctrl); - if (rc) - { - /* With no success start a new server. */ - if (opt.verbose) - log_info (_("no running gpg-agent - starting one\n")); - - gpgsm_status (ctrl, STATUS_PROGRESS, "starting_agent ? 0 0"); - - if (fflush (NULL)) - { - gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); - log_error ("error flushing pending output: %s\n", - strerror (errno)); - xfree (sockname); - return tmperr; - } - - if (!opt.agent_program || !*opt.agent_program) - opt.agent_program = gnupg_module_name (GNUPG_MODULE_NAME_AGENT); - -#ifdef HAVE_W32_SYSTEM - { - /* Under Windows we start the server in daemon mode. This - is because the default is to use the standard socket - and thus there is no need for the GPG_AGENT_INFO - envvar. This is possible as we don't have a real unix - domain socket but use a plain file and thus there is no - need to care about non-local file systems. */ - const char *argv[3]; - - /* The --no-reuse-standard option makes sure that we don't - start a second instance of a agent in case another - process has started one in the meantime. */ - argv[0] = "--daemon"; - argv[1] = "--no-reuse-standard-socket"; - argv[2] = NULL; - - rc = gnupg_spawn_process_detached (opt.agent_program, argv, NULL); - if (rc) - log_debug ("failed to start agent `%s': %s\n", - opt.agent_program, gpg_strerror (rc)); - else - { - /* Give the agent some time to prepare itself. */ - gnupg_sleep (3); - /* Now try again to connect the agent. */ - rc = assuan_socket_connect (&ctx, sockname, 0); - } - } -#else /*!HAVE_W32_SYSTEM*/ - { - const char *pgmname; - const char *argv[3]; - int no_close_list[3]; - int i; - - if ( !(pgmname = strrchr (opt.agent_program, '/'))) - pgmname = opt.agent_program; - else - pgmname++; - - argv[0] = pgmname; - argv[1] = "--server"; - argv[2] = NULL; - - i=0; - if (log_get_fd () != -1) - no_close_list[i++] = log_get_fd (); - no_close_list[i++] = fileno (stderr); - no_close_list[i] = -1; - - /* Connect to the agent and perform initial handshaking. */ - rc = assuan_pipe_connect (&ctx, opt.agent_program, argv, - no_close_list); - } -#endif /*!HAVE_W32_SYSTEM*/ - } - xfree (sockname); - } - else - { - int prot; - int pid; - - infostr = xstrdup (infostr); - if ( !(p = strchr (infostr, PATHSEP_C)) || p == infostr) - { - log_error (_("malformed GPG_AGENT_INFO environment variable\n")); - xfree (infostr); - force_pipe_server = 1; - return start_agent (ctrl); - } - *p++ = 0; - pid = atoi (p); - while (*p && *p != PATHSEP_C) - p++; - prot = *p? atoi (p+1) : 0; - if (prot != 1) - { - log_error (_("gpg-agent protocol version %d is not supported\n"), - prot); - xfree (infostr); - force_pipe_server = 1; - return start_agent (ctrl); - } - - rc = assuan_socket_connect (&ctx, infostr, pid); - xfree (infostr); - if (gpg_err_code (rc) == GPG_ERR_ASS_CONNECT_FAILED) - { - log_info (_("can't connect to the agent - trying fall back\n")); - force_pipe_server = 1; - return start_agent (ctrl); - } - } - - if (rc) - { - log_error ("can't connect to the agent: %s\n", gpg_strerror (rc)); - return gpg_error (GPG_ERR_NO_AGENT); - } - agent_ctx = ctx; - - if (DBG_ASSUAN) - log_debug ("connection to agent established\n"); - - rc = assuan_transact (agent_ctx, "RESET", NULL, NULL, NULL, NULL, NULL, NULL); - if (rc) - return rc; - - return send_pinentry_environment (agent_ctx, GPG_ERR_SOURCE_DEFAULT, - opt.display, opt.ttyname, opt.ttytype, - opt.lc_ctype, opt.lc_messages); } + static int membuf_data_cb (void *opaque, const void *buffer, size_t length) { Added: trunk/sm/certreqgen-ui.c =================================================================== --- trunk/sm/certreqgen-ui.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/sm/certreqgen-ui.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -0,0 +1,317 @@ +/* certreqgen-ui.c - Simple user interface for certreqgen.c + * Copyright (C) 2007 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gpgsm.h" +#include + +#include "i18n.h" +#include "ttyio.h" +#include "membuf.h" + + +/* Prompt for lines and append them to MB. */ +static void +ask_mb_lines (membuf_t *mb, const char *prefix) +{ + char *answer = NULL; + + do + { + xfree (answer); + answer = tty_get ("> "); + tty_kill_prompt (); + trim_spaces (answer); + if (*answer) + { + put_membuf_str (mb, prefix); + put_membuf_str (mb, answer); + put_membuf (mb, "\n", 1); + } + } + while (*answer); + xfree (answer); +} + +/* Helper to store stuff in a membuf. */ +void +store_key_value_lf (membuf_t *mb, const char *key, const char *value) +{ + put_membuf_str (mb, key); + put_membuf_str (mb, value); + put_membuf (mb, "\n", 1); +} + +/* Helper tp store a membuf create by mb_ask_lines into MB. Returns + -1 on error. */ +int +store_mb_lines (membuf_t *mb, membuf_t *lines) +{ + char *p; + + if (get_membuf_len (lines)) + { + put_membuf (lines, "", 1); + p = get_membuf (lines, NULL); + if (!p) + return -1; + put_membuf_str (mb, p); + xfree (p); + } + return 0; +} + + +/* This function is used to create a certificate request from the + command line. In the past the similar gpgsm-gencert.sh script has + been used for it; however that scripts requires a full Unix shell + and thus is not suitable for the Windows port. So here is the + re-implementation. */ +void +gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *output_fp) +{ + gpg_error_t err; + char *answer; + int selection; + FILE *fp = NULL; + int method; + char *keytype; + char *keygrip = NULL; + unsigned int nbits; + int minbits = 1024; + int maxbits = 4096; + int defbits = 2048; + const char *keyusage; + char *subject_name; + membuf_t mb_email, mb_dns, mb_uri, mb_result; + char *result = NULL; + int i; + const char *s, *s2; + + init_membuf (&mb_email, 100); + init_membuf (&mb_dns, 100); + init_membuf (&mb_uri, 100); + init_membuf (&mb_result, 512); + + /* Get the type of the key. */ + tty_printf (_("Please select what kind of key you want:\n")); + tty_printf (_(" (%d) RSA\n"), 1 ); + tty_printf (_(" (%d) Existing key\n"), 2 ); + tty_printf (_(" (%d) Existing key from card\n"), 3 ); + + do + { + answer = tty_get (_("Your selection? ")); + tty_kill_prompt (); + selection = *answer? atoi (answer): 1; + xfree (answer); + } + while (!(selection >= 1 && selection <= 3)); + method = selection; + + /* Get size of the key. */ + if (method == 1) + { + keytype = xstrdup ("RSA"); + for (;;) + { + answer = tty_getf (_("What keysize do you want? (%u) "), defbits); + tty_kill_prompt (); + nbits = *answer? atoi (answer): defbits; + xfree (answer); + if (nbits < minbits || nbits > maxbits) + tty_printf(_("%s keysizes must be in the range %u-%u\n"), + "RSA", minbits, maxbits); + else + break; /* Okay. */ + } + tty_printf (_("Requested keysize is %u bits\n"), nbits); + /* We round it up so that it better matches the word size. */ + if (( nbits % 64)) + { + nbits = ((nbits + 63) / 64) * 64; + tty_printf (_("rounded up to %u bits\n"), nbits); + } + } + else if (method == 2) + { + tty_printf ("Not yet supported; " + "use the gpgsm-gencert.sh script instead\n"); + keytype = xstrdup ("RSA"); + nbits = defbits; /* We need a dummy value. */ + } + else /* method == 3 */ + { + tty_printf ("Not yet supported; " + "use the gpgsm-gencert.sh script instead\n"); + keytype = xstrdup ("card:foobar"); + nbits = defbits; /* We need a dummy value. */ + } + + /* Ask for the key usage. */ + tty_printf (_("Possible actions for a %s key:\n"), "RSA"); + tty_printf (_(" (%d) sign, encrypt\n"), 1 ); + tty_printf (_(" (%d) sign\n"), 2 ); + tty_printf (_(" (%d) encrypt\n"), 3 ); + do + { + answer = tty_get (_("Your selection? ")); + tty_kill_prompt (); + selection = *answer? atoi (answer): 1; + xfree (answer); + switch (selection) + { + case 1: keyusage = "sign, encrypt"; break; + case 2: keyusage = "sign"; break; + case 3: keyusage = "encrypt"; break; + default: keyusage = NULL; break; + } + } + while (!keyusage); + + /* Get the subject name. */ + answer = NULL; + do + { + size_t erroff, errlen; + + xfree (answer); + answer = tty_get (_("Enter the X.509 subject name: ")); + tty_kill_prompt (); + trim_spaces (answer); + if (!*answer) + tty_printf (_("No subject name given\n")); + else if ( (err = ksba_dn_teststr (answer, 0, &erroff, &errlen)) ) + { + if (gpg_err_code (err) == GPG_ERR_UNKNOWN_NAME) + tty_printf (_("Invalid subject name label `%.*s'\n"), + (int)errlen, answer+erroff); + else + { + /* TRANSLATORS: The 22 in the second string is the + length of the first string up to the "%s". Please + adjust it do the length of your translation. The + second string is merely passed to atoi so you can + drop everything after the number. */ + tty_printf (_("Invalid subject name `%s'\n"), answer); + tty_printf ("%*s^\n", + atoi (_("22 translator: see " + "certreg-ui.c:gpgsm_gencertreq_tty")) + + (int)erroff, ""); + } + *answer = 0; + } + } + while (!*answer); + subject_name = answer; + answer = NULL; + + /* Get the email addresses. */ + tty_printf (_("Enter email addresses")); + tty_printf (_(" (end with an empty line):\n")); + ask_mb_lines (&mb_email, "Name-Email: "); + + /* DNS names. */ + tty_printf (_("Enter DNS names")); + tty_printf (_(" (optional; end with an empty line):\n")); + ask_mb_lines (&mb_email, "Name-DNS: "); + + /* URIs. */ + tty_printf (_("Enter URIs")); + tty_printf (_(" (optional; end with an empty line):\n")); + ask_mb_lines (&mb_email, "Name-URI: "); + + + /* Put it all together. */ + store_key_value_lf (&mb_result, "Key-Type: ", keytype); + { + char numbuf[30]; + snprintf (numbuf, sizeof numbuf, "%u", nbits); + store_key_value_lf (&mb_result, "Key-Length: ", numbuf); + } + store_key_value_lf (&mb_result, "Key-Usage: ", keyusage); + store_key_value_lf (&mb_result, "Name-DN: ", subject_name); + if (keygrip) + store_key_value_lf (&mb_result, "Key-Grip: ", keygrip); + if (store_mb_lines (&mb_result, &mb_email)) + goto mem_error; + if (store_mb_lines (&mb_result, &mb_dns)) + goto mem_error; + if (store_mb_lines (&mb_result, &mb_uri)) + goto mem_error; + put_membuf (&mb_result, "", 1); + result = get_membuf (&mb_result, NULL); + if (!result) + goto mem_error; + + tty_printf (_("Parameters to be used for the certificate request:\n")); + for (s=result; (s2 = strchr (s, '\n')); s = s2+1, i++) + tty_printf (" %.*s\n", (int)(s2-s), s); + tty_printf ("\n"); + + + if (!tty_get_answer_is_yes ("Really create request? (y/N) ")) + goto leave; + + /* Now create a parameter file and generate the key. */ + fp = tmpfile (); + if (!fp) + { + log_error (_("error creating temporary file: %s\n"), strerror (errno)); + goto leave; + } + fputs (result, fp); + rewind (fp); + tty_printf (_("Now creating certificate request. " + "This may take a while ...\n")); + { + int save_pem = ctrl->create_pem; + ctrl->create_pem = 1; /* Force creation of PEM. */ + err = gpgsm_genkey (ctrl, -1, fp, output_fp); + ctrl->create_pem = save_pem; + } + if (!err) + tty_printf (_("Ready. You should now send this request to your CA.\n")); + + + goto leave; + mem_error: + log_error (_("resource problem: out or core\n")); + leave: + if (fp) + fclose (fp); + xfree (keytype); + xfree (subject_name); + xfree (keygrip); + xfree (get_membuf (&mb_email, NULL)); + xfree (get_membuf (&mb_dns, NULL)); + xfree (get_membuf (&mb_uri, NULL)); + xfree (get_membuf (&mb_result, NULL)); + xfree (result); +} Modified: trunk/sm/certreqgen.c =================================================================== --- trunk/sm/certreqgen.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/sm/certreqgen.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -831,17 +831,20 @@ -/* Create a new key by reading the parameters from in_fd. Multiple - keys may be created */ +/* Create a new key by reading the parameters from in_fd or in_stream. + Multiple keys may be created */ int -gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *out_fp) +gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *in_stream, FILE *out_fp) { int rc; FILE *in_fp; Base64Context b64writer = NULL; ksba_writer_t writer; - in_fp = fdopen (dup (in_fd), "rb"); + if (in_stream) + in_fp = in_stream; + else + in_fp = fdopen (dup (in_fd), "rb"); if (!in_fp) { gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno)); @@ -877,7 +880,8 @@ leave: gpgsm_destroy_writer (b64writer); - fclose (in_fp); + if (!in_stream) + fclose (in_fp); return rc; } Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/sm/gpgsm.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -1590,12 +1590,15 @@ case aKeygen: /* Generate a key; well kind of. */ - log_error - (_("key generation is not available from the commandline\n")); - log_info (_("please use the script \"%s\" to generate a new key\n"), - "gpgsm-gencert.sh"); + { + FILE *fp = open_fwrite (opt.outfile?opt.outfile:"-"); + gpgsm_gencertreq_tty (&ctrl, fp); + if (fp != stdout) + fclose (fp); + } break; + case aImport: gpgsm_import_files (&ctrl, argc, argv, open_read); break; Modified: trunk/sm/gpgsm.h =================================================================== --- trunk/sm/gpgsm.h 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/sm/gpgsm.h 2007-06-21 18:44:48 UTC (rev 4523) @@ -167,7 +167,6 @@ signer) */ int use_ocsp; /* Set to true if OCSP should be used. */ }; -typedef struct server_control_s *ctrl_t; /* Data structure used in base64.c. */ @@ -317,8 +316,12 @@ int gpgsm_decrypt (ctrl_t ctrl, int in_fd, FILE *out_fp); /*-- certreqgen.c --*/ -int gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *out_fp); +int gpgsm_genkey (ctrl_t ctrl, int in_fd, FILE *in_stream, FILE *out_fp); +/*-- certreqgen-ui.c --*/ +void gpgsm_gencertreq_tty (ctrl_t ctrl, FILE *out_fp); + + /*-- qualified.c --*/ gpg_error_t gpgsm_is_in_qualified_list (ctrl_t ctrl, ksba_cert_t cert, char *country); Modified: trunk/sm/server.c =================================================================== --- trunk/sm/server.c 2007-06-20 11:16:42 UTC (rev 4522) +++ trunk/sm/server.c 2007-06-21 18:44:48 UTC (rev 4523) @@ -865,7 +865,7 @@ out_fp = fdopen ( dup(out_fd), "w"); if (!out_fp) return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed"); - rc = gpgsm_genkey (ctrl, inp_fd, out_fp); + rc = gpgsm_genkey (ctrl, inp_fd, NULL, out_fp); fclose (out_fp); /* close and reset the fds */ From cvs at cvs.gnupg.org Fri Jun 22 13:52:41 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 22 Jun 2007 13:52:41 +0200 Subject: [svn] GnuPG - r4524 - branches/STABLE-BRANCH-1-4/scripts Message-ID: Author: wk Date: 2007-06-22 13:52:12 +0200 (Fri, 22 Jun 2007) New Revision: 4524 Modified: branches/STABLE-BRANCH-1-4/scripts/ChangeLog branches/STABLE-BRANCH-1-4/scripts/mk-w32-dist Log: * mk-w32-dist: Remove underline markup from man pages. Reported by Dirk Traulsen. Modified: branches/STABLE-BRANCH-1-4/scripts/ChangeLog =================================================================== --- branches/STABLE-BRANCH-1-4/scripts/ChangeLog 2007-06-21 18:44:48 UTC (rev 4523) +++ branches/STABLE-BRANCH-1-4/scripts/ChangeLog 2007-06-22 11:52:12 UTC (rev 4524) @@ -1,3 +1,13 @@ +2007-06-22 Werner Koch + + * mk-w32-dist: Remove underline markup from man pages. Reported + by Dirk Traulsen. + +2007-05-03 Werner Koch + + * autogen.sh: Modernized. Removed autopoint invocation. This + should be done by the maintainer and the put into the SVN. + 2006-12-13 Werner Koch * gnupg.spec.in: Distribute gnupg1.info. Modified: branches/STABLE-BRANCH-1-4/scripts/mk-w32-dist =================================================================== --- branches/STABLE-BRANCH-1-4/scripts/mk-w32-dist 2007-06-21 18:44:48 UTC (rev 4523) +++ branches/STABLE-BRANCH-1-4/scripts/mk-w32-dist 2007-06-22 11:52:12 UTC (rev 4524) @@ -127,11 +127,11 @@ cp ${bindir}/doc/$i $i.txt todos $i.txt done -man -Tlatin1 -l ${srcdir}/doc/gpg.1 | sed `printf "s/\b.//g"` >gpg.man +man -Tlatin1 -l ${srcdir}/doc/gpg.1 | sed `printf "s/_\b//g;s/\b.//g"` >gpg.man todos gpg.man -man -Tlatin1 -l ${srcdir}/doc/gpgv.1 | sed `printf "s/\b.//g"` >gpgv.man +man -Tlatin1 -l ${srcdir}/doc/gpgv.1 | sed `printf "s/_\b//g;s/\b.//g"` >gpgv.man todos gpgv.man -man -Tlatin1 -l ${srcdir}/doc/gnupg.7 | sed `printf "s/\b.//g"` >gnupg.man +man -Tlatin1 -l ${srcdir}/doc/gnupg.7 | sed `printf "s/_\b//g;s/\b.//g"` >gnupg.man todos gnupg.man for i in README COPYING NEWS; do cp ${srcdir}/$i $i.txt From cvs at cvs.gnupg.org Mon Jun 25 13:55:17 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Mon, 25 Jun 2007 13:55:17 +0200 Subject: [svn] GnuPG - r4525 - in trunk: . common doc g10 sm Message-ID: Author: wk Date: 2007-06-25 13:54:43 +0200 (Mon, 25 Jun 2007) New Revision: 4525 Modified: trunk/autogen.sh trunk/common/ChangeLog trunk/common/estream-printf.c trunk/common/estream.c trunk/common/estream.h trunk/common/homedir.c trunk/common/iobuf.c trunk/common/iobuf.h trunk/common/sysutils.c trunk/common/sysutils.h trunk/doc/ChangeLog trunk/doc/gpg.texi trunk/g10/ChangeLog trunk/g10/gpg.c trunk/g10/gpgv.c trunk/sm/ChangeLog trunk/sm/certreqgen.c trunk/sm/gpgsm.c Log: Fixed a problem in estream-printf.c. Changes for Windows (gpgsm -k does now work). Minor cleanups. Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/autogen.sh 2007-06-25 11:54:43 UTC (rev 4525) @@ -93,7 +93,7 @@ --with-zlib=${w32root} \ --with-pth-prefix=${w32root} \ --without-included-gettext \ - --disable-regex + --disable-regex "$@" rc=$? exit $rc fi Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/common/ChangeLog 2007-06-25 11:54:43 UTC (rev 4525) @@ -1,3 +1,45 @@ +2007-06-25 Werner Koch + + * sysutils.c (translate_sys2libc_fd): New using the code from iobuf.c. + * iobuf.c: Include sysutils.h. + (iobuf_translate_file_handle): Remove. + (translate_file_handle): Use new function. + + * estream-printf.c [TEST]: Header including fixes. + (do_format): Do not append a trailing Nul. This avoids spurious + Nuls in the es_printf output. + (estream_vsnprintf, estream_vasprintf): Take this in account. + + * estream.h (struct es__stream): Change FLAGS to a bit structure. + (ES__FLAG_WRITING): Replace by a bit from FLAGS. * estream.c + (struct estream_internal): Rename FLAGS to MODEFLAGS so that they + are not confused with the estream flags. + (es_initialize, es_create): Add arg MODEFLAGS so that we can setup + the intial writemode. Changed all callers to pass them. + (es_convert_mode): Set O_BINARY. + (es_func_fd_create, es_func_fp_create, es_func_file_create) [W32]: + Call setmode if requested. + +2007-06-24 Werner Koch + + * estream.c (do_fpopen, es_fpopen, es_fpopen_nc): New. + (es_func_fp_create, es_func_fp_read, es_func_fp_write) + (es_func_fp_seek, es_func_fp_destroy): New. + +2007-06-22 Werner Koch + + * estream.c (es_fdopen): Factored code out to.. + (do_fdopen): .. new. + (es_fdopen_nc): New. + (estream_cookie_fd): Add field NO_CLOSE. + (es_func_fd_create): Add arg NO_CLOSE and changed all callers. + (es_func_fd_destroy): Handle the new flag. + + * homedir.c (gnupg_libexecdir) [W32]: Factor code out to .. + (w32_rootdir): .. new. + (gnupg_sysconfdir, gnupg_libdir, gnupg_datadir) [W32]: Return + name based on w32_rootdir(). + 2007-06-21 Werner Koch * membuf.h (get_membuf_len): New. Modified: trunk/common/estream-printf.c =================================================================== --- trunk/common/estream-printf.c 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/common/estream-printf.c 2007-06-25 11:54:43 UTC (rev 4525) @@ -60,19 +60,20 @@ #endif #ifdef TEST # include +#else +# ifdef _ESTREAM_PRINTF_EXTRA_INCLUDE +# include _ESTREAM_PRINTF_EXTRA_INCLUDE +# endif #endif -#ifdef _ESTREAM_PRINTF_EXTRA_INCLUDE -#include _ESTREAM_PRINTF_EXTRA_INCLUDE -#endif #include "estream-printf.h" /* Allow redefinition of asprintf used malloc functions. */ -#ifdef _ESTREAM_PRINTF_MALLOC +#if defined(_ESTREAM_PRINTF_MALLOC) && !defined(TEST) #define my_printf_malloc(a) _ESTREAM_PRINTF_MALLOC((a)) #else #define my_printf_malloc(a) malloc((a)) #endif -#ifdef _ESTREAM_PRINTF_FREE +#if defined(_ESTREAM_PRINTF_FREE) && !defined(TEST) #define my_printf_free(a) _ESTREAM_PRINTF_FREE((a)) #else #define my_printf_free(a) free((a)) @@ -1329,7 +1330,7 @@ /* Run the actual formatting. OUTFNC and OUTFNCARG are the output functions. FORMAT is format string ARGSPECS is the parsed format string, ARGSPECS_LEN the number of items in ARGSPECS. VALUETABLE - holds the values and may be directly addressed using the poistion + holds the values and may be directly addressed using the position arguments given by ARGSPECS. MYERRNO is used for the "%m" conversion. NBYTES well be updated to reflect the number of bytes send to the output function. */ @@ -1449,8 +1450,8 @@ } /* Print out any trailing stuff. */ - s++; /* Need to output a terminating nul; take it from format. */ - rc = outfnc (outfncarg, format, (n=s - format)); + n = s - format; + rc = n? outfnc (outfncarg, format, n) : 0; if (!rc) *nbytes += n; @@ -1619,10 +1620,8 @@ { FILE *fp = (FILE*)outfncarg; - fputs ("OUT->", fp); if ( fwrite (buf, buflen, 1, fp) != 1 ) return -1; - fputs ("<-\n", fp); return 0; } @@ -1715,6 +1714,8 @@ parm.used = 0; parm.buffer = bufsize?buf:NULL; rc = estream_format (fixed_buffer_out, &parm, format, arg_ptr); + if (!rc) + rc = fixed_buffer_out (&parm, "", 1); /* Print terminating Nul. */ if (rc == -1) return -1; if (bufsize && buf && parm.count >= parm.size) @@ -1807,7 +1808,9 @@ } rc = estream_format (dynamic_buffer_out, &parm, format, arg_ptr); - + if (!rc) + rc = dynamic_buffer_out (&parm, "", 1); /* Print terminating Nul. */ + /* Fixme: Should we shrink the resulting buffer? */ if (rc != -1 && parm.error_flag) { rc = -1; @@ -1820,9 +1823,9 @@ *bufp = NULL; return -1; } - + assert (parm.used); /* We have at least the terminating Nul. */ *bufp = parm.buffer; - return parm.used - 1; /* Do not include the nul. */ + return parm.used - 1; /* Do not include that Nul. */ } /* A replacement for asprintf. As with the BSD of asprintf version -1 @@ -1891,8 +1894,7 @@ static void run_tests (void) { -#if 0 - one_test ("%d %% %'d", 17, 19681977); + /*one_test ("%d %% %'d", 17, 19681977);*/ one_test ("%d %% %d", 17, 768114563); one_test ("%d %% %d", 17, -768114563); @@ -2011,8 +2013,9 @@ one_test ("%50s", "the quick brown fox jumps over the lazy dogs back"); one_test ("%51s", "the quick brown fox jumps over the lazy dogs back"); one_test ("%-51s", "the quick brown fox jumps over the lazy dogs back"); -#endif + one_test ("/%s=", "CN"); + one_test ("%f", 3.1415926535); one_test ("%f", -3.1415926535); one_test ("%.10f", 3.1415926535); Modified: trunk/common/estream.c =================================================================== --- trunk/common/estream.c 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/common/estream.c 2007-06-25 11:54:43 UTC (rev 4525) @@ -67,6 +67,10 @@ +#ifndef O_BINARY +#define O_BINARY 0 +#endif + /* Generally used types. */ typedef void *(*func_realloc_t) (void *mem, size_t size); @@ -139,8 +143,6 @@ #define ES_DEFAULT_OPEN_MODE (S_IRUSR | S_IWUSR) -#define ES_FLAG_WRITING ES__FLAG_WRITING - /* An internal stream object. */ struct estream_internal @@ -148,9 +150,9 @@ unsigned char buffer[BUFFER_BLOCK_SIZE]; unsigned char unread_buffer[BUFFER_UNREAD_SIZE]; estream_mutex_t lock; /* Lock. */ - void *cookie; /* Cookie. */ - void *opaque; /* Opaque data. */ - unsigned int flags; /* Flags. */ + void *cookie; /* Cookie. */ + void *opaque; /* Opaque data. */ + unsigned int modeflags; /* Flags for the backend. */ off_t offset; es_cookie_read_function_t func_read; es_cookie_write_function_t func_write; @@ -325,7 +327,7 @@ /* Cookie for memory objects. */ typedef struct estream_cookie_mem { - unsigned int flags; /* Open flags. */ + unsigned int modeflags; /* Open flags. */ unsigned char *memory; /* Data. */ size_t memory_size; /* Size of MEMORY. */ size_t offset; /* Current offset in MEMORY. */ @@ -349,7 +351,7 @@ unsigned int append_zero, unsigned int dont_free, char **ptr, size_t *size, func_realloc_t func_realloc, func_free_t func_free, - unsigned int flags) + unsigned int modeflags) { estream_cookie_mem_t mem_cookie; int err; @@ -359,7 +361,7 @@ err = -1; else { - mem_cookie->flags = flags; + mem_cookie->modeflags = modeflags; mem_cookie->memory = data; mem_cookie->memory_size = data_n; mem_cookie->offset = 0; @@ -416,7 +418,7 @@ { /* Regular write. */ - if (mem_cookie->flags & O_APPEND) + if (mem_cookie->modeflags & O_APPEND) /* Append to data. */ mem_cookie->offset = mem_cookie->data_len; @@ -593,17 +595,20 @@ es_func_mem_destroy }; + + /* Implementation of fd I/O. */ /* Cookie for fd objects. */ typedef struct estream_cookie_fd { - int fd; + int fd; /* The file descriptor we are using for actual output. */ + int no_close; /* If set we won't close the file descriptor. */ } *estream_cookie_fd_t; /* Create function for fd objects. */ static int -es_func_fd_create (void **cookie, int fd, unsigned int flags) +es_func_fd_create (void **cookie, int fd, unsigned int modeflags, int no_close) { estream_cookie_fd_t fd_cookie; int err; @@ -613,7 +618,13 @@ err = -1; else { +#ifdef HAVE_DOSISH_SYSTEM + /* Make sure it is in binary mode if requested. */ + if ( (modeflags & O_BINARY) ) + setmode (fd, O_BINARY); +#endif fd_cookie->fd = fd; + fd_cookie->no_close = no_close; *cookie = fd_cookie; err = 0; } @@ -680,7 +691,7 @@ if (fd_cookie) { - err = close (fd_cookie->fd); + err = fd_cookie->no_close? 0 : close (fd_cookie->fd); ES_MEM_FREE (fd_cookie); } else @@ -689,6 +700,7 @@ return err; } + static es_cookie_io_functions_t estream_functions_fd = { es_func_fd_read, @@ -697,12 +709,132 @@ es_func_fd_destroy }; + + + +/* Implementation of FILE* I/O. */ + +/* Cookie for fp objects. */ +typedef struct estream_cookie_fp +{ + FILE *fp; /* The file pointer we are using for actual output. */ + int no_close; /* If set we won't close the file pointer. */ +} *estream_cookie_fp_t; + +/* Create function for fd objects. */ +static int +es_func_fp_create (void **cookie, FILE *fp, unsigned int modeflags, int no_close) +{ + estream_cookie_fp_t fp_cookie; + int err; + + fp_cookie = ES_MEM_ALLOC (sizeof *fp_cookie); + if (!fp_cookie) + err = -1; + else + { +#ifdef HAVE_DOSISH_SYSTEM + /* Make sure it is in binary mode if requested. */ + if ( (modeflags & O_BINARY) ) + setmode (fileno (fp), O_BINARY); +#endif + fp_cookie->fp = fp; + fp_cookie->no_close = no_close; + *cookie = fp_cookie; + err = 0; + } + + return err; +} + +/* Read function for FILE* objects. */ +static ssize_t +es_func_fp_read (void *cookie, void *buffer, size_t size) + +{ + estream_cookie_fp_t file_cookie = cookie; + ssize_t bytes_read; + + bytes_read = fread (buffer, 1, size, file_cookie->fp); + if (!bytes_read && ferror (file_cookie->fp)) + return -1; + return bytes_read; +} + +/* Write function for FILE* objects. */ +static ssize_t +es_func_fp_write (void *cookie, const void *buffer, size_t size) + +{ + estream_cookie_fp_t file_cookie = cookie; + size_t bytes_written; + + bytes_written = fwrite (buffer, 1, size, file_cookie->fp); + if (bytes_written != size) + return -1; + return bytes_written; +} + +/* Seek function for FILE* objects. */ +static int +es_func_fp_seek (void *cookie, off_t *offset, int whence) +{ + estream_cookie_fp_t file_cookie = cookie; + long int offset_new; + + if ( fseek (file_cookie->fp, (long int)*offset, whence) ) + { + fprintf (stderr, "\nfseek failed: errno=%d (%s)\n", errno,strerror (errno)); + return -1; + } + + offset_new = ftell (file_cookie->fp); + if (offset_new == -1) + { + fprintf (stderr, "\nftell failed: errno=%d (%s)\n", errno,strerror (errno)); + return -1; + } + *offset = offset_new; + return 0; +} + +/* Destroy function for fd objects. */ +static int +es_func_fp_destroy (void *cookie) +{ + estream_cookie_fp_t fp_cookie = cookie; + int err; + + if (fp_cookie) + { + fflush (fp_cookie->fp); + err = fp_cookie->no_close? 0 : fclose (fp_cookie->fp); + ES_MEM_FREE (fp_cookie); + } + else + err = 0; + + return err; +} + + +static es_cookie_io_functions_t estream_functions_fp = + { + es_func_fp_read, + es_func_fp_write, + es_func_fp_seek, + es_func_fp_destroy + }; + + + + /* Implementation of file I/O. */ /* Create function for file objects. */ static int es_func_file_create (void **cookie, int *filedes, - const char *path, unsigned int flags) + const char *path, unsigned int modeflags) { estream_cookie_fd_t file_cookie; int err; @@ -718,12 +850,17 @@ goto out; } - fd = open (path, flags, ES_DEFAULT_OPEN_MODE); + fd = open (path, modeflags, ES_DEFAULT_OPEN_MODE); if (fd == -1) { err = -1; goto out; } +#ifdef HAVE_DOSISH_SYSTEM + /* Make sure it is in binary mode if requested. */ + if ( (modeflags & O_BINARY) ) + setmode (fd, O_BINARY); +#endif file_cookie->fd = fd; *cookie = file_cookie; @@ -750,16 +887,10 @@ /* Stream primitives. */ static int -es_convert_mode (const char *mode, unsigned int *flags) +es_convert_mode (const char *mode, unsigned int *modeflags) { - /* FIXME: We need to allow all mode flags permutations and for - binary mode we need to do a - - #ifdef HAVE_DOSISH_SYSTEM - setmode (fd, O_BINARY); - #endif - */ + /* FIXME: We need to allow all mode flags permutations. */ struct { const char *mode; @@ -767,33 +898,34 @@ } mode_flags[] = { { "r", O_RDONLY }, { "rb", - O_RDONLY }, + O_RDONLY | O_BINARY }, { "w", O_WRONLY | O_TRUNC | O_CREAT }, { "wb", - O_WRONLY | O_TRUNC | O_CREAT }, + O_WRONLY | O_TRUNC | O_CREAT | O_BINARY }, { "a", O_WRONLY | O_APPEND | O_CREAT }, { "ab", - O_WRONLY | O_APPEND | O_CREAT }, + O_WRONLY | O_APPEND | O_CREAT | O_BINARY }, { "r+", O_RDWR }, { "rb+", - O_RDWR }, + O_RDWR | O_BINARY }, { "r+b", - O_RDONLY | O_WRONLY }, + O_RDONLY | O_WRONLY | O_BINARY }, { "w+", O_RDWR | O_TRUNC | O_CREAT }, { "wb+", - O_RDWR | O_TRUNC | O_CREAT }, + O_RDWR | O_TRUNC | O_CREAT | O_BINARY }, { "w+b", - O_RDWR | O_TRUNC | O_CREAT }, + O_RDWR | O_TRUNC | O_CREAT | O_BINARY }, { "a+", O_RDWR | O_CREAT | O_APPEND }, { "ab+", - O_RDWR | O_CREAT | O_APPEND }, + O_RDWR | O_CREAT | O_APPEND | O_BINARY }, { "a+b", - O_RDWR | O_CREAT | O_APPEND } }; + O_RDWR | O_CREAT | O_APPEND | O_BINARY } + }; unsigned int i; int err; @@ -808,7 +940,7 @@ else { err = 0; - *flags = mode_flags[i].flags; + *modeflags = mode_flags[i].flags; } return err; @@ -868,7 +1000,7 @@ es_cookie_write_function_t func_write = stream->intern->func_write; int err; - assert (stream->flags & ES_FLAG_WRITING); + assert (stream->flags.writing); if (stream->data_offset) { @@ -935,7 +1067,7 @@ static void es_empty (estream_t stream) { - assert (! (stream->flags & ES_FLAG_WRITING)); + assert (!stream->flags.writing); stream->data_len = 0; stream->data_offset = 0; stream->unread_data_len = 0; @@ -944,7 +1076,8 @@ /* Initialize STREAM. */ static void es_initialize (estream_t stream, - void *cookie, int fd, es_cookie_io_functions_t functions) + void *cookie, int fd, es_cookie_io_functions_t functions, + unsigned int modeflags) { stream->intern->cookie = cookie; stream->intern->opaque = NULL; @@ -967,7 +1100,15 @@ stream->data_offset = 0; stream->data_flushed = 0; stream->unread_data_len = 0; - stream->flags = 0; + /* Depending on the modeflags we set whether we start in writing or + reading mode. This is required in case we are working on a + wronly stream which is not seeekable (like stdout). Without this + pre-initialization we would do a seek at the first write call and + as this will fail no utput will be delivered. */ + if ((modeflags & O_WRONLY) || (modeflags & O_RDWR) ) + stream->flags.writing = 1; + else + stream->flags.writing = 0; } /* Deinitialize STREAM. */ @@ -988,7 +1129,7 @@ func_close = stream->intern->func_close; err = 0; - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) SET_UNLESS_NONZERO (err, tmp_err, es_flush (stream)); if (func_close) SET_UNLESS_NONZERO (err, tmp_err, (*func_close) (stream->intern->cookie)); @@ -1000,7 +1141,7 @@ /* Create a new stream object, initialize it. */ static int es_create (estream_t *stream, void *cookie, int fd, - es_cookie_io_functions_t functions) + es_cookie_io_functions_t functions, unsigned int modeflags) { estream_internal_t stream_internal_new; estream_t stream_new; @@ -1030,7 +1171,7 @@ stream_new->intern = stream_internal_new; ESTREAM_MUTEX_INITIALIZE (stream_new->intern->lock); - es_initialize (stream_new, cookie, fd, functions); + es_initialize (stream_new, cookie, fd, functions, modeflags); err = es_list_add (stream_new); if (err) @@ -1186,13 +1327,13 @@ data_read = 0; err = 0; - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) { /* Switching to reading mode -> flush output. */ err = es_flush (stream); if (err) goto out; - stream->flags &= ~ES_FLAG_WRITING; + stream->flags.writing = 0; } /* Read unread data first. */ @@ -1274,14 +1415,14 @@ goto out; } - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) { /* Flush data first in order to prevent flushing it to the wrong offset. */ err = es_flush (stream); if (err) goto out; - stream->flags &= ~ES_FLAG_WRITING; + stream->flags.writing = 0; } off = offset; @@ -1451,7 +1592,7 @@ data_written = 0; err = 0; - if (! (stream->flags & ES_FLAG_WRITING)) + if (!stream->flags.writing) { /* Switching to writing mode -> discard input data and seek to position at which reading has stopped. We can do this only @@ -1489,8 +1630,8 @@ if (bytes_written) *bytes_written = data_written; if (data_written) - if (! (stream->flags & ES_FLAG_WRITING)) - stream->flags |= ES_FLAG_WRITING; + if (!stream->flags.writing) + stream->flags.writing = 1; return err; } @@ -1502,13 +1643,13 @@ { int err; - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) { /* Switching to reading mode -> flush output. */ err = es_flush (stream); if (err) goto out; - stream->flags &= ~ES_FLAG_WRITING; + stream->flags.writing = 0; } if (stream->data_offset == stream->data_len) @@ -1572,12 +1713,13 @@ line_stream_cookie = NULL; err = es_func_mem_create (&line_stream_cookie, NULL, 0, 0, BUFFER_BLOCK_SIZE, - 1, 0, 0, NULL, 0, ES_MEM_REALLOC, ES_MEM_FREE, O_RDWR); + 1, 0, 0, NULL, 0, ES_MEM_REALLOC, ES_MEM_FREE, + O_RDWR); if (err) goto out; err = es_create (&line_stream, line_stream_cookie, -1, - estream_functions_mem); + estream_functions_mem, O_RDWR); if (err) goto out; @@ -1738,7 +1880,7 @@ int err; /* Flush or empty buffer depending on mode. */ - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) { err = es_flush (stream); if (err) @@ -1839,7 +1981,7 @@ estream_t es_fopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode) { - unsigned int flags; + unsigned int modeflags; int create_called; estream_t stream; void *cookie; @@ -1850,16 +1992,16 @@ cookie = NULL; create_called = 0; - err = es_convert_mode (mode, &flags); + err = es_convert_mode (mode, &modeflags); if (err) goto out; - err = es_func_file_create (&cookie, &fd, path, flags); + err = es_func_file_create (&cookie, &fd, path, modeflags); if (err) goto out; create_called = 1; - err = es_create (&stream, cookie, fd, estream_functions_file); + err = es_create (&stream, cookie, fd, estream_functions_file, modeflags); if (err) goto out; @@ -1878,7 +2020,7 @@ func_realloc_t func_realloc, func_free_t func_free, const char *ES__RESTRICT mode) { - unsigned int flags; + unsigned int modeflags; int create_called; estream_t stream; void *cookie; @@ -1888,18 +2030,18 @@ stream = NULL; create_called = 0; - err = es_convert_mode (mode, &flags); + err = es_convert_mode (mode, &modeflags); if (err) goto out; err = es_func_mem_create (&cookie, data, data_n, data_len, BUFFER_BLOCK_SIZE, grow, 0, 0, - NULL, 0, func_realloc, func_free, flags); + NULL, 0, func_realloc, func_free, modeflags); if (err) goto out; create_called = 1; - err = es_create (&stream, cookie, -1, estream_functions_mem); + err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags); out: @@ -1913,25 +2055,25 @@ estream_t es_open_memstream (char **ptr, size_t *size) { - unsigned int flags; + unsigned int modeflags; int create_called; estream_t stream; void *cookie; int err; - flags = O_RDWR; + modeflags = O_RDWR; create_called = 0; stream = NULL; cookie = 0; err = es_func_mem_create (&cookie, NULL, 0, 0, BUFFER_BLOCK_SIZE, 1, 1, 1, - ptr, size, ES_MEM_REALLOC, ES_MEM_FREE, flags); + ptr, size, ES_MEM_REALLOC, ES_MEM_FREE, modeflags); if (err) goto out; create_called = 1; - err = es_create (&stream, cookie, -1, estream_functions_mem); + err = es_create (&stream, cookie, -1, estream_functions_mem, modeflags); out: @@ -1947,18 +2089,18 @@ const char *ES__RESTRICT mode, es_cookie_io_functions_t functions) { - unsigned int flags; + unsigned int modeflags; estream_t stream; int err; stream = NULL; - flags = 0; + modeflags = 0; - err = es_convert_mode (mode, &flags); + err = es_convert_mode (mode, &modeflags); if (err) goto out; - err = es_create (&stream, cookie, -1, functions); + err = es_create (&stream, cookie, -1, functions, modeflags); if (err) goto out; @@ -1969,9 +2111,9 @@ estream_t -es_fdopen (int filedes, const char *mode) +do_fdopen (int filedes, const char *mode, int no_close) { - unsigned int flags; + unsigned int modeflags; int create_called; estream_t stream; void *cookie; @@ -1981,16 +2123,16 @@ cookie = NULL; create_called = 0; - err = es_convert_mode (mode, &flags); + err = es_convert_mode (mode, &modeflags); if (err) goto out; - err = es_func_fd_create (&cookie, filedes, flags); + err = es_func_fd_create (&cookie, filedes, modeflags, no_close); if (err) goto out; create_called = 1; - err = es_create (&stream, cookie, filedes, estream_functions_fd); + err = es_create (&stream, cookie, filedes, estream_functions_fd, modeflags); out: @@ -1999,9 +2141,80 @@ return stream; } + +estream_t +es_fdopen (int filedes, const char *mode) +{ + return do_fdopen (filedes, mode, 0); +} + +/* A variant of es_fdopen which does not close FILEDES at the end. */ +estream_t +es_fdopen_nc (int filedes, const char *mode) +{ + return do_fdopen (filedes, mode, 1); +} + + +estream_t +do_fpopen (FILE *fp, const char *mode, int no_close) +{ + unsigned int modeflags; + int create_called; + estream_t stream; + void *cookie; + int err; + + stream = NULL; + cookie = NULL; + create_called = 0; + + err = es_convert_mode (mode, &modeflags); + if (err) + goto out; + + fflush (fp); + err = es_func_fp_create (&cookie, fp, modeflags, no_close); + if (err) + goto out; + + create_called = 1; + err = es_create (&stream, cookie, fileno (fp), estream_functions_fp, + modeflags); + + out: + + if (err && create_called) + (*estream_functions_fp.func_close) (cookie); + + return stream; +} + +/* Create an estream from the stdio stream FP. This mechanism is + useful in case the stdio streams have special properties and may + not be mixed with fd based functions. This is for example the case + under Windows where the 3 standard streams are associated with the + console whereas a duped and fd-opened stream of one of this stream + won't be associated with the console. As this messes things up it + is easier to keep on using the standard I/O stream as a backend for + estream. */ +estream_t +es_fpopen (FILE *fp, const char *mode) +{ + return do_fpopen (fp, mode, 0); +} + +/* Same as es_fpopen but does not close FP at the end. */ estream_t +es_fpopen_nc (FILE *fp, const char *mode) +{ + return do_fpopen (fp, mode, 1); +} + + +estream_t es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode, estream_t ES__RESTRICT stream) { @@ -2009,7 +2222,7 @@ if (path) { - unsigned int flags; + unsigned int modeflags; int create_called; void *cookie; int fd; @@ -2021,16 +2234,16 @@ es_deinitialize (stream); - err = es_convert_mode (mode, &flags); + err = es_convert_mode (mode, &modeflags); if (err) goto leave; - err = es_func_file_create (&cookie, &fd, path, flags); + err = es_func_file_create (&cookie, &fd, path, modeflags); if (err) goto leave; create_called = 1; - es_initialize (stream, cookie, fd, estream_functions_file); + es_initialize (stream, cookie, fd, estream_functions_file, modeflags); leave: @@ -2173,7 +2386,7 @@ if (stream) { ESTREAM_LOCK (stream); - if (stream->flags & ES_FLAG_WRITING) + if (stream->flags.writing) err = es_flush (stream); else { @@ -2686,7 +2899,7 @@ estream_t es_tmpfile (void) { - unsigned int flags; + unsigned int modeflags; int create_called; estream_t stream; void *cookie; @@ -2695,7 +2908,7 @@ create_called = 0; stream = NULL; - flags = O_RDWR | O_TRUNC | O_CREAT; + modeflags = O_RDWR | O_TRUNC | O_CREAT; cookie = NULL; fd = tmpfd (); @@ -2705,12 +2918,12 @@ goto out; } - err = es_func_fd_create (&cookie, fd, flags); + err = es_func_fd_create (&cookie, fd, modeflags, 0); if (err) goto out; create_called = 1; - err = es_create (&stream, cookie, fd, estream_functions_fd); + err = es_create (&stream, cookie, fd, estream_functions_fd, modeflags); out: Modified: trunk/common/estream.h =================================================================== --- trunk/common/estream.h 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/common/estream.h 2007-06-25 11:54:43 UTC (rev 4525) @@ -45,6 +45,9 @@ #define es_mopen _ESTREAM_PREFIX(es_mopen) #define es_open_memstream _ESTREAM_PREFIX(es_open_memstream) #define es_fdopen _ESTREAM_PREFIX(es_fdopen) +#define es_fdopen_nc _ESTREAM_PREFIX(es_fdopen_nc) +#define es_fpopen _ESTREAM_PREFIX(es_fpopen) +#define es_fpopen_nc _ESTREAM_PREFIX(es_fpopen_nc) #define es_freopen _ESTREAM_PREFIX(es_freopen) #define es_fopencookie _ESTREAM_PREFIX(es_fopencookie) #define es_fclose _ESTREAM_PREFIX(es_fclose) @@ -136,8 +139,10 @@ size_t unread_data_len; /* Various flags. */ -#define ES__FLAG_WRITING (1 << 0) - unsigned int flags; + struct { + unsigned int writing: 1; + unsigned int reserved: 7; + } flags; /* A pointer to our internal data for this stream. */ struct estream_internal *intern; @@ -197,6 +202,9 @@ const char *ES__RESTRICT mode); estream_t es_open_memstream (char **ptr, size_t *size); estream_t es_fdopen (int filedes, const char *mode); +estream_t es_fdopen_nc (int filedes, const char *mode); +estream_t es_fpopen (FILE *fp, const char *mode); +estream_t es_fpopen_nc (FILE *fp, const char *mode); estream_t es_freopen (const char *ES__RESTRICT path, const char *ES__RESTRICT mode, estream_t ES__RESTRICT stream); @@ -232,14 +240,14 @@ int _es_putc_overflow (int c, estream_t stream); #define es_getc_unlocked(stream) \ - (((! ((stream)->flags & 1)) \ + (((!(stream)->flags.writing) \ && ((stream)->data_offset < (stream)->data_len) \ && (! (stream)->unread_data_len)) \ ? ((int) (stream)->buffer[((stream)->data_offset)++]) \ : _es_getc_underflow ((stream))) #define es_putc_unlocked(c, stream) \ - ((((stream)->flags & 1) \ + (((stream)->flags.writing \ && ((stream)->data_offset < (stream)->buffer_size) \ && (c != '\n')) \ ? ((int) ((stream)->buffer[((stream)->data_offset)++] = (c))) \ Modified: trunk/common/homedir.c =================================================================== --- trunk/common/homedir.c 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/common/homedir.c 2007-06-25 11:54:43 UTC (rev 4525) @@ -126,38 +126,10 @@ } -/* Return the name of the sysconfdir. This is a static string. This - function is required because under Windows we can't simply compile - it in. */ -const char * -gnupg_sysconfdir (void) -{ #ifdef HAVE_W32_SYSTEM -#warning get the sysconfdir from somewhere else - return GNUPG_SYSCONFDIR; -#else /*!HAVE_W32_SYSTEM*/ - return GNUPG_SYSCONFDIR; -#endif /*!HAVE_W32_SYSTEM*/ -} - - -const char * -gnupg_bindir (void) +static const char * +w32_rootdir (void) { -#ifdef HAVE_W32_SYSTEM - return gnupg_libexecdir (); -#else /*!HAVE_W32_SYSTEM*/ - return GNUPG_BINDIR; -#endif /*!HAVE_W32_SYSTEM*/ -} - - -/* Return the name of the libexec directory. The name is allocated in - a static area on the first use. This function won't fail. */ -const char * -gnupg_libexecdir (void) -{ -#ifdef HAVE_W32_SYSTEM static int got_dir; static char dir[MAX_PATH+5]; @@ -184,17 +156,75 @@ if (*dir) return dir; /* Fallback to the hardwired value. */ + return GNUPG_LIBEXECDIR; +} #endif /*HAVE_W32_SYSTEM*/ + + + +/* Return the name of the sysconfdir. This is a static string. This + function is required because under Windows we can't simply compile + it in. */ +const char * +gnupg_sysconfdir (void) +{ +#ifdef HAVE_W32_SYSTEM + static char *name; + + if (!name) + { + const char *s1, *s2; + s1 = w32_rootdir (); + s2 = DIRSEP_S "etc" DIRSEP_S "gnupg"; + name = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (stpcpy (name, s1), s2); + } + return name; +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_SYSCONFDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +const char * +gnupg_bindir (void) +{ +#ifdef HAVE_W32_SYSTEM + return w32_rootdir (); +#else /*!HAVE_W32_SYSTEM*/ + return GNUPG_BINDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + + +/* Return the name of the libexec directory. The name is allocated in + a static area on the first use. This function won't fail. */ +const char * +gnupg_libexecdir (void) +{ +#ifdef HAVE_W32_SYSTEM + return w32_rootdir (); +#else /*!HAVE_W32_SYSTEM*/ return GNUPG_LIBEXECDIR; +#endif /*!HAVE_W32_SYSTEM*/ } const char * gnupg_libdir (void) { #ifdef HAVE_W32_SYSTEM -#warning get the libdir from somewhere else - return GNUPG_LIBDIR; + static char *name; + + if (!name) + { + const char *s1, *s2; + s1 = w32_rootdir (); + s2 = DIRSEP_S "lib" DIRSEP_S "gnupg"; + name = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (stpcpy (name, s1), s2); + } + return name; #else /*!HAVE_W32_SYSTEM*/ return GNUPG_LIBDIR; #endif /*!HAVE_W32_SYSTEM*/ @@ -204,8 +234,17 @@ gnupg_datadir (void) { #ifdef HAVE_W32_SYSTEM -#warning get the datadir from somewhere else - return GNUPG_DATADIR; + static char *name; + + if (!name) + { + const char *s1, *s2; + s1 = w32_rootdir (); + s2 = DIRSEP_S "share" DIRSEP_S "gnupg"; + name = xmalloc (strlen (s1) + strlen (s2) + 1); + strcpy (stpcpy (name, s1), s2); + } + return name; #else /*!HAVE_W32_SYSTEM*/ return GNUPG_DATADIR; #endif /*!HAVE_W32_SYSTEM*/ Modified: trunk/common/iobuf.c =================================================================== --- trunk/common/iobuf.c 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/common/iobuf.c 2007-06-25 11:54:43 UTC (rev 4525) @@ -40,6 +40,7 @@ #endif /* __riscos__ */ #include "util.h" +#include "sysutils.h" #include "iobuf.h" /* The size of the internal buffers. @@ -2350,37 +2351,12 @@ return nbytes; } -/* This is the non iobuf specific function */ -int -iobuf_translate_file_handle (int fd, int for_write) -{ -#ifdef _WIN32 - { - int x; - - if (fd <= 2) - return fd; /* do not do this for error, stdin, stdout, stderr */ - - x = _open_osfhandle (fd, for_write ? 1 : 0); - if (x == -1) - log_error ("failed to translate osfhandle %p\n", (void *) fd); - else - { - /*log_info ("_open_osfhandle %p yields %d%s\n", - (void*)fd, x, for_write? " for writing":"" ); */ - fd = x; - } - } -#endif - return fd; -} - static int translate_file_handle (int fd, int for_write) { #ifdef _WIN32 #ifdef FILE_FILTER_USES_STDIO - fd = iobuf_translate_file_handle (fd, for_write); + fd = translate_sys2libc_fd (fd, for_write); #else { int x; Modified: trunk/common/iobuf.h =================================================================== --- trunk/common/iobuf.h 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/common/iobuf.h 2007-06-25 11:54:43 UTC (rev 4525) @@ -136,8 +136,6 @@ void iobuf_set_partial_block_mode (iobuf_t a, size_t len); -int iobuf_translate_file_handle (int fd, int for_write); - void iobuf_skip_rest (iobuf_t a, unsigned long n, int partial); Modified: trunk/common/sysutils.c =================================================================== --- trunk/common/sysutils.c 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/common/sysutils.c 2007-06-25 11:54:43 UTC (rev 4525) @@ -272,3 +272,32 @@ # endif #endif } + + +/* This function is a NOP for POSIX systems but required under Windows + as the file handles as returned by OS calls (like CreateFile) are + different from the libc file descriptors (like open). This function + translates system file handles to libc file handles. FOR_WRITE + gives the direction of the handle. */ +int +translate_sys2libc_fd (int fd, int for_write) +{ +#ifdef HAVE_W32_SYSTEM + int x; + + if (fd <= 2) + return fd; /* Do not do this for error, stdin, stdout, stderr. + (This also ignores an fd of -1.) */ + + x = _open_osfhandle (fd, for_write ? 1 : 0); + if (x == -1) + log_error ("failed to translate osfhandle %p\n", (void *) fd); + else + { +/* log_info ("_open_osfhandle %p yields %d%s\n", */ +/* (void*)fd, x, for_write? " for writing":"" ); */ + fd = x; + } +#endif /* HAVE_W32_SYSTEM */ + return fd; +} Modified: trunk/common/sysutils.h =================================================================== --- trunk/common/sysutils.h 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/common/sysutils.h 2007-06-25 11:54:43 UTC (rev 4525) @@ -28,6 +28,7 @@ const unsigned char *get_session_marker (size_t *rlen); int check_permissions (const char *path,int extension,int checkonly); void gnupg_sleep (unsigned int seconds); +int translate_sys2libc_fd (int fd, int for_write); #ifdef HAVE_W32_SYSTEM Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/doc/ChangeLog 2007-06-25 11:54:43 UTC (rev 4525) @@ -1,3 +1,8 @@ +2007-06-22 Werner Koch + + * gpg.texi (Operational GPG Commands): Describe the flags used by + --check-sigs. + 2007-06-21 Werner Koch * gpgsm.texi (Certificate Management): Changed description of Modified: trunk/doc/gpg.texi =================================================================== --- trunk/doc/gpg.texi 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/doc/gpg.texi 2007-06-25 11:54:43 UTC (rev 4525) @@ -309,6 +309,14 @@ @opindex check-sigs Same as @option{--list-sigs}, but the signatures are verified. +The status of the verification is indicated by a flag directly following +the "sig" tag (and thus before the flags described above for + at option{--list-sigs}). A "!" indicates that the signature has been +successfully verified, a "-" denotes a bad signature and a "%" is used +if an error occured while checking the signature (e.g. a non supported +algorithm). + + @item --fingerprint @opindex fingerprint List all keys (or the specified ones) along with their Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/g10/ChangeLog 2007-06-25 11:54:43 UTC (rev 4525) @@ -1,3 +1,9 @@ +2007-06-25 Werner Koch + + * gpg.c (main): Replace iobuf_translate_file_handle by + translate_sys2libc_fd. + * gpgv.c (main): Ditto. + 2007-06-21 Werner Koch * main.h: Include util.h. Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/g10/gpg.c 2007-06-25 11:54:43 UTC (rev 4525) @@ -2161,19 +2161,19 @@ case oDebugLevel: debug_level = pargs.r.ret_str; break; case oStatusFD: - set_status_fd( iobuf_translate_file_handle (pargs.r.ret_int, 1) ); + set_status_fd( translate_sys2libc_fd (pargs.r.ret_int, 1) ); break; case oStatusFile: set_status_fd ( open_info_file (pargs.r.ret_str, 1) ); break; case oAttributeFD: - set_attrib_fd(iobuf_translate_file_handle (pargs.r.ret_int, 1)); + set_attrib_fd(translate_sys2libc_fd (pargs.r.ret_int, 1)); break; case oAttributeFile: set_attrib_fd ( open_info_file (pargs.r.ret_str, 1) ); break; case oLoggerFD: - log_set_fd (iobuf_translate_file_handle (pargs.r.ret_int, 1)); + log_set_fd (translate_sys2libc_fd (pargs.r.ret_int, 1)); break; case oLoggerFile: logfile = pargs.r.ret_str; @@ -2437,14 +2437,14 @@ set_passphrase_from_string(pargs.r.ret_str); break; case oPasswdFD: - pwfd = iobuf_translate_file_handle (pargs.r.ret_int, 0); + pwfd = translate_sys2libc_fd (pargs.r.ret_int, 0); break; case oPasswdFile: pwfd = open_info_file (pargs.r.ret_str, 0); break; case oPasswdRepeat: opt.passwd_repeat=pargs.r.ret_int; break; case oCommandFD: - opt.command_fd = iobuf_translate_file_handle (pargs.r.ret_int, 0); + opt.command_fd = translate_sys2libc_fd (pargs.r.ret_int, 0); break; case oCommandFile: opt.command_fd = open_info_file (pargs.r.ret_str, 0); Modified: trunk/g10/gpgv.c =================================================================== --- trunk/g10/gpgv.c 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/g10/gpgv.c 2007-06-25 11:54:43 UTC (rev 4525) @@ -155,7 +155,7 @@ case oKeyring: append_to_strlist( &nrings, pargs.r.ret_str); break; case oStatusFD: set_status_fd( pargs.r.ret_int ); break; case oLoggerFD: - log_set_fd (iobuf_translate_file_handle (pargs.r.ret_int, 1)); + log_set_fd (translate_sys2libc_fd (pargs.r.ret_int, 1)); break; case oHomedir: opt.homedir = pargs.r.ret_str; break; case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break; Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/sm/ChangeLog 2007-06-25 11:54:43 UTC (rev 4525) @@ -1,3 +1,13 @@ +2007-06-25 Werner Koch + + * gpgsm.c (check_special_filename): Use translate_sys2libc_fd and + add new arg FOR_WRITE. Change callers to pass new arg. + +2007-06-24 Werner Koch + + * gpgsm.c (open_es_fwrite): Avoid the dup by using the new + es_fdopen_nc(). + 2007-06-21 Werner Koch * certreqgen-ui.c: New. Modified: trunk/sm/certreqgen.c =================================================================== --- trunk/sm/certreqgen.c 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/sm/certreqgen.c 2007-06-25 11:54:43 UTC (rev 4525) @@ -573,8 +573,8 @@ if (rc) { r = get_parameter (para, pKEYTYPE, 0); - log_error (_("line %d: key generation failed: %s\n"), - r->lnr, gpg_strerror (rc)); + log_error (_("line %d: key generation failed: %s <%s>\n"), + r->lnr, gpg_strerror (rc), gpg_strsource (rc)); xfree (cardkeyid); return rc; } @@ -863,8 +863,8 @@ rc = read_parameters (ctrl, in_fp, writer); if (rc) { - log_error ("error creating certificate request: %s\n", - gpg_strerror (rc)); + log_error ("error creating certificate request: %s <%s>\n", + gpg_strerror (rc), gpg_strsource (rc)); goto leave; } Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2007-06-22 11:52:12 UTC (rev 4524) +++ trunk/sm/gpgsm.c 2007-06-25 11:54:43 UTC (rev 4525) @@ -481,7 +481,7 @@ enum cmd_and_opt_values new_cmd ); static void emergency_cleanup (void); -static int check_special_filename (const char *fname); +static int check_special_filename (const char *fname, int for_write); static int open_read (const char *filename); static FILE *open_fwrite (const char *filename); static estream_t open_es_fwrite (const char *filename); @@ -1732,7 +1732,7 @@ /* Check whether the filename has the form "-&nnnn", where n is a non-zero number. Returns this number or -1 if it is not the case. */ static int -check_special_filename (const char *fname) +check_special_filename (const char *fname, int for_write) { if (allow_special_filenames && fname && *fname == '-' && fname[1] == '&' ) { @@ -1742,7 +1742,7 @@ for (i=0; isdigit (fname[i]); i++ ) ; if ( !fname[i] ) - return atoi (fname); + return translate_sys2libc_fd (atoi (fname), for_write); } return -1; } @@ -1762,7 +1762,7 @@ set_binary (stdin); return 0; /* stdin */ } - fd = check_special_filename (filename); + fd = check_special_filename (filename, 0); if (fd != -1) return fd; fd = open (filename, O_RDONLY | O_BINARY); @@ -1790,7 +1790,7 @@ return stdout; } - fd = check_special_filename (filename); + fd = check_special_filename (filename, 1); if (fd != -1) { fp = fdopen (dup (fd), "wb"); @@ -1825,14 +1825,14 @@ if (filename[0] == '-' && !filename[1]) { fflush (stdout); - fp = es_fdopen (dup (fileno(stdout)), "wb"); + fp = es_fdopen_nc (fileno(stdout), "wb"); return fp; } - fd = check_special_filename (filename); + fd = check_special_filename (filename, 1); if (fd != -1) { - fp = es_fdopen (dup (fd), "wb"); + fp = es_fdopen_nc (fd, "wb"); if (!fp) { log_error ("es_fdopen(%d) failed: %s\n", fd, strerror (errno)); From cvs at cvs.gnupg.org Tue Jun 26 15:49:22 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 26 Jun 2007 15:49:22 +0200 Subject: [svn] GnuPG - r4526 - in trunk: . agent common g10 gl kbx sm tools Message-ID: Author: wk Date: 2007-06-26 15:48:44 +0200 (Tue, 26 Jun 2007) New Revision: 4526 Added: trunk/common/init.h Modified: trunk/ChangeLog trunk/TODO trunk/agent/ChangeLog trunk/agent/gpg-agent.c trunk/common/ChangeLog trunk/common/Makefile.am trunk/common/gpgrlhelp.c trunk/common/homedir.c trunk/common/iobuf.c trunk/common/sysutils.h trunk/common/ttyio.c trunk/common/util.h trunk/g10/ChangeLog trunk/g10/gpg.c trunk/g10/gpgv.c trunk/g10/openfile.c trunk/gl/mkdtemp.c trunk/kbx/ChangeLog trunk/kbx/kbxutil.c trunk/sm/ChangeLog trunk/sm/Makefile.am trunk/sm/gpgsm.c trunk/tools/ChangeLog trunk/tools/gpgconf-comp.c Log: More W32 related changes Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/ChangeLog 2007-06-26 13:48:44 UTC (rev 4526) @@ -1,3 +1,8 @@ +2007-06-25 Werner Koch + + * gl/mkdtemp.c (gen_tempname) [MKDIR_TAKES_ONE_ARG]: Avoid + compiler warning by using the proper config macro. + 2007-06-15 Werner Koch * configure.ac: Call AM_PO_SUBDIRS. Modified: trunk/TODO =================================================================== --- trunk/TODO 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/TODO 2007-06-26 13:48:44 UTC (rev 4526) @@ -109,7 +109,7 @@ ** GCRY_MD_USER Remove these definitions. ** MY_GCRY_PK_ECDSA - Removed this. + Remove this. * Extend selinux support to other modules Modified: trunk/agent/ChangeLog =================================================================== --- trunk/agent/ChangeLog 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/agent/ChangeLog 2007-06-26 13:48:44 UTC (rev 4526) @@ -1,3 +1,7 @@ +2007-06-26 Werner Koch + + * gpg-agent.c (create_directories) [W32]: Made it work. + 2007-06-21 Werner Koch * agent.h (ctrl_t): Remove. It is now declared in ../common/util.h. Modified: trunk/agent/gpg-agent.c =================================================================== --- trunk/agent/gpg-agent.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/agent/gpg-agent.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -1351,10 +1351,7 @@ create_directories (void) { struct stat statbuf; -#ifdef HAVE_W32_SYSTEM -#warning change it so that it works like in gpg. -#endif - const char *defhome = GNUPG_DEFAULT_HOMEDIR; + const char *defhome = standard_homedir (); char *home; home = make_filename (opt.homedir, NULL); @@ -1362,11 +1359,16 @@ { if (errno == ENOENT) { - if ( (*defhome == '~' + if ( +#ifdef HAVE_W32_SYSTEM + ( !compare_filenames (home, defhome) ) +#else + (*defhome == '~' && (strlen (home) >= strlen (defhome+1) && !strcmp (home + strlen(home) - strlen (defhome+1), defhome+1))) || (*defhome != '~' && !strcmp (home, defhome) ) +#endif ) { #ifdef HAVE_W32_SYSTEM Modified: trunk/common/ChangeLog =================================================================== --- trunk/common/ChangeLog 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/common/ChangeLog 2007-06-26 13:48:44 UTC (rev 4526) @@ -1,5 +1,22 @@ +2007-06-26 Werner Koch + + * Makefile.am ($(PROGRAMS)): New. + + * util.h (init_common_subsystems): Moved to .. + * init.h: .. New. + * util.h: Include init.h. + + * homedir.c (standard_homedir): New. + (default_homedir) [W32]: Reimplemented in terms of + standard_homedir. Fixed memory leak. + 2007-06-25 Werner Koch + * iobuf.c: Add more documentation and slighly restructured macro + defintion for better readability. + (FILEP_OR_FD): Rename to fp_or_fd_t. + (CLOSE_CACHE): Rename to close_cache_t. + * sysutils.c (translate_sys2libc_fd): New using the code from iobuf.c. * iobuf.c: Include sysutils.h. (iobuf_translate_file_handle): Remove. Modified: trunk/common/Makefile.am =================================================================== --- trunk/common/Makefile.am 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/common/Makefile.am 2007-06-26 13:48:44 UTC (rev 4526) @@ -37,7 +37,7 @@ openpgpdefs.h \ keyserver.h \ sexp-parse.h \ - init.c \ + init.c init.h \ sexputil.c \ sysutils.c sysutils.h \ homedir.c \ @@ -91,3 +91,6 @@ t_convert_DEPENDENCIES = convert.c libcommon.a t_convert_LDADD = $(t_common_ldadd) + +$(PROGRAMS): ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a + Modified: trunk/common/gpgrlhelp.c =================================================================== --- trunk/common/gpgrlhelp.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/common/gpgrlhelp.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -21,8 +21,8 @@ /* This module may by used by applications to initializes readline support. It is required so that we can have hooks in other parts - of libcommon without actually requing to link against - libreadline. It works along ttyio.c which a proper part of + of libcommon without actually requiring to link against + libreadline. It works along with ttyio.c which is a proper part of libcommon. */ #include Modified: trunk/common/homedir.c =================================================================== --- trunk/common/homedir.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/common/homedir.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -1,5 +1,5 @@ /* homedir.c - Setup the home directory. - * Copyright (C) 2004, 2006 Free Software Foundation, Inc. + * Copyright (C) 2004, 2006, 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -83,18 +83,17 @@ #endif /*HAVE_W32_SYSTEM*/ -/* Set up the default home directory. The usual --homedir option - should be parsed later. */ +/* Get the standard home directory. In general this function should + not be used as it does not consider a registry value (under W32) or + the GNUPGHOME encironment variable. It is better to use + default_homedir(). */ const char * -default_homedir (void) +standard_homedir (void) { - const char *dir; +#ifdef HAVE_W32_SYSTEM + static const char *dir; - dir = getenv("GNUPGHOME"); -#ifdef HAVE_W32_SYSTEM - if (!dir || !*dir) - dir = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", "HomeDir"); - if (!dir || !*dir) + if (!dir) { char path[MAX_PATH]; @@ -112,12 +111,54 @@ strcpy (stpcpy (tmp, path), "\\gnupg"); dir = tmp; - /* Try to create the directory if it does not yet - exists. */ + /* Try to create the directory if it does not yet exists. */ if (access (dir, F_OK)) CreateDirectory (dir, NULL); } + else + dir = GNUPG_DEFAULT_HOMEDIR; } + return dir; +#else/*!HAVE_W32_SYSTEM*/ + return GNUPG_DEFAULT_HOMEDIR; +#endif /*!HAVE_W32_SYSTEM*/ +} + +/* Set up the default home directory. The usual --homedir option + should be parsed later. */ +const char * +default_homedir (void) +{ + const char *dir; + + dir = getenv ("GNUPGHOME"); +#ifdef HAVE_W32_SYSTEM + if (!dir || !*dir) + { + static const char *saved_dir; + + if (!saved_dir) + { + if (!dir || !*dir) + { + char *tmp; + + tmp = read_w32_registry_string (NULL, "Software\\GNU\\GnuPG", + "HomeDir"); + if (tmp && *tmp) + { + xfree (tmp); + tmp = NULL; + } + if (tmp) + saved_dir = tmp; + } + + if (!saved_dir) + saved_dir = standard_homedir (); + } + dir = saved_dir; + } #endif /*HAVE_W32_SYSTEM*/ if (!dir || !*dir) dir = GNUPG_DEFAULT_HOMEDIR; Added: trunk/common/init.h =================================================================== --- trunk/common/init.h 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/common/init.h 2007-06-26 13:48:44 UTC (rev 4526) @@ -0,0 +1,28 @@ +/* init.h - Definitions for init fucntions. + * Copyright (C) 2007 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 2 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, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifndef GNUPG_COMMON_INIT_H +#define GNUPG_COMMON_INIT_H + +void init_common_subsystems (void); + + +#endif /*GNUPG_COMMON_INIT_H*/ Modified: trunk/common/iobuf.c =================================================================== --- trunk/common/iobuf.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/common/iobuf.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -1,6 +1,6 @@ -/* iobuf.c - file handling - * Copyright (C) 1998, 1999, 2000, 2001, 2003, - * 2004, 2006 Free Software Foundation, Inc. +/* iobuf.c - File Handling for OpenPGP. + * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, + * 2007 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -31,95 +31,129 @@ #include #include #include -#ifdef HAVE_DOSISH_SYSTEM -#include +#ifdef HAVE_W32_SYSTEM +# include #endif #ifdef __riscos__ -#include -#include +# include +# include #endif /* __riscos__ */ #include "util.h" #include "sysutils.h" #include "iobuf.h" +/*-- Begin configurable part. --*/ + /* The size of the internal buffers. NOTE: If you change this value you MUST also adjust the regression test "armored_key_8192" in armor.test! */ #define IOBUF_BUFFER_SIZE 8192 +/* We don't want to use the STDIO based backend. */ #undef FILE_FILTER_USES_STDIO -#ifdef HAVE_DOSISH_SYSTEM -#define USE_SETMODE 1 -#endif +/*-- End configurable part. --*/ + +/* Under W32 the default is to use the setmode call. Define a macro + which allows us to enable this call. */ +#ifdef HAVE_W32_SYSTEM +# define USE_SETMODE 1 +#endif /*HAVE_W32_SYSTEM*/ + + +/* Definition of constants and macros used by our file filter + implementation. What we define here are 3 macros to make the + appropriate calls: + + my_fileno + Is expanded to fileno(a) if using a stdion backend and to a if we + are using the low-level backend. + + my_fopen + Is defined to fopen for the stdio backend and to direct_open if + we are using the low-evel backend. + + my_fopen_ro + Is defined to fopen for the stdio backend and to fd_cache_open if + we are using the low-evel backend. + + fp_or_fd_t + Is the type we use for the backend stream or fiel descriptor. + + INVALID_FP, FILEP_OR_FD_FOR_STDIN, FILEP_OR_FD_FOR_STDOUT + Are macros defined depending on the used backend. + +*/ #ifdef FILE_FILTER_USES_STDIO -#define my_fileno(a) fileno ((a)) -#define my_fopen_ro(a,b) fopen ((a),(b)) -#define my_fopen(a,b) fopen ((a),(b)) -typedef FILE *FILEP_OR_FD; -#define INVALID_FP NULL -#define FILEP_OR_FD_FOR_STDIN (stdin) -#define FILEP_OR_FD_FOR_STDOUT (stdout) +# define my_fileno(a) fileno ((a)) +# define my_fopen_ro(a,b) fopen ((a),(b)) +# define my_fopen(a,b) fopen ((a),(b)) + typedef FILE *fp_or_fd_t; +# define INVALID_FP NULL +# define FILEP_OR_FD_FOR_STDIN (stdin) +# define FILEP_OR_FD_FOR_STDOUT (stdout) +#else /*!FILE_FILTER_USES_STDIO*/ +# define my_fopen_ro(a,b) fd_cache_open ((a),(b)) +# define my_fopen(a,b) direct_open ((a),(b)) +# ifdef HAVE_W32_SYSTEM + /* (We assume that a HANDLE first into an int.) */ +# define my_fileno(a) ((int)(a)) + typedef HANDLE fp_or_fd_t; +# define INVALID_FP ((HANDLE)-1) +# define FILEP_OR_FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE)) +# define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE)) +# undef USE_SETMODE +# else /*!HAVE_W32_SYSTEM*/ +# define my_fileno(a) (a) + typedef int fp_or_fd_t; +# define INVALID_FP (-1) +# define FILEP_OR_FD_FOR_STDIN (0) +# define FILEP_OR_FD_FOR_STDOUT (1) +# endif /*!HAVE_W32_SYSTEM*/ +#endif /*!FILE_FILTER_USES_STDIO*/ + +/* The context used by the file filter. */ typedef struct { - FILE *fp; /* open file handle */ - int keep_open; + fp_or_fd_t fp; /* Open file pointer or handle. */ + int keep_open; int no_cache; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ -} -file_filter_ctx_t; -#else -#define my_fileno(a) (a) -#define my_fopen_ro(a,b) fd_cache_open ((a),(b)) -#define my_fopen(a,b) direct_open ((a),(b)) -#ifdef HAVE_DOSISH_SYSTEM -typedef HANDLE FILEP_OR_FD; -#define INVALID_FP ((HANDLE)-1) -#define FILEP_OR_FD_FOR_STDIN (GetStdHandle (STD_INPUT_HANDLE)) -#define FILEP_OR_FD_FOR_STDOUT (GetStdHandle (STD_OUTPUT_HANDLE)) -#undef USE_SETMODE -#else -typedef int FILEP_OR_FD; -#define INVALID_FP (-1) -#define FILEP_OR_FD_FOR_STDIN (0) -#define FILEP_OR_FD_FOR_STDOUT (1) -#endif -typedef struct -{ - FILEP_OR_FD fp; /* open file handle */ - int keep_open; - int no_cache; int eof_seen; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ + int print_only_name; /* Flags indicating that fname is not a real file. */ + char fname[1]; /* Name of the file. */ } file_filter_ctx_t; + +/* If we are not using stdio as the backend we make use of a "close + cache". */ +#ifndef FILE_FILTER_USES_STDIO struct close_cache_s { struct close_cache_s *next; - FILEP_OR_FD fp; + fp_or_fd_t fp; char fname[1]; }; -typedef struct close_cache_s *CLOSE_CACHE; -static CLOSE_CACHE close_cache; -#endif +typedef struct close_cache_s *close_cache_t; +static close_cache_t close_cache; +#endif /*!FILE_FILTER_USES_STDIO*/ -#ifdef _WIN32 + + +#ifdef HAVE_W32_SYSTEM typedef struct { int sock; int keep_open; int no_cache; int eof_seen; - int print_only_name; /* flags indicating that fname is not a real file */ - char fname[1]; /* name of the file */ + int print_only_name; /* Flag indicating that fname is not a real file. */ + char fname[1]; /* Name of the file */ } sock_filter_ctx_t; -#endif /*_WIN32*/ +#endif /*HAVE_W32_SYSTEM*/ /* The first partial length header block must be of size 512 * to make it easier (and efficienter) we use a min. block size of 512 @@ -127,33 +161,41 @@ #define OP_MIN_PARTIAL_CHUNK 512 #define OP_MIN_PARTIAL_CHUNK_2POW 9 +/* The context we use for the block filter (used to handle OpenPGP + length information header). */ typedef struct { int use; size_t size; size_t count; - int partial; /* 1 = partial header, 2 in last partial packet */ - char *buffer; /* used for partial header */ - size_t buflen; /* used size of buffer */ - int first_c; /* of partial header (which is > 0) */ + int partial; /* 1 = partial header, 2 in last partial packet. */ + char *buffer; /* Used for partial header. */ + size_t buflen; /* Used size of buffer. */ + int first_c; /* First character of a partial header (which is > 0). */ int eof; } block_filter_ctx_t; + +/* Global flag to tell whether special file names are enabled. See + gpg.c for an explanation of these file names. FIXME: it does not + belong into the iobuf subsystem. */ static int special_names_enabled; +/* Local prototypes. */ static int underflow (iobuf_t a); static int translate_file_handle (int fd, int for_write); + + #ifndef FILE_FILTER_USES_STDIO - /* * Invalidate (i.e. close) a cached iobuf */ static void fd_cache_invalidate (const char *fname) { - CLOSE_CACHE cc; + close_cache_t cc; assert (fname); if (DBG_IOBUF) @@ -165,7 +207,7 @@ { if (DBG_IOBUF) log_debug (" did (%s)\n", cc->fname); -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM CloseHandle (cc->fp); #else close (cc->fp); @@ -176,11 +218,10 @@ } - -static FILEP_OR_FD +static fp_or_fd_t direct_open (const char *fname, const char *mode) { -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM unsigned long da, cd, sm; HANDLE hfile; @@ -213,7 +254,7 @@ hfile = CreateFile (fname, da, sm, NULL, cd, FILE_ATTRIBUTE_NORMAL, NULL); return hfile; -#else +#else /*!HAVE_W32_SYSTEM*/ int oflag; int cflag = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; @@ -236,6 +277,7 @@ if (strchr (mode, 'b')) oflag |= O_BINARY; #endif + /* No we need to distinguish between POSIX and RISC OS. */ #ifndef __riscos__ return open (fname, oflag, cflag); #else @@ -250,7 +292,7 @@ return open (fname, oflag, cflag); } #endif -#endif +#endif /*!HAVE_W32_SYSTEM*/ } @@ -259,14 +301,14 @@ * Note that this caching strategy only works if the process does not chdir. */ static void -fd_cache_close (const char *fname, FILEP_OR_FD fp) +fd_cache_close (const char *fname, fp_or_fd_t fp) { - CLOSE_CACHE cc; + close_cache_t cc; assert (fp); if (!fname || !*fname) { -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM CloseHandle (fp); #else close (fp); @@ -299,21 +341,21 @@ /* * Do an direct_open on FNAME but first try to reuse one from the fd_cache */ -static FILEP_OR_FD +static fp_or_fd_t fd_cache_open (const char *fname, const char *mode) { - CLOSE_CACHE cc; + close_cache_t cc; assert (fname); for (cc = close_cache; cc; cc = cc->next) { if (cc->fp != INVALID_FP && !strcmp (cc->fname, fname)) { - FILEP_OR_FD fp = cc->fp; + fp_or_fd_t fp = cc->fp; cc->fp = INVALID_FP; if (DBG_IOBUF) log_debug ("fd_cache_open (%s) using cached fp\n", fname); -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM if (SetFilePointer (fp, 0, NULL, FILE_BEGIN) == 0xffffffff) { log_error ("rewind file failed on handle %p: ec=%d\n", @@ -335,7 +377,6 @@ return direct_open (fname, mode); } - #endif /*FILE_FILTER_USES_STDIO */ @@ -368,7 +409,7 @@ size_t * ret_len) { file_filter_ctx_t *a = opaque; - FILEP_OR_FD f = a->fp; + fp_or_fd_t f = a->fp; size_t size = *ret_len; size_t nbytes = 0; int rc = 0; @@ -444,7 +485,7 @@ } else { -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM unsigned long nread; nbytes = 0; @@ -503,7 +544,7 @@ { if (size) { -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM byte *p = buf; unsigned long n; @@ -563,7 +604,7 @@ } else if (control == IOBUFCTRL_FREE) { -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM if (f != FILEP_OR_FD_FOR_STDIN && f != FILEP_OR_FD_FOR_STDOUT) { if (DBG_IOBUF) @@ -587,9 +628,10 @@ return rc; } -#ifdef _WIN32 -/* Becuase sockets are an special object under Lose32 we have to - * use a special filter */ + +#ifdef HAVE_W32_SYSTEM +/* Because network sockets are special objects under Lose32 we have to + use a dedicated filter for them. */ static int sock_filter (void *opaque, int control, iobuf_t chain, byte * buf, size_t * ret_len) @@ -674,7 +716,7 @@ } return rc; } -#endif /*_WIN32*/ +#endif /*HAVE_W32_SYSTEM*/ /**************** * This is used to implement the block write mode. @@ -1050,7 +1092,7 @@ const char *s; iobuf_t a2; int rc; -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) +#if defined(HAVE_W32_SYSTEM) || defined(__riscos__) char *remove_name = NULL; #endif @@ -1059,7 +1101,7 @@ s = iobuf_get_real_fname (a); if (s && *s) { -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) +#if defined(HAVE_W32_SYSTEM) || defined(__riscos__) remove_name = xstrdup (s); #else remove (s); @@ -1076,7 +1118,7 @@ } rc = iobuf_close (a); -#if defined(HAVE_DOSISH_SYSTEM) || defined(__riscos__) +#if defined(HAVE_W32_SYSTEM) || defined(__riscos__) if (remove_name) { /* Argg, MSDOS does not allow to remove open files. So @@ -1161,7 +1203,7 @@ iobuf_open (const char *fname) { iobuf_t a; - FILEP_OR_FD fp; + fp_or_fd_t fp; file_filter_ctx_t *fcx; size_t len; int print_only = 0; @@ -1206,7 +1248,7 @@ iobuf_fdopen (int fd, const char *mode) { iobuf_t a; - FILEP_OR_FD fp; + fp_or_fd_t fp; file_filter_ctx_t *fcx; size_t len; @@ -1214,7 +1256,7 @@ if (!(fp = fdopen (fd, mode))) return NULL; #else - fp = (FILEP_OR_FD) fd; + fp = (fp_or_fd_t) fd; #endif a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, 8192); fcx = xmalloc (sizeof *fcx + 20); @@ -1236,7 +1278,7 @@ iobuf_sockopen (int fd, const char *mode) { iobuf_t a; -#ifdef _WIN32 +#ifdef HAVE_W32_SYSTEM sock_filter_ctx_t *scx; size_t len; @@ -1265,7 +1307,7 @@ iobuf_create (const char *fname) { iobuf_t a; - FILEP_OR_FD fp; + fp_or_fd_t fp; file_filter_ctx_t *fcx; size_t len; int print_only = 0; @@ -1339,7 +1381,7 @@ iobuf_openrw (const char *fname) { iobuf_t a; - FILEP_OR_FD fp; + fp_or_fd_t fp; file_filter_ctx_t *fcx; size_t len; @@ -1379,7 +1421,7 @@ b->keep_open = intval; return 0; } -#ifdef _WIN32 +#ifdef HAVE_W32_SYSTEM else if (!a->chain && a->filter == sock_filter) { sock_filter_ctx_t *b = a->filter_ov; @@ -1414,7 +1456,7 @@ b->no_cache = intval; return 0; } -#ifdef _WIN32 +#ifdef HAVE_W32_SYSTEM else if (!a->chain && a->filter == sock_filter) { sock_filter_ctx_t *b = a->filter_ov; @@ -2027,9 +2069,9 @@ if ( !a->chain && a->filter == file_filter ) { file_filter_ctx_t *b = a->filter_ov; - FILEP_OR_FD fp = b->fp; + fp_or_fd_t fp = b->fp; -#if defined(HAVE_DOSISH_SYSTEM) && !defined(FILE_FILTER_USES_STDIO) +#if defined(HAVE_W32_SYSTEM) && !defined(FILE_FILTER_USES_STDIO) ulong size; static int (* __stdcall get_file_size_ex) (void *handle, LARGE_INTEGER *r_size); @@ -2096,7 +2138,7 @@ if (!a->chain && a->filter == file_filter) { file_filter_ctx_t *b = a->filter_ov; - FILEP_OR_FD fp = b->fp; + fp_or_fd_t fp = b->fp; return my_fileno (fp); } @@ -2184,7 +2226,7 @@ return -1; } #else -#ifdef HAVE_DOSISH_SYSTEM +#ifdef HAVE_W32_SYSTEM if (SetFilePointer (b->fp, newpos, NULL, FILE_BEGIN) == 0xffffffff) { log_error ("SetFilePointer failed on handle %p: ec=%d\n", @@ -2354,10 +2396,10 @@ static int translate_file_handle (int fd, int for_write) { -#ifdef _WIN32 -#ifdef FILE_FILTER_USES_STDIO +#ifdef HAVE_W32_SYSTEM +# ifdef FILE_FILTER_USES_STDIO fd = translate_sys2libc_fd (fd, for_write); -#else +# else { int x; @@ -2376,8 +2418,8 @@ fd = x; } +# endif #endif -#endif return fd; } Modified: trunk/common/sysutils.h =================================================================== --- trunk/common/sysutils.h 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/common/sysutils.h 2007-06-26 13:48:44 UTC (rev 4526) @@ -26,7 +26,7 @@ int disable_core_dumps (void); int enable_core_dumps (void); const unsigned char *get_session_marker (size_t *rlen); -int check_permissions (const char *path,int extension,int checkonly); +/*int check_permissions (const char *path,int extension,int checkonly);*/ void gnupg_sleep (unsigned int seconds); int translate_sys2libc_fd (int fd, int for_write); Modified: trunk/common/ttyio.c =================================================================== --- trunk/common/ttyio.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/common/ttyio.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -632,7 +632,7 @@ } -/* Called by gnupg_rl_initialize to setup the reradline support. */ +/* Called by gnupg_rl_initialize to setup the readline support. */ void tty_private_set_rl_hooks (void (*init_stream) (FILE *), void (*set_completer) (rl_completion_func_t*), Modified: trunk/common/util.h =================================================================== --- trunk/common/util.h 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/common/util.h 2007-06-26 13:48:44 UTC (rev 4526) @@ -40,12 +40,15 @@ #include "../jnlib/utf8conv.h" #include "../jnlib/dynload.h" +#include "init.h" + /* Redefine asprintf by our estream version which uses our own memory allocator.. */ #include "estream-printf.h" #define asprintf estream_asprintf #define vasprintf estream_vasprintf + /* GCC attributes. */ #if __GNUC__ >= 4 # define GNUPG_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a))) @@ -119,8 +122,6 @@ strcpy (d, s); } -/*-- init.c --*/ -void init_common_subsystems (void); /*-- signal.c --*/ void gnupg_init_signals (int mode, void (*fast_cleanup)(void)); @@ -170,6 +171,7 @@ /*-- homedir.c --*/ +const char *standard_homedir (void); const char *default_homedir (void); const char *gnupg_sysconfdir (void); const char *gnupg_bindir (void); Modified: trunk/g10/ChangeLog =================================================================== --- trunk/g10/ChangeLog 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/g10/ChangeLog 2007-06-26 13:48:44 UTC (rev 4526) @@ -1,8 +1,13 @@ +2007-06-26 Werner Koch + + * openfile.c (try_make_homedir): Support W32; use standard_homedir. + 2007-06-25 Werner Koch - * gpg.c (main): Replace iobuf_translate_file_handle by + * gpg.c, gpgv.c: Include sysutils.h. + (main): Replace iobuf_translate_file_handle by translate_sys2libc_fd. - * gpgv.c (main): Ditto. + 2007-06-21 Werner Koch Modified: trunk/g10/gpg.c =================================================================== --- trunk/g10/gpg.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/g10/gpg.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -53,6 +53,7 @@ #include "filter.h" #include "ttyio.h" #include "i18n.h" +#include "sysutils.h" #include "status.h" #include "keyserver-internal.h" #include "exec.h" Modified: trunk/g10/gpgv.c =================================================================== --- trunk/g10/gpgv.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/g10/gpgv.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -48,6 +48,7 @@ #include "filter.h" #include "ttyio.h" #include "i18n.h" +#include "sysutils.h" #include "status.h" #include "call-agent.h" Modified: trunk/g10/openfile.c =================================================================== --- trunk/g10/openfile.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/g10/openfile.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -404,37 +404,35 @@ void -try_make_homedir( const char *fname ) +try_make_homedir (const char *fname) { - const char *defhome = GNUPG_DEFAULT_HOMEDIR; -#ifdef HAVE_W32_SYSTEM -#warning use a function and not a constant -#endif + const char *defhome = standard_homedir (); - /* Create the directory only if the supplied directory name - * is the same as the default one. This way we avoid to create - * arbitrary directories when a non-default homedirectory is used. - * To cope with HOME, we do compare only the suffix if we see that - * the default homedir does start with a tilde. - */ - if( opt.dry_run || opt.no_homedir_creation ) - return; + /* Create the directory only if the supplied directory name is the + same as the default one. This way we avoid to create arbitrary + directories when a non-default home directory is used. To cope + with HOME, we do compare only the suffix if we see that the + default homedir does start with a tilde. */ + if ( opt.dry_run || opt.no_homedir_creation ) + return; - if ( ( *defhome == '~' - && ( strlen(fname) >= strlen (defhome+1) - && !strcmp(fname+strlen(fname)-strlen(defhome+1), - defhome+1 ) )) - || ( *defhome != '~' - && !compare_filenames( fname, defhome ) ) - ) { - if( mkdir( fname, S_IRUSR|S_IWUSR|S_IXUSR ) ) - log_fatal( _("can't create directory `%s': %s\n"), - fname, strerror(errno) ); - else if( !opt.quiet ) - log_info( _("directory `%s' created\n"), fname ); - copy_options_file( fname ); -/* log_info(_("you have to start GnuPG again, " */ -/* "so it can read the new configuration file\n") ); */ -/* g10_exit(1); */ + if ( +#ifdef HAVE_W32_SYSTEM + ( !compare_filenames (fname, defhome) ) +#else + ( *defhome == '~' + && (strlen(fname) >= strlen (defhome+1) + && !strcmp(fname+strlen(fname)-strlen(defhome+1), defhome+1 ) )) + || (*defhome != '~' && !compare_filenames( fname, defhome ) ) +#endif + ) + { + if ( mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR) ) + log_fatal ( _("can't create directory `%s': %s\n"), + fname, strerror(errno) ); + else if (!opt.quiet ) + log_info ( _("directory `%s' created\n"), fname ); + copy_options_file( fname ); + } } Modified: trunk/gl/mkdtemp.c =================================================================== --- trunk/gl/mkdtemp.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/gl/mkdtemp.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -74,9 +74,6 @@ #ifdef __MINGW32__ # include -/* mingw's _mkdir() function has 1 argument, but we pass 2 arguments. - Therefore we have to disable the argument count checking. */ -# define mkdir ((int (*)()) _mkdir) #endif #if !_LIBC @@ -177,7 +174,11 @@ v /= 62; XXXXXX[5] = letters[v % 62]; +#ifdef MKDIR_TAKES_ONE_ARG + fd = mkdir (tmpl); +#else fd = __mkdir (tmpl, S_IRUSR | S_IWUSR | S_IXUSR); +#endif if (fd >= 0) { Modified: trunk/kbx/ChangeLog =================================================================== --- trunk/kbx/ChangeLog 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/kbx/ChangeLog 2007-06-26 13:48:44 UTC (rev 4526) @@ -1,3 +1,7 @@ +2007-06-26 Werner Koch + + * kbxutil.c: Include init.h + 2007-06-15 Werner Koch * Makefile.am (kbxutil_LDADD): Add W32SOCKLIBS. Modified: trunk/kbx/kbxutil.c =================================================================== --- trunk/kbx/kbxutil.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/kbx/kbxutil.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -34,12 +34,12 @@ #include "../jnlib/argparse.h" #include "../jnlib/stringhelp.h" #include "../jnlib/utf8conv.h" -#include "../common/i18n.h" +#include "i18n.h" +#include "init.h" #include "keybox-defs.h" #include - enum cmd_and_opt_values { aNull = 0, oArmor = 'a', Modified: trunk/sm/ChangeLog =================================================================== --- trunk/sm/ChangeLog 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/sm/ChangeLog 2007-06-26 13:48:44 UTC (rev 4526) @@ -1,3 +1,8 @@ +2007-06-26 Werner Koch + + * gpgsm.c (main): Call gnupg_rl_initialize. + * Makefile.am (gpgsm_LDADD): Add LIBREADLINE and libgpgrl.a. + 2007-06-25 Werner Koch * gpgsm.c (check_special_filename): Use translate_sys2libc_fd and Modified: trunk/sm/Makefile.am =================================================================== --- trunk/sm/Makefile.am 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/sm/Makefile.am 2007-06-26 13:48:44 UTC (rev 4526) @@ -57,9 +57,9 @@ common_libs = ../jnlib/libjnlib.a ../kbx/libkeybox.a \ $(libcommon) ../gl/libgnu.a -gpgsm_LDADD = $(common_libs) \ +gpgsm_LDADD = $(common_libs) ../common/libgpgrl.a \ $(LIBGCRYPT_LIBS) $(KSBA_LIBS) $(LIBASSUAN_LIBS) \ - $(GPG_ERROR_LIBS) $(LIBINTL) $(ZLIBS) $(LIBICONV) + $(GPG_ERROR_LIBS) $(LIBREADLINE) $(LIBINTL) $(ZLIBS) $(LIBICONV) # Make sure that all libs are build before we use them. This is # important for things like make -j2. Modified: trunk/sm/gpgsm.c =================================================================== --- trunk/sm/gpgsm.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/sm/gpgsm.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -736,6 +736,7 @@ /*mtrace();*/ /* trap_unaligned ();*/ + gnupg_rl_initialize (); set_strusage (my_strusage); gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN); /* We don't need any locking in libgcrypt unless we use any kind of Modified: trunk/tools/ChangeLog =================================================================== --- trunk/tools/ChangeLog 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/tools/ChangeLog 2007-06-26 13:48:44 UTC (rev 4526) @@ -1,3 +1,14 @@ +2007-06-26 Werner Koch + + * gpgconf-comp.c (key_matches_user_or_group) [W32]: Implement user + name matching. + (GPGNAME): New. Use it instead of "gpg". + (gc_component) [W32]: Disable dirmngr for now. + (gc_component_retrieve_options): Ignore components without options. + (gc_component_change_options): Ditto. + (gc_component_list_options): Ditto. + (gc_component_find, gc_component_list_components): Ditto. + 2007-06-19 Werner Koch * gpgconf-comp.c (percent_escape): Rename to my_percent_escape. Modified: trunk/tools/gpgconf-comp.c =================================================================== --- trunk/tools/gpgconf-comp.c 2007-06-25 11:54:43 UTC (rev 4525) +++ trunk/tools/gpgconf-comp.c 2007-06-26 13:48:44 UTC (rev 4526) @@ -33,9 +33,12 @@ #include #include #include -#ifndef HAVE_W32_SYSTEM -#include -#include +#ifdef HAVE_W32_SYSTEM +# define WIN32_LEAN_AND_MEAN 1 +# include +#else +# include +# include #endif /* For log_logv(), asctimestamp(), gnupg_get_time (). */ @@ -46,6 +49,16 @@ #include "gpgconf.h" +/* There is a problem with gpg 1.4 under Windows: --gpgconf-list + returns a plain filename without escaping. As long as we have not + fixed that we need to use gpg2 - it might actually be better to use + gpg2 in any case. */ +#ifdef HAVE_W32_SYSTEM +#define GPGNAME "gpg2" +#else +#define GPGNAME "gpg" +#endif + /* TODO: Components: Add more components and their options. @@ -156,7 +169,7 @@ } gc_backend[GC_BACKEND_NR] = { { NULL }, /* GC_BACKEND_ANY dummy entry. */ - { "GnuPG", "gpg", NULL, "gpgconf-gpg.conf" }, + { "GnuPG", GPGNAME, NULL, "gpgconf-gpg.conf" }, { "GPGSM", "gpgsm", NULL, "gpgconf-gpgsm.conf" }, { "GPG Agent", "gpg-agent", gpg_agent_runtime_change, "gpgconf-gpg-agent.conf" }, @@ -901,7 +914,9 @@ { "gpg-agent", NULL, "GPG Agent", gc_options_gpg_agent }, { "scdaemon", NULL, "Smartcard Daemon", gc_options_scdaemon }, { "gpgsm", NULL, "GPG for S/MIME", gc_options_gpgsm }, +#ifndef HAVE_W32_SYSTEM { "dirmngr", NULL, "Directory Manager", gc_options_dirmngr } +#endif }; @@ -1081,10 +1096,13 @@ for (idx = 0; idx < GC_COMPONENT_NR; idx++) { - const char *desc = gc_component[idx].desc; - desc = my_dgettext (gc_component[idx].desc_domain, desc); - fprintf (out, "%s:%s\n", - gc_component[idx].name, my_percent_escape (desc)); + if (gc_component[idx].options) + { + const char *desc = gc_component[idx].desc; + desc = my_dgettext (gc_component[idx].desc_domain, desc); + fprintf (out, "%s:%s\n", + gc_component[idx].name, my_percent_escape (desc)); + } } } @@ -1098,7 +1116,8 @@ for (idx = 0; idx < GC_COMPONENT_NR; idx++) { - if (!strcmp (name, gc_component[idx].name)) + if (gc_component[idx].options + && !strcmp (name, gc_component[idx].name)) return idx; } return -1; @@ -1222,7 +1241,7 @@ const gc_option_t *option = gc_component[component].options; const gc_option_t *group_option = NULL; - while (option->name) + while (option && option->name) { /* Do not output unknown or internal options. */ if (!(option->flags & GC_OPT_FLAG_GROUP) @@ -1595,7 +1614,7 @@ { option = gc_component[component].options; - while (option->name) + while (option && option->name) { if (!(option->flags & GC_OPT_FLAG_GROUP)) { @@ -2507,7 +2526,7 @@ write them out to new configuration files, verify them externally, and then commit them. */ option = gc_component[component].options; - while (option->name) + while (option && option->name) { /* Go on if we have already seen this backend, or if there is nothing to do. */ @@ -2649,11 +2668,7 @@ static int key_matches_user_or_group (char *user) { -#ifdef HAVE_W32_SYSTEM -# warning We need a real user and group lookup. -#else char *group; - int n; if (*user == '*' && user[1] == 0) return 1; /* A single asterisk matches all users. */ @@ -2662,6 +2677,30 @@ if (group) *group++ = 0; +#ifdef HAVE_W32_SYSTEM + /* Under Windows we don't support groups. */ + if (group && *group) + gc_error (0, 0, _("Note that group specifications are ignored\n")); + if (*user) + { + static char *my_name; + + if (!my_name) + { + char tmp[1]; + DWORD size = 1; + + GetUserNameA (tmp, &size); + my_name = xmalloc (size); + if (!GetUserNameA (my_name, &size)) + gc_error (1,0, "error getting current user name: %s", + w32_strerror (-1)); + } + + if (!strcmp (user, my_name)) + return 1; /* Found. */ + } +#else /*!HAVE_W32_SYSTEM*/ /* First check whether the user matches. */ if (*user) { @@ -2683,6 +2722,7 @@ { static char *my_group; static char **my_supgroups; + int n; if (!my_group) { @@ -2719,7 +2759,7 @@ if (!strcmp (group, my_supgroups[n])) return 1; /* Found. */ } -#endif +#endif /*!HAVE_W32_SYSTEM*/ return 0; /* No match. */ } From cvs at cvs.gnupg.org Tue Jun 26 21:02:33 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Tue, 26 Jun 2007 21:02:33 +0200 Subject: [svn] pinentry - r160 - in trunk: . w32 Message-ID: Author: wk Date: 2007-06-26 21:02:02 +0200 (Tue, 26 Jun 2007) New Revision: 160 Modified: trunk/ChangeLog trunk/w32/Makefile.am trunk/w32/main.c Log: Fixed focus issues. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-06-20 14:29:22 UTC (rev 159) +++ trunk/ChangeLog 2007-06-26 19:02:02 UTC (rev 160) @@ -1,5 +1,16 @@ +2007-06-26 Werner Koch + + * w32/Makefile.am (pinentry_w32_LDFLAGS): Add -mconsole again. + + * w32/main.c (dlg_proc): Set focus. + (resize_button): New. No code yet. + (dlg_proc): Call it for the buttons. + (w32_cmd_handler): Restore old foreground window. + 2007-06-20 Werner Koch + * w32/Makefile.am (pinentry_w32_LDFLAGS): Remove -mconsole. + * w32/main.c (wchar_to_utf8): New. (ok_button_clicked): Use it. (utf8_to_wchar): New. Modified: trunk/w32/Makefile.am =================================================================== --- trunk/w32/Makefile.am 2007-06-20 14:29:22 UTC (rev 159) +++ trunk/w32/Makefile.am 2007-06-26 19:02:02 UTC (rev 160) @@ -29,9 +29,7 @@ pinentry_w32_SOURCES = main.c pinentry-w32.rc resource.h -# If you want to test pinnetry on the console, you should add -# -mconsole to the ldflags. -pinentry_w32_LDFLAGS = -mwindows +pinentry_w32_LDFLAGS = -mwindows -mconsole pinentry_w32_LDADD = pinentry-w32.o \ ../pinentry/libpinentry.a ../assuan/libassuan.a ../secmem/libsecmem.a Modified: trunk/w32/main.c =================================================================== --- trunk/w32/main.c 2007-06-20 14:29:22 UTC (rev 159) +++ trunk/w32/main.c 2007-06-26 19:02:02 UTC (rev 160) @@ -1,5 +1,5 @@ /* main.c - Secure W32 dialog for PIN entry. - Copyright (C) 2004 g10 Code GmbH + Copyright (C) 2004, 2007 g10 Code GmbH This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -116,7 +116,7 @@ /* Center the window CHILDWND with the desktop as its parent window. STYLE is passed as second arg to SetWindowPos.*/ -void +static void center_window (HWND childwnd, HWND style) { HWND parwnd; @@ -155,8 +155,23 @@ } +/* Resize the button so that STRING fits into it. */ +static void +resize_button (HWND hwnd, const char *string) +{ + if (!hwnd) + return; + /* FIXME: Need to figure out how to convert dialog coorddnates to + screen coordinates and how buttons should be placed. */ +/* SetWindowPos (hbutton, NULL, */ +/* 10, 180, */ +/* strlen (string+2), 14, */ +/* (SWP_NOZORDER)); */ +} + + /* Call SetDlgItemTextW with an UTF8 string. */ static void @@ -185,10 +200,12 @@ dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam) { static pinentry_t pe; + static int item; switch (msg) { case WM_INITDIALOG: + dialog_handle = dlg; pe = (pinentry_t)lparam; if (!pe) abort (); @@ -196,21 +213,34 @@ set_dlg_item_text (dlg, IDC_PINENT_DESC, pe->description); set_dlg_item_text (dlg, IDC_PINENT_TEXT, ""); if (pe->ok) - set_dlg_item_text (dlg, IDOK, pe->ok); + { + set_dlg_item_text (dlg, IDOK, pe->ok); + resize_button (GetDlgItem (dlg, IDOK), pe->ok); + } if (pe->cancel) - set_dlg_item_text (dlg, IDCANCEL, pe->cancel); + { + set_dlg_item_text (dlg, IDCANCEL, pe->cancel); + resize_button (GetDlgItem (dlg, IDCANCEL), pe->cancel); + } if (pe->error) set_dlg_item_text (dlg, IDC_PINENT_ERR, pe->error); + center_window (dlg, HWND_TOP); + if (confirm_mode) { EnableWindow (GetDlgItem (dlg, IDC_PINENT_TEXT), FALSE); SetWindowPos (GetDlgItem (dlg, IDC_PINENT_TEXT), NULL, 0, 0, 0, 0, (SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_HIDEWINDOW)); + + item = IDOK; } + else + item = IDC_PINENT_TEXT; - dialog_handle = dlg; - center_window (dlg, HWND_TOP); + if (GetDlgCtrlID ((HWND)wparam) != item) + SetFocus ( GetDlgItem (dlg, item)); + /* Fixme: There are two problems: A race condition between the two calls and more important that SetForegroundWindow will fail if a Menu is somewhere open. */ @@ -274,17 +304,26 @@ static int w32_cmd_handler (pinentry_t pe) { + HWND lastwindow = GetForegroundWindow (); + confirm_mode = !pe->pin; passphrase_ok = confirm_yes = 0; + dialog_handle = NULL; DialogBoxParam (NULL, (LPCTSTR) IDD_PINENT, GetDesktopWindow (), dlg_proc, (LPARAM)pe); - ShowWindow (dialog_handle, SW_SHOWNORMAL); - if (lock_set_foreground_window) - lock_set_foreground_window (LSFW_UNLOCK); - DestroyWindow (dialog_handle); - dialog_handle = NULL; + if (dialog_handle) + { + ShowWindow (dialog_handle, SW_SHOWNORMAL); + if (lock_set_foreground_window) + lock_set_foreground_window (LSFW_UNLOCK); + if (lastwindow) + SetForegroundWindow (lastwindow); + } + else + return -1; + if (confirm_mode) return confirm_yes; else if (passphrase_ok && pe->pin) From cvs at cvs.gnupg.org Wed Jun 27 18:50:51 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 27 Jun 2007 18:50:51 +0200 Subject: [svn] pinentry - r161 - trunk/w32 Message-ID: Author: wk Date: 2007-06-27 18:50:22 +0200 (Wed, 27 Jun 2007) New Revision: 161 Modified: trunk/w32/Makefile.am trunk/w32/main.c trunk/w32/pinentry-w32.rc Log: Revamped the SetFocus stuff. I am not sure whether this hack will work under Vista. Modified: trunk/w32/Makefile.am =================================================================== --- trunk/w32/Makefile.am 2007-06-26 19:02:02 UTC (rev 160) +++ trunk/w32/Makefile.am 2007-06-27 16:50:22 UTC (rev 161) @@ -29,7 +29,8 @@ pinentry_w32_SOURCES = main.c pinentry-w32.rc resource.h -pinentry_w32_LDFLAGS = -mwindows -mconsole +# Note: For testing you should add -mconsole to LDFLAGS. +pinentry_w32_LDFLAGS = -mwindows pinentry_w32_LDADD = pinentry-w32.o \ ../pinentry/libpinentry.a ../assuan/libassuan.a ../secmem/libsecmem.a Modified: trunk/w32/main.c =================================================================== --- trunk/w32/main.c 2007-06-26 19:02:02 UTC (rev 160) +++ trunk/w32/main.c 2007-06-27 16:50:22 UTC (rev 161) @@ -19,14 +19,15 @@ #include #include #include +#define WINVER 0x0403 /* Required for SendInput. */ #include #include "pinentry.h" #include "memory.h" #include "resource.h" +/* #include "msgcodes.h" */ - #define PGMNAME "pinentry-w32" #ifndef LSFW_LOCK @@ -43,20 +44,66 @@ static void ok_button_clicked (HWND dlg, pinentry_t pe); -/* We use gloabl variables for the state, because there should never +/* We use global variables for the state, because there should never ever be a second instance. */ static HWND dialog_handle; static int confirm_mode; static int passphrase_ok; static int confirm_yes; +static FILE *debugfp; + + /* Connect this module to the pinnetry framework. */ pinentry_cmd_handler_t pinentry_cmd_handler = w32_cmd_handler; +const char * +w32_strerror (int ec) +{ + static char strerr[256]; + + if (ec == -1) + ec = (int)GetLastError (); + FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec, + MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), + strerr, sizeof strerr - 1, NULL); + return strerr; +} +/* static HWND */ +/* show_window_hierarchy (HWND parent, int level) */ +/* { */ +/* HWND child; */ + +/* child = GetWindow (parent, GW_CHILD); */ +/* while (child) */ +/* { */ +/* char buf[1024+1]; */ +/* char name[200]; */ +/* int nname; */ +/* char *pname; */ + +/* memset (buf, 0, sizeof (buf)); */ +/* GetWindowText (child, buf, sizeof (buf)-1); */ +/* nname = GetClassName (child, name, sizeof (name)-1); */ +/* if (nname) */ +/* pname = name; */ +/* else */ +/* pname = NULL; */ +/* fprintf (debugfp, "### %*shwnd=%p (%s) `%s'\n", level*2, "", child, */ +/* pname? pname:"", buf); */ +/* show_window_hierarchy (child, level+1); */ +/* child = GetNextWindow (child, GW_HWNDNEXT); */ +/* } */ + +/* return NULL; */ +/* } */ + + + /* Convert a wchar to UTF8. Caller needs to release the string. Returns NULL on error. */ static char * @@ -155,6 +202,58 @@ } + +static void +move_mouse_and_click (HWND hwnd) +{ + RECT rect; + HDC hdc; + int wscreen, hscreen, x, y, normx, normy; + INPUT inp[3]; + int idx; + + hdc = GetDC (hwnd); + wscreen = GetDeviceCaps (hdc, HORZRES); + hscreen = GetDeviceCaps (hdc, VERTRES); + ReleaseDC (hwnd, hdc); + if (wscreen < 10 || hscreen < 10) + return; + + GetWindowRect (hwnd, &rect); + x = rect.left; + y = rect.bottom; + + normx = x * (65535 / wscreen); + if (normx < 0 || normx > 65535) + return; + normy = y * (65535 / hscreen); + if (normy < 0 || normy > 65535) + return; + + for (idx=0; idx < 3; idx++) + memset (&inp[idx], 0, sizeof inp[idx]); + + idx=0; + inp[idx].type = INPUT_MOUSE; + inp[idx].mi.dx = normx; + inp[idx].mi.dy = normy; + inp[idx].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE; + idx++; + + inp[idx].type = INPUT_MOUSE; + inp[idx].mi.dwFlags = MOUSEEVENTF_LEFTDOWN; + idx++; + + inp[idx].type = INPUT_MOUSE; + inp[idx].mi.dwFlags = MOUSEEVENTF_LEFTUP; + idx++; + + if ( SendInput (idx, inp, sizeof (INPUT)) != idx && debugfp ) + fprintf (debugfp, "SendInput failed: %s\n", w32_strerror (-1)); +} + + + /* Resize the button so that STRING fits into it. */ static void resize_button (HWND hwnd, const char *string) @@ -172,6 +271,7 @@ + /* Call SetDlgItemTextW with an UTF8 string. */ static void @@ -202,6 +302,19 @@ static pinentry_t pe; static int item; + +/* { */ +/* int idx; */ + +/* for (idx=0; msgcodes[idx].string; idx++) */ +/* if (msg == msgcodes[idx].msg) */ +/* break; */ +/* if (msgcodes[idx].string) */ +/* fprintf (debugfp, "received %s\n", msgcodes[idx].string); */ +/* else */ +/* fprintf (debugfp, "received WM_%u\n", msg); */ +/* } */ + switch (msg) { case WM_INITDIALOG: @@ -225,8 +338,6 @@ if (pe->error) set_dlg_item_text (dlg, IDC_PINENT_ERR, pe->error); - center_window (dlg, HWND_TOP); - if (confirm_mode) { EnableWindow (GetDlgItem (dlg, IDC_PINENT_TEXT), FALSE); @@ -238,14 +349,22 @@ else item = IDC_PINENT_TEXT; - if (GetDlgCtrlID ((HWND)wparam) != item) - SetFocus ( GetDlgItem (dlg, item)); - - /* Fixme: There are two problems: A race condition between the - two calls and more important that SetForegroundWindow will - fail if a Menu is somewhere open. */ - if (SetForegroundWindow (dlg) && lock_set_foreground_window) - lock_set_foreground_window (LSFW_LOCK); + center_window (dlg, HWND_TOP); + + /* Unfortunately we can't use SetForegroundWindow because there + is no easy eay to have all the calling processes do an + AllowSetForegroundWindow. What we do instead is to bad hack + by simulating a click to the Window. */ +/* if (SetForegroundWindow (dlg) && lock_set_foreground_window) */ +/* { */ +/* lock_set_foreground_window (LSFW_LOCK); */ +/* } */ + +/* show_window_hierarchy (GetDesktopWindow (), 0); */ + + ShowWindow (dlg, SW_SHOW); + move_mouse_and_click ( GetDlgItem (dlg, IDC_PINENT_PROMPT) ); + break; case WM_COMMAND: @@ -304,22 +423,21 @@ static int w32_cmd_handler (pinentry_t pe) { - HWND lastwindow = GetForegroundWindow (); +/* HWND lastwindow = GetForegroundWindow (); */ confirm_mode = !pe->pin; passphrase_ok = confirm_yes = 0; dialog_handle = NULL; - DialogBoxParam (NULL, (LPCTSTR) IDD_PINENT, + DialogBoxParam (GetModuleHandle (NULL), MAKEINTRESOURCE (IDD_PINENT), GetDesktopWindow (), dlg_proc, (LPARAM)pe); if (dialog_handle) { - ShowWindow (dialog_handle, SW_SHOWNORMAL); - if (lock_set_foreground_window) - lock_set_foreground_window (LSFW_UNLOCK); - if (lastwindow) - SetForegroundWindow (lastwindow); +/* if (lock_set_foreground_window) */ +/* lock_set_foreground_window (LSFW_UNLOCK); */ +/* if (lastwindow) */ +/* SetForegroundWindow (lastwindow); */ } else return -1; @@ -347,7 +465,11 @@ exit (EXIT_SUCCESS); } - /* We need to load a functuion because that one is only available +/* debugfp = fopen ("pinentry.log", "w"); */ +/* if (!debugfp) */ +/* debugfp = stderr; */ + + /* We need to load a function because that one is only available since W2000 but not in older NTs. */ handle = LoadLibrary ("user32.dll"); if (handle) Modified: trunk/w32/pinentry-w32.rc =================================================================== --- trunk/w32/pinentry-w32.rc 2007-06-26 19:02:02 UTC (rev 160) +++ trunk/w32/pinentry-w32.rc 2007-06-27 16:50:22 UTC (rev 161) @@ -26,12 +26,12 @@ IDD_PINENT DIALOG DISCARDABLE 0, 0, 186, 125 STYLE DS_MODALFRAME | DS_SYSMODAL | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Pinentry W32" -FONT 8, "MS Sans Serif" +CAPTION "Pinentry" +FONT 8, "MS Shell Dlg" BEGIN LTEXT "", IDC_PINENT_DESC, 6, 6, 152, 40 EDITTEXT IDC_PINENT_TEXT, 71, 56, 107, 12, ES_PASSWORD | ES_AUTOHSCROLL - DEFPUSHBUTTON "OK", IDOK, 77, 100, 50, 14 + DEFPUSHBUTTON "O&K", IDOK, 77, 100, 50, 14 PUSHBUTTON "&Cancel", IDCANCEL, 132, 100, 50, 14 LTEXT "", IDC_PINENT_PROMPT, 6, 56, 64, 12 LTEXT "", IDC_PINENT_ERR, 6, 82, 170, 9 From cvs at cvs.gnupg.org Wed Jun 27 21:59:30 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Wed, 27 Jun 2007 21:59:30 +0200 Subject: [svn] gpg-error - r194 - in trunk: . src Message-ID: Author: wk Date: 2007-06-27 21:59:00 +0200 (Wed, 27 Jun 2007) New Revision: 194 Modified: trunk/ChangeLog trunk/src/code-from-errno.c trunk/src/gpg-error.m4 Log: Minor W32 enhancements Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-05-19 22:01:45 UTC (rev 193) +++ trunk/ChangeLog 2007-06-27 19:59:00 UTC (rev 194) @@ -3,6 +3,16 @@ * lang/cl/gpg-error.lisp (gpg-err-source-t): Add :gpg-err-source-any. +2007-06-18 Werner Koch + + * src/code-from-errno.c (w32_special_errnos) [W32]: New. This is + to provide some common mappings for winsocket error codes. + (gpg_err_code_from_errno, gpg_err_code_from_syserror): Use it. + +2007-05-09 Werner Koch + + * src/gpg-error.m4: Print found version on success. + 2006-12-09 Marcus Brinkmann * src/Makefile.am (EXTRA_DIST): Add README. Modified: trunk/src/code-from-errno.c =================================================================== --- trunk/src/code-from-errno.c 2007-05-19 22:01:45 UTC (rev 193) +++ trunk/src/code-from-errno.c 2007-06-27 19:59:00 UTC (rev 194) @@ -23,11 +23,37 @@ #endif #include +#ifdef HAVE_W32_SYSTEM +#include +#endif #include #include "code-from-errno.h" +#ifdef HAVE_W32_SYSTEM +/* Under Windows socket related error codes are defined in a different + file and prefixed with "WSA". As their ranges don't overlap, we map + some of them to our usual error codes. */ +gpg_err_code_t +w32_special_errnos (int err) +{ + switch (err) + { + case WSAEADDRINUSE: return GPG_ERR_EADDRINUSE; + case WSAEADDRNOTAVAIL: return GPG_ERR_EADDRNOTAVAIL; + case WSAECONNABORTED: return GPG_ERR_ECONNABORTED; + case WSAECONNREFUSED: return GPG_ERR_ECONNREFUSED; + case WSAECONNRESET: return GPG_ERR_ECONNRESET; + case WSAENAMETOOLONG: return GPG_ERR_ENAMETOOLONG; + case WSAEHOSTDOWN: return GPG_ERR_EHOSTDOWN; + case WSAEHOSTUNREACH: return GPG_ERR_EHOSTUNREACH; + default: + return GPG_ERR_UNKNOWN_ERRNO; + } +} +#endif /*HAVE_W32_SYSTEM*/ + /* Retrieve the error code for the system error ERR. This returns GPG_ERR_UNKNOWN_ERRNO if the system error is not mapped (report this). */ @@ -42,7 +68,13 @@ idx = errno_to_idx (err); if (idx < 0) - return GPG_ERR_UNKNOWN_ERRNO; + { +#ifdef HAVE_W32_SYSTEM + return w32_special_errnos (err); +#else + return GPG_ERR_UNKNOWN_ERRNO; +#endif + } return GPG_ERR_SYSTEM_ERROR | err_code_from_index[idx]; } @@ -63,7 +95,13 @@ idx = errno_to_idx (err); if (idx < 0) - return GPG_ERR_UNKNOWN_ERRNO; + { +#ifdef HAVE_W32_SYSTEM + return w32_special_errnos (err); +#else + return GPG_ERR_UNKNOWN_ERRNO; +#endif + } return GPG_ERR_SYSTEM_ERROR | err_code_from_index[idx]; } Modified: trunk/src/gpg-error.m4 =================================================================== --- trunk/src/gpg-error.m4 2007-05-19 22:01:45 UTC (rev 193) +++ trunk/src/gpg-error.m4 2007-06-27 19:59:00 UTC (rev 194) @@ -51,7 +51,7 @@ if test $ok = yes; then GPG_ERROR_CFLAGS=`$GPG_ERROR_CONFIG $gpg_error_config_args --cflags` GPG_ERROR_LIBS=`$GPG_ERROR_CONFIG $gpg_error_config_args --libs` - AC_MSG_RESULT(yes) + AC_MSG_RESULT([yes ($gpg_error_config_version)]) ifelse([$2], , :, [$2]) else GPG_ERROR_CFLAGS="" From cvs at cvs.gnupg.org Fri Jun 29 16:42:05 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 29 Jun 2007 16:42:05 +0200 Subject: [svn] gpgme - r1218 - in trunk: doc gpgme Message-ID: Author: wk Date: 2007-06-29 16:41:35 +0200 (Fri, 29 Jun 2007) New Revision: 1218 Modified: trunk/doc/ChangeLog trunk/doc/Makefile.am trunk/gpgme/gpgme.h Log: Added target "online". Modified: trunk/doc/ChangeLog =================================================================== --- trunk/doc/ChangeLog 2007-06-05 14:47:18 UTC (rev 1217) +++ trunk/doc/ChangeLog 2007-06-29 14:41:35 UTC (rev 1218) @@ -2,6 +2,10 @@ * gpgme.texi (Advanced Key Editing): New section. +2007-05-21 Werner Koch + + * Makefile.am (online): New target. + 2007-05-18 Marcus Brinkmann * gpgme.texi (Error Strings): Fix documentation of Modified: trunk/doc/Makefile.am =================================================================== --- trunk/doc/Makefile.am 2007-06-05 14:47:18 UTC (rev 1217) +++ trunk/doc/Makefile.am 2007-06-29 14:41:35 UTC (rev 1218) @@ -23,3 +23,12 @@ info_TEXINFOS = gpgme.texi gpgme_TEXINFOS = lesser.texi + +online: gpgme.html gpgme.pdf + set -e; \ + echo "Uploading current manuals to www.gnupg.org ..."; \ + user=werner ; \ + (cd gpgme.html && rsync -vr --exclude='.svn' . \ + $${user}@cvs.gnupg.org:webspace/manuals/gpgme/ ); \ + rsync -v gpgme.pdf $${user}@cvs.gnupg.org:webspace/manuals/ + Modified: trunk/gpgme/gpgme.h =================================================================== --- trunk/gpgme/gpgme.h 2007-06-05 14:47:18 UTC (rev 1217) +++ trunk/gpgme/gpgme.h 2007-06-29 14:41:35 UTC (rev 1218) @@ -72,7 +72,7 @@ AM_PATH_GPGME macro) check that this header matches the installed library. Warning: Do not edit the next line. configure will do that for you! */ -#define GPGME_VERSION "1.1.4" +#define GPGME_VERSION "1.1.5-cvs1213" From cvs at cvs.gnupg.org Fri Jun 29 20:38:29 2007 From: cvs at cvs.gnupg.org (svn author wk) Date: Fri, 29 Jun 2007 20:38:29 +0200 Subject: [svn] w32pth - r4 - trunk Message-ID: Author: wk Date: 2007-06-29 20:38:00 +0200 (Fri, 29 Jun 2007) New Revision: 4 Modified: trunk/ChangeLog trunk/README trunk/autogen.sh trunk/w32-pth.c Log: Rewrote most of the event stuff. Modified: trunk/ChangeLog =================================================================== --- trunk/ChangeLog 2007-06-12 13:40:50 UTC (rev 3) +++ trunk/ChangeLog 2007-06-29 18:38:00 UTC (rev 4) @@ -1,3 +1,31 @@ +2007-06-29 Werner Koch + + * w32-pth.c (pth_event_add): Remove. + (pth_event_concat): Correctly implement as a ring. + (do_pth_wait): Fixed bug which let us wait only on the first + event. More or less rewrote it. + (do_pth_event_occurred): removed and repalced by direct call to + theSTATUS field of the event. + (pth_event_status): Changed implementation to accommodate the + changed do_pth_wait. + (pth_event_status): Ditto. + +2007-06-28 Werner Koch + + * w32-pth.c (sig_handler): Ignore the logoff and close event. + (do_pth_event_body): Properly ignore the static mode. + (do_pth_event_body): Implement PTH_EVENT_SELECT. + (wait_select_thread): New. + (pth_select_ev): Support ev_extra. + +2007-06-25 Werner Koch + + * w32-pth.c (pth_mutex_init): Remove superfluous free. + +2007-06-15 Werner Koch + + * autogen.sh: Use = and not == in test to be POSIXly correct. + 2007-05-30 Werner Koch Package created. Modified: trunk/README =================================================================== --- trunk/README 2007-06-12 13:40:50 UTC (rev 3) +++ trunk/README 2007-06-29 18:38:00 UTC (rev 4) @@ -10,7 +10,16 @@ It is currently limited to what GnuPG 2.0 requires. -Thisng we need to implement: +Thing we need to implement: pth_select_ev - EV is currently ignored. + +Missing stuff: + + PTH_MODE_STATIC is known but ignored. + PTH_MODE_REUSE + PTH_MODE_CHAIN + + as well as many more things. + Modified: trunk/autogen.sh =================================================================== --- trunk/autogen.sh 2007-06-12 13:40:50 UTC (rev 3) +++ trunk/autogen.sh 2007-06-29 18:38:00 UTC (rev 4) @@ -30,7 +30,7 @@ DIE=no FORCE= -if test "$1" == "--force"; then +if test x"$1" = x"--force"; then FORCE=" --force" shift fi @@ -76,7 +76,7 @@ fi ./configure --enable-maintainer-mode --prefix=${w32root} \ - --host=${host} --build=${build} + --host=${host} --build=${build} "$@" exit $? fi Modified: trunk/w32-pth.c =================================================================== --- trunk/w32-pth.c 2007-06-12 13:40:50 UTC (rev 3) +++ trunk/w32-pth.c 2007-06-29 18:38:00 UTC (rev 4) @@ -33,6 +33,7 @@ #include #include #include +#include /* We don't want to have any Windows specific code in the header, thus we use a macro which defaults to a compatible type in w32-pth.h. */ @@ -70,27 +71,42 @@ /* Events are store in a double linked event ring. */ struct pth_event_s { - struct pth_event_s * next; - struct pth_event_s * prev; - HANDLE hd; + struct pth_event_s *next; + struct pth_event_s *prev; + HANDLE hd; /* The event object. */ + int u_type; /* The type of the event. */ union { - struct sigset_s * sig; - int fd; - struct timeval tv; - pth_mutex_t * mx; + int fd; /* Used for PTH_EVENT_FD. */ + struct + { + int *rc; + int nfd; + fd_set *rfds; + fd_set *wfds; + fd_set *efds; + } sel; /* Used for PTH_EVENT_SELECT. */ + struct + { + struct sigset_s *set; + int *signo; + } sig; /* Used for PTH_EVENT_SIGS. */ + struct timeval tv; /* Used for PTH_EVENT_TIME. */ + pth_mutex_t *mx; /* Used for PTH_EVENT_MUTEX. */ } u; - int * val; - int u_type; - int flags; + unsigned int flags; /* Flags used to further describe an event. + This is the bit wise combination of + PTH_MODE_* or PTH_UNTIL_*. */ + pth_status_t status; /* Current status of the event. */ }; +/* Attribute object for threads. */ struct pth_attr_s { unsigned int flags; unsigned int stack_size; - char * name; + char *name; }; @@ -113,8 +129,8 @@ static pth_event_t do_pth_event (unsigned long spec, ...); static unsigned int do_pth_waitpid (unsigned pid, int * status, int options); static int do_pth_wait (pth_event_t ev); -static int do_pth_event_status (pth_event_t ev); static void *launch_thread (void * ctx); +static int do_pth_event_free (pth_event_t ev, int mode); @@ -323,7 +339,6 @@ } else if (n == -1) { - DWORD nwrite; char strerr[256]; if (DBG_ERROR) @@ -338,30 +353,90 @@ int -pth_select (int nfds, fd_set * rfds, fd_set * wfds, fd_set * efds, +pth_select (int nfd, fd_set * rfds, fd_set * wfds, fd_set * efds, const struct timeval * timeout) { int n; implicit_init (); enter_pth (__FUNCTION__); - n = select (nfds, rfds, wfds, efds, timeout); + n = select (nfd, rfds, wfds, efds, timeout); leave_pth (__FUNCTION__); return n; } int -pth_select_ev (int nfds, fd_set * rfds, fd_set * wfds, fd_set * efds, - const struct timeval * timeout, pth_event_t ev_extra) +pth_select_ev (int nfd, fd_set *rfds, fd_set *wfds, fd_set *efds, + const struct timeval *timeout, pth_event_t ev_extra) { - int n; + int rc; + pth_event_t ev; + pth_event_t ev_time = NULL; + int selected; implicit_init (); enter_pth (__FUNCTION__); - n = select (nfds, rfds, wfds, efds, timeout); + + ev = do_pth_event (PTH_EVENT_SELECT, &rc, nfd, rfds, wfds, efds); + if (!ev) + { + leave_pth (__FUNCTION__); + return -1; + } + if (timeout) + { + ev_time = do_pth_event (PTH_EVENT_TIME, + pth_timeout (timeout->tv_sec, timeout->tv_usec)); + if (!ev_time) + { + rc = -1; + goto leave; + } + pth_event_concat (ev, ev_time, NULL); + } + if (ev_extra) + pth_event_concat (ev, ev_extra, NULL); + + do + { + rc = do_pth_wait (ev); + if (rc < 0) + goto leave; + } + while (!rc); + + if (ev_extra) + pth_event_isolate (ev_extra); + if (timeout) + pth_event_isolate (ev_time); + + /* Fixme: We should check whether select failed and return EBADF in + this case. */ + selected = (ev && ev->status == PTH_STATUS_OCCURRED); + if (timeout && (ev_time && ev_time->status == PTH_STATUS_OCCURRED)) + { + selected = 1; + if (rfds) + FD_ZERO(rfds); + if (wfds) + FD_ZERO(wfds); + if (efds) + FD_ZERO(efds); + rc = 0; + } + if (ev_extra && !selected) + { + rc = -1; + errno = EINTR; + } + + leave: + do_pth_event_free (ev, PTH_FREE_THIS); + do_pth_event_free (ev_time, PTH_FREE_THIS); + leave_pth (__FUNCTION__); - return n; + return rc; } @@ -448,7 +523,7 @@ if (ev_extra) { pth_event_isolate (ev); - if (do_pth_event_status (ev) != PTH_STATUS_OCCURRED) + if (ev && ev->status != PTH_STATUS_OCCURRED) { pth_fdmode (fd, fdmode); leave_pth (__FUNCTION__); @@ -562,8 +637,6 @@ *mutex = CreateMutex (&sa, FALSE, NULL); if (!*mutex) { - free (*mutex); - *mutex = NULL; leave_pth (__FUNCTION__); return FALSE; } @@ -829,7 +902,10 @@ { case CTRL_C_EVENT: pth_signo = SIGINT; break; case CTRL_BREAK_EVENT: pth_signo = SIGTERM; break; + default: + return FALSE; } + /* Fixme: We can keep only track of one signal at a time. */ SetEvent (pth_signo_ev); if (DBG_INFO) fprintf (stderr, "%s: sig_handler=%d\n", log_get_prefix (NULL), pth_signo); @@ -844,18 +920,38 @@ pth_event_t ev; int rc; + if ((spec & (PTH_MODE_CHAIN|PTH_MODE_REUSE))) + { + if (DBG_ERROR) + fprintf (stderr, "%s: pth_event spec=%lu - not supported\n", + log_get_prefix (NULL), spec); + return NULL; /* Not supported. */ + } + if (DBG_INFO) fprintf (stderr, "%s: pth_event spec=%lu\n", log_get_prefix (NULL), spec); + ev = calloc (1, sizeof *ev); if (!ev) return NULL; + + /* We don't support static yet but we need to consume the + argument. */ + if ( (spec & PTH_MODE_STATIC) ) + { + ev->flags |= PTH_MODE_STATIC; + va_arg (arg, pth_key_t); + } + + ev->status = PTH_STATUS_PENDING; + if (spec == 0) ; else if (spec & PTH_EVENT_SIGS) { - ev->u.sig = va_arg (arg, struct sigset_s *); ev->u_type = PTH_EVENT_SIGS; - ev->val = va_arg (arg, int *); + ev->u.sig.set = va_arg (arg, struct sigset_s *); + ev->u.sig.signo = va_arg (arg, int *); rc = SetConsoleCtrlHandler (sig_handler, TRUE); if (DBG_INFO) fprintf (stderr, "%s: pth_event: sigs rc=%d\n", @@ -865,10 +961,7 @@ { if (spec & PTH_UNTIL_FD_READABLE) ev->flags |= PTH_UNTIL_FD_READABLE; - if (spec & PTH_MODE_STATIC) - ev->flags |= PTH_MODE_STATIC; ev->u_type = PTH_EVENT_FD; - va_arg (arg, pth_key_t); ev->u.fd = va_arg (arg, int); if (DBG_INFO) fprintf (stderr, "%s: pth_event: fd=%d\n", @@ -877,9 +970,6 @@ else if (spec & PTH_EVENT_TIME) { pth_time_t t; - if (spec & PTH_MODE_STATIC) - ev->flags |= PTH_MODE_STATIC; - va_arg (arg, pth_key_t); t = va_arg (arg, pth_time_t); ev->u_type = PTH_EVENT_TIME; ev->u.tv.tv_sec = t.tv_sec; @@ -887,16 +977,25 @@ } else if (spec & PTH_EVENT_MUTEX) { - va_arg (arg, pth_key_t); ev->u_type = PTH_EVENT_MUTEX; ev->u.mx = va_arg (arg, pth_mutex_t*); } - + else if (spec & PTH_EVENT_SELECT) + { + ev->u_type = PTH_EVENT_SELECT; + ev->u.sel.rc = va_arg (arg, int *); + ev->u.sel.nfd = va_arg (arg, int); + ev->u.sel.rfds = va_arg (arg, fd_set *); + ev->u.sel.wfds = va_arg (arg, fd_set *); + ev->u.sel.efds = va_arg (arg, fd_set *); + } + + /* Create an Event which needs to be manually reset. */ memset (&sa, 0, sizeof sa); sa.bInheritHandle = TRUE; sa.lpSecurityDescriptor = NULL; sa.nLength = sizeof sa; - ev->hd = CreateEvent (&sa, FALSE, FALSE, NULL); + ev->hd = CreateEvent (&sa, TRUE, FALSE, NULL); if (!ev->hd) { free (ev); @@ -939,34 +1038,33 @@ } -static void -pth_event_add (pth_event_t root, pth_event_t node) -{ - pth_event_t n; - - for (n=root; n->next; n = n->next) - ; - n->next = node; -} - - pth_event_t -pth_event_concat (pth_event_t evf, ...) +pth_event_concat (pth_event_t head, ...) { - pth_event_t evn; + pth_event_t ev, next, last, tmp; va_list ap; - if (!evf) + if (!head) return NULL; implicit_init (); - va_start (ap, evf); - while ((evn = va_arg(ap, pth_event_t)) != NULL) - pth_event_add (evf, evn); + ev = head; + last = head->next; + va_start (ap, head); + while ( (next = va_arg (ap, pth_event_t))) + { + ev->next = next; + tmp = next->prev; + next->prev = ev; + ev = tmp; + } va_end (ap); - return evf; + ev->next = last; + last->prev = ev; + + return head; } @@ -1054,91 +1152,43 @@ /* } */ -static int -sigpresent (struct sigset_s * ss, int signo) -{ +/* static int */ +/* sigpresent (struct sigset_s * ss, int signo) */ +/* { */ /* int i; */ /* for (i=0; i < ss->idx; i++) { */ /* if (ss->sigs[i] == signo) */ /* return 1; */ /* } */ /* FIXME: See how to implement it. */ - return 0; -} +/* return 0; */ +/* } */ -static int -do_pth_event_occurred (pth_event_t ev) + +int +pth_event_status (pth_event_t ev) { - int ret; + int ret; if (!ev) return 0; - - ret = 0; - switch (ev->u_type) - { - case 0: - if (WaitForSingleObject (ev->hd, 0) == WAIT_OBJECT_0) - ret = 1; - break; - - case PTH_EVENT_SIGS: - if (sigpresent (ev->u.sig, pth_signo) && - WaitForSingleObject (pth_signo_ev, 0) == WAIT_OBJECT_0) - { - if (DBG_INFO) - fprintf (stderr, "%s: pth_event_occurred: sig signaled.\n", - log_get_prefix (NULL)); - (*ev->val) = pth_signo; - ret = 1; - } - break; - - case PTH_EVENT_FD: - if (WaitForSingleObject (ev->hd, 0) == WAIT_OBJECT_0) - ret = 1; - break; - } - - return ret; -} - - -int -pth_event_occurred (pth_event_t ev) -{ - int ret; - implicit_init (); enter_pth (__FUNCTION__); - ret = do_pth_event_occurred (ev); + ret = ev? ev->status : 0;; leave_pth (__FUNCTION__); return ret; } -static int -do_pth_event_status (pth_event_t ev) -{ - if (!ev) - return 0; - if (do_pth_event_occurred (ev)) - return PTH_STATUS_OCCURRED; - return 0; -} - int -pth_event_status (pth_event_t ev) +pth_event_occurred (pth_event_t ev) { - if (!ev) - return 0; - if (pth_event_occurred (ev)) - return PTH_STATUS_OCCURRED; - return 0; + return pth_event_status (ev) == PTH_STATUS_OCCURRED; } + static int do_pth_event_free (pth_event_t ev, int mode) { @@ -1252,19 +1302,7 @@ } -static void -free_helper_threads (HANDLE *waitbuf, int *hdidx, int n) -{ - int i; - for (i=0; i < n; i++) - { - CloseHandle (waitbuf[hdidx[i]]); - waitbuf[hdidx[i]] = NULL; - } -} - - static void * wait_fd_thread (void * ctx) { @@ -1293,13 +1331,30 @@ } +static void * +wait_select_thread (void * ctx) +{ + pth_event_t ev = ctx; + + *ev->u.sel.rc = select (ev->u.sel.nfd, + ev->u.sel.rfds, ev->u.sel.wfds, ev->u.sel.efds,NULL); + SetEvent (ev->hd); + if (DBG_INFO) + fprintf (stderr, "%s: wait_select_thread: exit.\n", log_get_prefix (NULL)); + ExitThread (0); + return NULL; +} + + static int do_pth_wait (pth_event_t ev) { HANDLE waitbuf[MAXIMUM_WAIT_OBJECTS/2]; - int hdidx[MAXIMUM_WAIT_OBJECTS/2]; - DWORD n = 0; - int pos=0, i=0; + pth_event_t evarray[MAXIMUM_WAIT_OBJECTS/2]; + HANDLE threadlist[MAXIMUM_WAIT_OBJECTS/2]; + DWORD n; + int pos, idx, threadlistidx, i; + pth_event_t r; if (!ev) return 0; @@ -1310,58 +1365,105 @@ if (DBG_INFO) fprintf (stderr, "%s: pth_wait: cnt %lu\n", log_get_prefix (NULL), n); - if (ev) + + /* Set all events to pending. */ + r = ev; + do { - pth_event_t r = ev; - do + r->status = PTH_STATUS_PENDING; + r = r->next; + } + while ( r != ev); + + /* Prepare all events which requires to launch helper threads for + some types. This creates an array of handles which are lates + passed to WFMO. */ + pos = threadlistidx = 0; + r = ev; + do + { + switch (r->u_type) { - switch (r->u_type) - { - case 0: - waitbuf[pos++] = r->hd; - break; - - case PTH_EVENT_SIGS: - waitbuf[pos++] = pth_signo_ev; - if (DBG_INFO) - fprintf (stderr, "pth_wait: add signal event.\n"); - break; - - case PTH_EVENT_FD: - if (DBG_INFO) - fprintf (stderr, "pth_wait: spawn event wait thread.\n"); - hdidx[i++] = pos; - waitbuf[pos++] = spawn_helper_thread (wait_fd_thread, r); - break; - - case PTH_EVENT_TIME: - if (DBG_INFO) - fprintf (stderr, "pth_wait: spawn event timer thread.\n"); - hdidx[i++] = pos; - waitbuf[pos++] = spawn_helper_thread (wait_timer_thread, r); - break; + case PTH_EVENT_SIGS: + if (DBG_INFO) + fprintf (stderr, "pth_wait: add signal event\n"); + /* Register the global signal event. */ + evarray[pos] = ev; + waitbuf[pos++] = pth_signo_ev; + break; - case PTH_EVENT_MUTEX: - if (DBG_INFO) - fprintf (stderr, "pth_wait: ignoring mutex event.\n"); - break; - } + case PTH_EVENT_FD: + if (DBG_INFO) + fprintf (stderr, "pth_wait: spawn wait_fd_thread\n"); + evarray[pos] = ev; + waitbuf[pos] = spawn_helper_thread (wait_fd_thread, r); + threadlist[threadlistidx++] = waitbuf[pos]; + pos++; + break; + + case PTH_EVENT_TIME: + if (DBG_INFO) + fprintf (stderr, "pth_wait: spawn wait_timer_thread\n"); + evarray[pos] = ev; + waitbuf[pos] = spawn_helper_thread (wait_timer_thread, r); + threadlist[threadlistidx++] = waitbuf[pos]; + pos++; + break; + + case PTH_EVENT_SELECT: + if (DBG_INFO) + fprintf (stderr, "pth_wait: spawn wait_select_thread.\n"); + evarray[pos] = ev; + waitbuf[pos] = spawn_helper_thread (wait_select_thread, r); + threadlist[threadlistidx++] = waitbuf[pos]; + pos++; + break; + + case PTH_EVENT_MUTEX: + if (DBG_ERROR) + fprintf (stderr, "pth_wait: ignoring mutex event.\n"); + break; } - while ( r != ev ); + r = r->next; } + while ( r != ev ); + if (DBG_INFO) - fprintf (stderr, "%s: pth_wait: set %d\n", log_get_prefix (NULL), pos); + fprintf (stderr, "%s: pth_wait: WFMO n=%d\n", log_get_prefix (NULL), pos); n = WaitForMultipleObjects (pos, waitbuf, FALSE, INFINITE); - free_helper_threads (waitbuf, hdidx, i); + for (i=0; i < threadlistidx; i++) + CloseHandle (threadlist[i]); if (DBG_INFO) - fprintf (stderr, "%s: pth_wait: n %ld\n", log_get_prefix (NULL), n); + fprintf (stderr, "%s: pth_wait: WFMO returned %ld\n", + log_get_prefix (NULL), n); - if (n != WAIT_TIMEOUT) - return 1; - - return 0; + if (n >= 0 && n < pos) + { + int count; + /* At least one object has been signaled. Walk over all events + with an assigned handle and update the status. We start at N + which indicates the lowest signaled event. */ + for (count = 0, idx = n; idx < pos; idx++) + if (idx == n || WaitForSingleObject (waitbuf[idx], 0) == WAIT_OBJECT_0) + { + ResetEvent (evarray[idx]->hd); + evarray[idx]->status = PTH_STATUS_OCCURRED; + count++; + if (evarray[idx]->u_type == PTH_EVENT_SIGS) + *(evarray[idx]->u.sig.signo) = pth_signo; + } + if (DBG_INFO) + fprintf (stderr, "%s: pth_wait: %d events have been signalled\n", + log_get_prefix (NULL), count); + return count; + } + else if (n == WAIT_TIMEOUT) + return 0; + else + return -1; } + int pth_wait (pth_event_t ev) {