summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2006-09-13 17:57:30 +0200
committerWerner Koch <wk@gnupg.org>2006-09-13 17:57:30 +0200
commit9577dd45abd3e0f68403dc38a21e69bbf2c4d813 (patch)
treea75b2809f5c21b6de3994692cf1c03143dd63c66
parentdoc fixes (diff)
downloadgnupg2-9577dd45abd3e0f68403dc38a21e69bbf2c4d813.tar.xz
gnupg2-9577dd45abd3e0f68403dc38a21e69bbf2c4d813.zip
Various fixes and new features.
Enhanced gpg-connect-agent.
-rw-r--r--ChangeLog4
-rw-r--r--NEWS16
-rw-r--r--README.SVN (renamed from README.CVS)2
-rw-r--r--agent/ChangeLog8
-rw-r--r--agent/call-scd.c1
-rw-r--r--agent/preset-passphrase.c9
-rwxr-xr-xautogen.sh42
-rw-r--r--doc/ChangeLog9
-rw-r--r--doc/HACKING211
-rw-r--r--doc/gpg.texi5
-rw-r--r--doc/gpgsm.texi9
-rw-r--r--doc/tools.texi25
-rw-r--r--g10/ChangeLog4
-rw-r--r--g10/gpg.c1
-rw-r--r--sm/ChangeLog14
-rw-r--r--sm/gpgsm.c85
-rw-r--r--sm/keylist.c4
-rw-r--r--sm/server.c57
-rw-r--r--tools/ChangeLog5
-rw-r--r--tools/gpg-connect-agent.c154
20 files changed, 371 insertions, 294 deletions
diff --git a/ChangeLog b/ChangeLog
index 210943c22..d2cadef1d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-09-13 Werner Koch <wk@g10code.com>
+
+ * autogen.sh: Better detection of the cross compiler kit.
+
2006-09-06 Marcus Brinkmann <marcus@g10code.de>
* configure.ac: New automake conditional RUN_GPG_TESTS.
diff --git a/NEWS b/NEWS
index ff5feb9ae..b4eb576d8 100644
--- a/NEWS
+++ b/NEWS
@@ -1,8 +1,8 @@
Noteworthy changes in version 1.9.23
-------------------------------------------------
- * man pages for most tools are now build directly from the texinfo
- source.
+ * Regular man pages for most tools are now build directly from the
+ texinfo source.
* The gpg code from 1.4.5 has been fully merged into this release.
The configure option --enable-gpg is still required to build this
@@ -14,6 +14,18 @@ Noteworthy changes in version 1.9.23
* The scdaemon will now call a script on reader status changes.
+ * gpgsm now allows file descriptor passing for "INPUT", "OUTPUT" and
+ "MESSAGE".
+
+ * The gpgsm server may now output a key listing to the output file
+ handle. This needs to be enabled using "OPTION list-to-output=1".
+
+ * The --output option of gpgsm has now an effect on list-keys.
+
+ * New gpgsm commands --dump-chain and list-chain.
+
+ * gpg-connect-agent has new options to utilize descriptor passing.
+
Noteworthy changes in version 1.9.22 (2006-07-27)
-------------------------------------------------
diff --git a/README.CVS b/README.SVN
index ae17923bd..af4f49d7d 100644
--- a/README.CVS
+++ b/README.SVN
@@ -1,4 +1,4 @@
-If you are building from CVS, run the script
+If you are building from Subversion, run the script
./autogen.sh
diff --git a/agent/ChangeLog b/agent/ChangeLog
index 0db76684a..714ce15cc 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -1,3 +1,11 @@
+2006-09-13 Werner Koch <wk@g10code.com>
+
+ * preset-passphrase.c (main) [W32]: Check for WSAStartup error.
+
+2006-09-08 Werner Koch <wk@g10code.com>
+
+ * call-scd.c: Add signal.h as we are referencing SIGUSR2.
+
2006-09-06 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (AM_CFLAGS): Add $(GPG_ERR_CFLAGS).
diff --git a/agent/call-scd.c b/agent/call-scd.c
index 3dc869137..1c22ab364 100644
--- a/agent/call-scd.c
+++ b/agent/call-scd.c
@@ -27,6 +27,7 @@
#include <ctype.h>
#include <assert.h>
#include <unistd.h>
+#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#ifndef HAVE_W32_SYSTEM
diff --git a/agent/preset-passphrase.c b/agent/preset-passphrase.c
index 8f8f60e76..1b54248a5 100644
--- a/agent/preset-passphrase.c
+++ b/agent/preset-passphrase.c
@@ -281,10 +281,15 @@ main (int argc, char **argv)
#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
- doen twice, like when Pth is used too. */
+ done twice, like when Pth is used too. */
{
WSADATA wsadat;
- WSAStartup (0x202, &wsadat);
+ if (WSAStartup (0x202, &wsadat) )
+ {
+ log_error ("error initializing socket library: ec=%d\n",
+ (int)WSAGetLastError () );
+ return 2;
+ }
}
#endif
diff --git a/autogen.sh b/autogen.sh
index aaf0d0ea4..29e19ea14 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -55,36 +55,32 @@ if test "$1" = "--build-w32"; then
[ -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; 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
if ! head $tsdir/config.log | grep "$host" >/dev/null; then
- echo "Pease run a 'make distclean' first" >&2
+ echo "Please run a 'make distclean' first" >&2
exit 1
fi
fi
./configure --enable-maintainer-mode --prefix=${w32root} \
- --host=i586-mingw32msvc --build=${build} \
+ --host=${host} --build=${build} \
--with-gpg-error-prefix=${w32root} \
--with-ksba-prefix=${w32root} \
--with-libgcrypt-prefix=${w32root} \
@@ -93,10 +89,6 @@ if test "$1" = "--build-w32"; then
--with-pth-prefix=${w32root} \
--disable-gpg
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 *******
diff --git a/doc/ChangeLog b/doc/ChangeLog
index ae2e15743..832753d66 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,12 @@
+2006-09-13 Werner Koch <wk@g10code.com>
+
+ * gpg.texi (GPG Esoteric Options): Fixed typo in
+ --require-cross-certification and made it the default.
+
+2006-09-11 Werner Koch <wk@g10code.com>
+
+ * HACKING: Cleaned up.
+
2006-09-08 Werner Koch <wk@g10code.com>
* yat2m.c (parse_file): Ignore @node lines immediately.
diff --git a/doc/HACKING b/doc/HACKING
index 5efb6c947..07f09c56b 100644
--- a/doc/HACKING
+++ b/doc/HACKING
@@ -6,76 +6,6 @@
===> Under construction <=======
-SOURCE FILES
-============
-
-Here is a list of directories with source files:
-
-jnlib/ utility functions
-kbx/ keybox library
-g10/ the gpg program here called gpg2
-sm/ the gpgsm program
-agent/ the gpg-agent
-scd/ the smartcard daemon
-doc/ documentation
-
-
-
-
-CVS Access
-==========
-
-NOTE: CVS access has been disabled while we are migrating to Subversion.
-Watch www.gnupg.org for instarctions on how to use the Subversion repository.
-
-Anonymous read-only CVS access is available:
-
- cvs -z3 -d :pserver:anoncvs@cvs.gnupg.org:/cvs/gnupg login
-
-use the password "anoncvs". To check out the the complete
-archive use:
-
- cvs -z3 -d :pserver:anoncvs@cvs.gnupg.org:/cvs/gnupg \
- checkout -R STABLE-BRANCH-1-0 gnupg
-
-This service is provided to help you in hunting bugs and not to deliver
-stable snapshots; it may happen that it even does not compile, so please
-don't complain. CVS may put a high load on a server, so please don't poll
-poll for new updates but wait for an announcement; to receive this you may
-want to subscribe to:
-
- gnupg-commit-watchers@gnupg.org
-
-by sending a mail with subject "subscribe" to
-
- gnupg-commit-watchers-request@gnupg.org
-
-
-You must run scripts/autogen.sh before doing the ./configure,
-as this creates some needed while which are not in the CVS.
-autogen.sh should checks that you have all required tools
-installed.
-
-
-RSYNC access
-============
-The FTP archive is also available by anonymous rsync. A daily snapshot
-of the CVS head revision is also available. See rsync(1) and try
-"rsync ftp.gnupg.org::" to see available resources.
-
-
-
-Special Tools
-=============
-Documentation is based on the docbook DTD. Actually we have only the
-man page for now. To build a man page you need the docbook-to-man
-tool and all the other thinks needed for SGML processing. Debian
-comes with the docbook tools and you only need this docbook-to-man
-script which is comes with gtk-doc or download it from
-ftp.openit.de:/pub/devel/sgml. If you don't have it everything
-should still work fine but you will have only a dummy man page.
-
-
RFCs
====
@@ -98,44 +28,23 @@ RFCs
-Debug Flags
------------
-Use the option "--debug n" to output debug information. This option
-can be used multiple times, all values are ORed; n maybe prefixed with
-0x to use hex-values.
-
- value used for
- ----- ----------------------------------------------
- 1 packet reading/writing
- 2 MPI details
- 4 ciphers and primes (may reveal sensitive data)
- 8 iobuf filter functions
- 16 iobuf stuff
- 32 memory allocation stuff
- 64 caching
- 128 show memory statistics at exit
- 256 trust verification stuff
-
-
-
-
Directory Layout
----------------
- ./ Readme, configure
- ./scripts Scripts needed by configure and others
- ./doc Documentation
- ./util General purpose utility function
- ./mpi Multi precision integer library
- ./cipher Cryptographic functions
- ./g10 GnuPG application
- ./tools Some helper and demo programs
- ./keybox The keybox library (under construction)
- ./gcrypt Stuff needed to build libgcrypt (under construction)
+ ./ Readme, configure
+ ./agent Gpg-agent and related tools
+ ./doc Documentation
+ ./doc Documentation
+ ./g10 Gpg program here called gpg2
+ ./jnlib Utility functions
+ ./kbx Keybox library
+ ./scd Smartcard daemon
+ ./scripts Scripts needed by configure and others
+ ./sm Gpgsm program
Detailed Roadmap
----------------
-g10/g10.c Main module with option parsing and all the stuff you have
+g10/gpg.c Main module with option parsing and all the stuff you have
to do on startup. Also has the exout handler and some
helper functions.
g10/sign.c Create signature and optionally encrypt
@@ -208,17 +117,28 @@ Memory allocation
-----------------
Use only the functions:
- m_alloc()
- m_alloc_clear()
- m_strdup()
- m_free()
-
-If you want to store a passphrase or some other sensitive data you may
-want to use m_alloc_secure() instead of m_alloc(), as this puts the data
-into a memory region which is protected from swapping (on some platforms).
-m_free() works for both. This functions will not return if there is not
-enough memory available.
-
+ xmalloc
+ xmalloc_secure
+ xtrymalloc
+ xtrymalloc_secure
+ xcalloc
+ xcalloc_secure
+ xtrycalloc
+ xtrycalloc_secure
+ xrealloc
+ xtryrealloc
+ xstrdup
+ xtrystrdup
+ xfree
+
+
+The *secure versions allocated memory in the secure memory. That is,
+swapping out of this memory is avoided and is gets overwritten on
+free. Use this for passphrases, session keys and other sensitive
+material. This memory set aside for secure memory is linited to a few
+k. In general the function don't print a memeory message and
+terminate the process if there is not enough memory available. The
+"try" versions of the functions return NULL instead.
Logging
@@ -254,68 +174,3 @@ the other way: constructing messages using pushed filters but it may be
easier to understand.
-How to use the message digest functions
----------------------------------------
-cipher/md.c implements an interface to hash (message digest functions).
-
-a) If you have a common part of data and some variable parts
- and you need to hash of the concatenated parts, you can use this:
- md = md_open(...)
- md_write( md, common_part )
- md1 = md_copy( md )
- md_write(md1, part1)
- md_final(md1);
- digest1 = md_read(md1)
- md2 = md_copy( md )
- md_write(md2, part2)
- md_final(md2);
- digest2 = md_read(md2)
-
- An example are key signatures; the key packet is the common part
- and the user-id packets are the variable parts.
-
-b) If you need a running digest you should use this:
- md = md_open(...)
- md_write( md, part1 )
- digest_of_part1 = md_digest( md );
- md_write( md, part2 )
- digest_of_part1_cat_part2 = md_digest( md );
- ....
-
-Both methods may be combined. [Please see the source for the real syntax]
-
-
-
-
-How to use the cipher functions
--------------------------------
-cipher/cipher.c implements the interface to symmetric encryption functions.
-As usual you have a function to open a cipher (which returns a handle to be used
-with all other functions), some functions to set the key and other stuff and
-a encrypt and decrypt function which does the real work. You probably know
-how to work with files - so it should really be easy to work with these
-functions. Here is an example:
-
- CIPHER_HANDLE hd;
-
- hd = cipher_open( CIPHER_ALGO_TWOFISH, CIPHER_MODE_CFB, 0 );
- if( !hd )
- oops( use other function to check for the real error );
- rc = cipher_setkey( hd, key256bit, 32 ) )
- if( rc )
- oops( weak key or something like this );
- cipher_setiv( hd, some_IV_or_NULL_for_all_zeroes );
- cipher_encrypt( hd, plain, cipher, size );
- cipher_close( hd );
-
-
-
-How to use the public key functions
------------------------------------
-cipher/pubkey.c implements the interface to asymmetric encryption and
-signature functions. This is basically the same as with the symmetric
-counterparts, but due to their nature it is a little bit more complicated.
-
- [Give an example]
-
-
diff --git a/doc/gpg.texi b/doc/gpg.texi
index 219ff15f4..f744c1a22 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -2178,12 +2178,11 @@ content of an encrypted message; using this option you can do this without
handing out the secret key.
@item --require-cross-certification
-@itemx --no-require-certification
+@itemx --no-require-cross-certification
When verifying a signature made from a subkey, ensure that the cross
certification "back signature" on the subkey is present and valid.
This protects against a subtle attack against subkeys that can sign.
-Currently defaults to --no-require-cross-certification, but will be
-changed to --require-cross-certification in the future.
+Defaults to --require-cross-certification for @command{gpg2}.
@item --ask-sig-expire
@itemx --no-ask-sig-expire
diff --git a/doc/gpgsm.texi b/doc/gpgsm.texi
index 5de9efbe9..a7a24022f 100644
--- a/doc/gpgsm.texi
+++ b/doc/gpgsm.texi
@@ -184,11 +184,20 @@ is available.
List certificates matching @var{pattern} using an external server. This
utilizes the @code{dirmngr} service.
+@item --list-chain
+@opindex list-chain
+Same as @option{--list-keys} but also prints all keys making up the chain.
+
+
@item --dump-keys
@opindex dump-keys
List all available certificates stored in the local key database using a
format useful mainly for debugging.
+@item --dump-chain
+@opindex dump-chain
+Same as @option{--dump-keys} but also prints all keys making up the chain.
+
@item --dump-secret-keys
@opindex dump-secret-keys
List all available certificates for which a corresponding a secret key
diff --git a/doc/tools.texi b/doc/tools.texi
index 4e9a80d8e..dec548905 100644
--- a/doc/tools.texi
+++ b/doc/tools.texi
@@ -989,6 +989,22 @@ Connect to socket @var{name} assuming this is an Assuan style server.
Do not run any special initializations or environment checks. This may
be used to directly connect to any Assuan style socket server.
+@item -E
+@itemx --exec
+@opindex exec
+Take the rest of the command line as a program and it's arguments and
+execute it as an assuan server. Here is how you would run @command{gpgsm}:
+@smallexample
+ gpg-connect-agent --exec gpgsm --server
+@end smallexample
+
+
+@item --no-ext-connect
+@opindex no-ext-connect
+When using @option{-S} or @option{--exec}, @command{gpg-connect-agent}
+connects to the assuan server in extended mode to allow descriptor
+passing. This option makes it use the old mode.
+
@end table
@mansect control commands
@@ -1020,6 +1036,15 @@ Print all definitions
@item /cleardef
Delete all definitions
+@item /sendfd @var{file} @var{mode}
+Open @var{file} in @var{mode} (which needs to be a valid @code{fopen}
+mode string) and send the file descriptor to the server. This is
+usually followed by a command like @code{INPUT FD} to set the
+input source for other commands.
+
+@item /recvfd
+Not yet implemented.
+
@item /help
Print a list of available control commands.
diff --git a/g10/ChangeLog b/g10/ChangeLog
index c6de096e2..99d73a6b7 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -1,3 +1,7 @@
+2006-09-13 Werner Koch <wk@g10code.com>
+
+ * gpg.c (main): Made --require-cross-certification the default.
+
2006-09-06 Marcus Brinkmann <marcus@g10code.de>
* Makefile.am (gpg2_LDADD, gpgv2_LDADD): Replace -lassuan and
diff --git a/g10/gpg.c b/g10/gpg.c
index 826cdd305..79617ee3c 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -1834,6 +1834,7 @@ main (int argc, char **argv )
opt.rfc2440_text=1;
opt.def_sig_expire="0";
opt.def_cert_expire="0";
+ opt.require_cross_cert = 1;
set_homedir ( default_homedir () );
/* Check whether we have a config file on the command line. */
diff --git a/sm/ChangeLog b/sm/ChangeLog
index 3c60f6f9c..7bf2c0713 100644
--- a/sm/ChangeLog
+++ b/sm/ChangeLog
@@ -1,3 +1,17 @@
+2006-09-13 Werner Koch <wk@g10code.com>
+
+ * keylist.c (list_internal_keys): Print marker line to FP and not
+ to stdout.
+
+ * gpgsm.c (main): All list key list commands now make ose of
+ --output. Cleaned up calls to list modes. New command
+ --dump-chain. Renamed --list-sigs to --list-chain and added an
+ alias for the old one.
+
+ * server.c (cmd_message): Changed to use assuan_command_parse_fd.
+ (option_handler): New option list-to-output.
+ (do_listkeys): Use it.
+
2006-09-06 Werner Koch <wk@g10code.com>
* gpgsm.h (OUT_OF_CORE): Removed and changed all callers to
diff --git a/sm/gpgsm.c b/sm/gpgsm.c
index aaf5c42fe..49a56cd7c 100644
--- a/sm/gpgsm.c
+++ b/sm/gpgsm.c
@@ -80,7 +80,7 @@ enum cmd_and_opt_values {
aVerify,
aVerifyFiles,
aListExternalKeys,
- aListSigs,
+ aListChain,
aSendKeys,
aRecvKeys,
aExport,
@@ -93,6 +93,7 @@ enum cmd_and_opt_values {
aPasswd,
aGPGConfList,
aDumpKeys,
+ aDumpChain,
aDumpSecretKeys,
aDumpExternalKeys,
aKeydbClearSomeCertFlags,
@@ -251,8 +252,7 @@ static ARGPARSE_OPTS opts[] = {
{ aListKeys, "list-keys", 256, N_("list keys")},
{ aListExternalKeys, "list-external-keys", 256, N_("list external keys")},
{ aListSecretKeys, "list-secret-keys", 256, N_("list secret keys")},
- { aListSigs, "list-sigs", 256, N_("list certificate chain")},
- { aListSigs, "check-sigs",256, "@"},
+ { aListChain, "list-chain", 256, N_("list certificate chain")},
{ oFingerprint, "fingerprint", 256, N_("list keys and fingerprints")},
{ aKeygen, "gen-key", 256, N_("generate a new key pair")},
{ aDeleteKey, "delete-key",256, N_("remove key from the public keyring")},
@@ -269,6 +269,7 @@ static ARGPARSE_OPTS opts[] = {
{ aGPGConfList, "gpgconf-list", 256, "@" },
{ aDumpKeys, "dump-keys", 256, "@"},
+ { aDumpChain, "dump-chain", 256, "@"},
{ aDumpExternalKeys, "dump-external-keys", 256, "@"},
{ aDumpSecretKeys, "dump-secret-keys", 256, "@"},
{ aKeydbClearSomeCertFlags, "keydb-clear-some-cert-flags", 256, "@"},
@@ -428,9 +429,11 @@ static ARGPARSE_OPTS opts[] = {
{ oWithValidation, "with-validation", 0, "@"},
{ oWithMD5Fingerprint, "with-md5-fingerprint", 0, "@"},
{ oWithEphemeralKeys, "with-ephemeral-keys", 0, "@"},
- { aListKeys, "list-key", 0, "@" }, /* alias */
- { aListSigs, "list-sig", 0, "@" }, /* alias */
- { aListSigs, "check-sig",0, "@" }, /* alias */
+ { aListKeys, "list-key", 256, "@" }, /* alias */
+ { aListChain, "list-sig", 256, "@" }, /* alias */
+ { aListChain, "list-sigs",256, "@" }, /* alias */
+ { aListChain, "check-sig",256, "@" }, /* alias */
+ { aListChain, "check-sigs",256, "@"}, /* alias */
{ oSkipVerify, "skip-verify",0, "@" },
{ oCompressKeys, "compress-keys",0, "@"},
{ oCompressSigs, "compress-sigs",0, "@"},
@@ -930,12 +933,13 @@ main ( int argc, char **argv)
case aExport:
case aExportSecretKeyP12:
case aDumpKeys:
+ case aDumpChain:
case aDumpExternalKeys:
case aDumpSecretKeys:
case aListKeys:
case aListExternalKeys:
case aListSecretKeys:
- case aListSigs:
+ case aListChain:
case aLearnCard:
case aPasswd:
case aKeydbClearSomeCertFlags:
@@ -1518,52 +1522,43 @@ main ( int argc, char **argv)
free_strlist(sl);
break;
- case aListSigs:
- ctrl.with_chain = 1;
+ case aListChain:
+ case aDumpChain:
+ ctrl.with_chain = 1;
case aListKeys:
- for (sl=NULL; argc; argc--, argv++)
- add_to_strlist (&sl, *argv);
- gpgsm_list_keys (&ctrl, sl, stdout, (0 | (1<<6)));
- free_strlist(sl);
- break;
-
case aDumpKeys:
- for (sl=NULL; argc; argc--, argv++)
- add_to_strlist (&sl, *argv);
- gpgsm_list_keys (&ctrl, sl, stdout, (256 | (1<<6)));
- free_strlist(sl);
- break;
-
case aListExternalKeys:
- for (sl=NULL; argc; argc--, argv++)
- add_to_strlist (&sl, *argv);
- gpgsm_list_keys (&ctrl, sl, stdout,
- (0 | (1<<7)));
- free_strlist(sl);
- break;
-
case aDumpExternalKeys:
- for (sl=NULL; argc; argc--, argv++)
- add_to_strlist (&sl, *argv);
- gpgsm_list_keys (&ctrl, sl, stdout,
- (256 | (1<<7)));
- free_strlist(sl);
- break;
-
case aListSecretKeys:
- for (sl=NULL; argc; argc--, argv++)
- add_to_strlist (&sl, *argv);
- gpgsm_list_keys (&ctrl, sl, stdout, (2 | (1<<6)));
- free_strlist(sl);
- break;
-
case aDumpSecretKeys:
- for (sl=NULL; argc; argc--, argv++)
- add_to_strlist (&sl, *argv);
- gpgsm_list_keys (&ctrl, sl, stdout, (256 | 2 | (1<<6)));
- free_strlist(sl);
+ {
+ unsigned int mode;
+ FILE *fp;
+
+ switch (cmd)
+ {
+ case aListChain:
+ case aListKeys: mode = (0 | 0 | (1<<6)); break;
+ case aDumpChain:
+ case aDumpKeys: mode = (256 | 0 | (1<<6)); break;
+ case aListExternalKeys: mode = (0 | 0 | (1<<7)); break;
+ case aDumpExternalKeys: mode = (256 | 0 | (1<<7)); break;
+ case aListSecretKeys: mode = (0 | 2 | (1<<6)); break;
+ case aDumpSecretKeys: mode = (256 | 2 | (1<<6)); break;
+ default: BUG();
+ }
+
+ fp = open_fwrite (opt.outfile?opt.outfile:"-");
+ for (sl=NULL; argc; argc--, argv++)
+ add_to_strlist (&sl, *argv);
+ gpgsm_list_keys (&ctrl, sl, fp, mode);
+ free_strlist(sl);
+ if (fp != stdout)
+ fclose (fp);
+ }
break;
+
case aKeygen: /* generate a key */
log_error ("this function is not yet available from the commandline\n");
break;
diff --git a/sm/keylist.c b/sm/keylist.c
index 4b8f418b2..927bc88a6 100644
--- a/sm/keylist.c
+++ b/sm/keylist.c
@@ -1130,7 +1130,7 @@ list_cert_chain (ctrl_t ctrl, KEYDB_HANDLE hd,
/* List all internal keys or just the keys given as NAMES. MODE is a
bit vector to specify what keys are to be included; see
gpgsm_list_keys (below) for details. If RAW_MODE is true, the raw
- output mode will be used intead of the standard beautified one.
+ output mode will be used instead of the standard beautified one.
*/
static gpg_error_t
list_internal_keys (ctrl_t ctrl, STRLIST names, FILE *fp,
@@ -1229,7 +1229,7 @@ list_internal_keys (ctrl_t ctrl, STRLIST names, FILE *fp,
{
fprintf (fp, "%s\n", resname );
for (i=strlen(resname); i; i-- )
- putchar('-');
+ putc ('-', fp);
putc ('\n', fp);
lastresname = resname;
}
diff --git a/sm/server.c b/sm/server.c
index d7046c59e..16475f66e 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -44,6 +44,7 @@ struct server_local_s {
int message_fd;
int list_internal;
int list_external;
+ int list_to_output; /* Write keylistings to the output fd. */
certlist_t recplist;
certlist_t signerlist;
certlist_t default_recplist; /* As set by main() - don't release. */
@@ -171,6 +172,11 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
else
return gpg_error (GPG_ERR_ASS_PARAMETER);
}
+ else if (!strcmp (key, "list-to-output"))
+ {
+ int i = *value? atoi (value) : 0;
+ ctrl->server_local->list_to_output = i;
+ }
else if (!strcmp (key, "with-validation"))
{
int i = *value? atoi (value) : 0;
@@ -624,40 +630,33 @@ cmd_delkeys (assuan_context_t ctx, char *line)
static int
cmd_message (assuan_context_t ctx, char *line)
{
- char *endp;
+ int rc;
int fd;
ctrl_t ctrl = assuan_get_pointer (ctx);
- if (strncmp (line, "FD=", 3))
- return set_error (GPG_ERR_ASS_SYNTAX, "FD=<n> expected");
- line += 3;
- if (!digitp (line))
- return set_error (GPG_ERR_ASS_SYNTAX, "number required");
- fd = strtoul (line, &endp, 10);
- if (*endp)
- return set_error (GPG_ERR_ASS_SYNTAX, "garbage found");
+ rc = assuan_command_parse_fd (ctx, line, &fd);
+ if (rc)
+ return rc;
if (fd == -1)
return set_error (GPG_ERR_ASS_NO_INPUT, NULL);
-
ctrl->server_local->message_fd = fd;
return 0;
}
-
+/* LISTKEYS [<patterns>]
+ LISTSECRETKEYS [<patterns>]
+*/
static int
do_listkeys (assuan_context_t ctx, char *line, int mode)
{
ctrl_t ctrl = assuan_get_pointer (ctx);
- FILE *fp = assuan_get_data_fp (ctx);
+ FILE *fp;
char *p;
STRLIST list, sl;
unsigned int listmode;
gpg_error_t err;
- if (!fp)
- return set_error (GPG_ERR_ASS_GENERAL, "no data stream");
-
- /* break the line down into an STRLIST */
+ /* Break the line down into an STRLIST. */
list = NULL;
for (p=line; *p; line = p)
{
@@ -680,6 +679,21 @@ do_listkeys (assuan_context_t ctx, char *line, int mode)
}
}
+ if (ctrl->server_local->list_to_output)
+ {
+ if ( assuan_get_output_fd (ctx) == -1 )
+ return set_error (GPG_ERR_ASS_NO_OUTPUT, NULL);
+ fp = fdopen (assuan_get_output_fd (ctx), "w");
+ if (!fp)
+ return set_error (GPG_ERR_ASS_GENERAL, "fdopen() failed");
+ }
+ else
+ {
+ fp = assuan_get_data_fp (ctx);
+ if (!fp)
+ return set_error (GPG_ERR_ASS_GENERAL, "no data stream");
+ }
+
ctrl->with_colons = 1;
listmode = mode;
if (ctrl->server_local->list_internal)
@@ -688,6 +702,11 @@ do_listkeys (assuan_context_t ctx, char *line, int mode)
listmode |= (1<<7);
err = gpgsm_list_keys (assuan_get_pointer (ctx), list, fp, listmode);
free_strlist (list);
+ if (ctrl->server_local->list_to_output)
+ {
+ fclose (fp);
+ assuan_close_output_fd (ctx);
+ }
return err;
}
@@ -793,9 +812,9 @@ gpgsm_server (certlist_t default_recplist)
memset (&ctrl, 0, sizeof ctrl);
gpgsm_init_default_ctrl (&ctrl);
- /* For now we use a simple pipe based server so that we can work
- from scripts. We will later add options to run as a daemon and
- wait for requests on a Unix domain socket */
+ /* We use a pipe based server so that we can work from scripts.
+ assuan_init_pipe_server will automagically detect when we are
+ called with a socketpair and ignore FIELDES in this case. */
filedes[0] = 0;
filedes[1] = 1;
rc = assuan_init_pipe_server (&ctx, filedes);
diff --git a/tools/ChangeLog b/tools/ChangeLog
index 1b8a79345..295a574c7 100644
--- a/tools/ChangeLog
+++ b/tools/ChangeLog
@@ -1,3 +1,8 @@
+2006-09-12 Werner Koch <wk@g10code.com>
+
+ * gpg-connect-agent.c (read_and_print_response): With verbosity
+ level 2 also print comment lines.
+
2006-09-06 Werner Koch <wk@g10code.com>
* gpg-connect-agent.c: Switch everything to new Assuan error code
diff --git a/tools/gpg-connect-agent.c b/tools/gpg-connect-agent.c
index eacbd924f..31fed9504 100644
--- a/tools/gpg-connect-agent.c
+++ b/tools/gpg-connect-agent.c
@@ -41,10 +41,12 @@ enum cmd_and_opt_values
oQuiet = 'q',
oVerbose = 'v',
oRawSocket = 'S',
+ oExec = 'E',
oNoVerbose = 500,
oHomedir,
- oHex
+ oHex,
+ oNoExtConnect
};
@@ -58,6 +60,9 @@ static ARGPARSE_OPTS opts[] =
{ oQuiet, "quiet", 0, N_("quiet") },
{ oHex, "hex", 0, N_("print data out hex encoded") },
{ oRawSocket, "raw-socket", 2, N_("|NAME|connect to Assuan socket NAME")},
+ { oExec, "exec", 0, N_("run the Assuan server given on the command line")},
+ { oNoExtConnect, "no-ext-connect",
+ 0, N_("do not use extended connect mode")},
/* hidden options */
{ oNoVerbose, "no-verbose", 0, "@"},
@@ -74,6 +79,8 @@ struct
const char *homedir; /* Configuration directory name */
int hex; /* Print data lines in hex format. */
const char *raw_socket; /* Name of socket to connect in raw mode. */
+ int exec; /* Run the pgm given on the command line. */
+ unsigned int connect_flags; /* Flags used for connecting. */
} opt;
@@ -209,13 +216,68 @@ clear_definq (void)
}
+static void
+do_sendfd (assuan_context_t ctx, char *line)
+{
+ FILE *fp;
+ char *name, *mode, *p;
+ int rc, fd;
+
+ /* Get file name. */
+ name = line;
+ for (p=name; *p && !spacep (p); p++)
+ ;
+ if (*p)
+ *p++ = 0;
+ while (spacep (p))
+ p++;
+
+ /* Get mode. */
+ mode = p;
+ if (!*mode)
+ mode = "r";
+ else
+ {
+ for (p=mode; *p && !spacep (p); p++)
+ ;
+ if (*p)
+ *p++ = 0;
+ }
+
+ /* Open and send. */
+ fp = fopen (name, mode);
+ if (!fp)
+ {
+ log_error ("can't open `%s' in \"%s\" mode: %s\n",
+ name, mode, strerror (errno));
+ return;
+ }
+ fd = fileno (fp);
+
+ if (opt.verbose)
+ log_error ("file `%s' opened in \"%s\" mode, fd=%d\n",
+ name, mode, fd);
+
+ rc = assuan_sendfd (ctx, fd);
+ if (rc)
+ log_error ("sednig descriptor %d failed: %s\n", fd, gpg_strerror (rc));
+ fclose (fp);
+}
+
+
+static void
+do_recvfd (assuan_context_t ctx, char *line)
+{
+ log_info ("This command has not yet been implemented\n");
+}
+
+
/* gpg-connect-agent's entry point. */
int
main (int argc, char **argv)
{
ARGPARSE_ARGS pargs;
- const char *fname;
int no_more_options = 0;
assuan_context_t ctx;
char *line, *p;
@@ -229,6 +291,7 @@ main (int argc, char **argv)
i18n_init();
opt.homedir = default_homedir ();
+ opt.connect_flags = 1; /* Use extended connect mode. */
/* Parse the command line. */
pargs.argc = &argc;
@@ -244,6 +307,8 @@ main (int argc, char **argv)
case oHomedir: opt.homedir = pargs.r.ret_str; break;
case oHex: opt.hex = 1; break;
case oRawSocket: opt.raw_socket = pargs.r.ret_str; break;
+ case oExec: opt.exec = 1; break;
+ case oNoExtConnect: opt.connect_flags &= ~(1); break;
default: pargs.err = 2; break;
}
@@ -251,12 +316,48 @@ main (int argc, char **argv)
if (log_get_errorcount (0))
exit (2);
-
- fname = argc ? *argv : NULL;
- if (opt.raw_socket)
+ if (opt.exec)
+ {
+ if (!argc)
+ {
+ log_error (_("option \"%s\" requires a program "
+ "and optional arguments\n"), "--exec" );
+ exit (1);
+ }
+ }
+ else if (argc)
+ usage (1);
+
+ if (opt.exec && opt.raw_socket)
+ log_info (_("option \"%s\" ignored due to \"%s\"\n"),
+ "--raw-socket", "--exec");
+
+ if (opt.exec)
+ {
+ int no_close[3];
+
+ no_close[0] = fileno (stderr);
+ no_close[1] = log_get_fd ();
+ no_close[2] = -1;
+ rc = assuan_pipe_connect_ext (&ctx, *argv, (const char **)argv,
+ no_close, NULL, NULL,
+ opt.connect_flags);
+ if (rc)
+ {
+ log_error ("assuan_pipe_connect_ext failed: %s\n",
+ gpg_strerror (rc));
+ exit (1);
+ }
+
+ if (opt.verbose)
+ log_info ("server `%s' started\n", *argv);
+
+ }
+ else if (opt.raw_socket)
{
- rc = assuan_socket_connect (&ctx, opt.raw_socket, 0);
+ rc = assuan_socket_connect_ext (&ctx, opt.raw_socket, 0,
+ opt.connect_flags);
if (rc)
{
log_error ("can't connect to socket `%s': %s\n",
@@ -325,18 +426,31 @@ main (int argc, char **argv)
{
puts (p);
}
+ else if (!strcmp (cmd, "sendfd"))
+ {
+ do_sendfd (ctx, p);
+ continue;
+ }
+ else if (!strcmp (cmd, "recvfd"))
+ {
+ do_recvfd (ctx, p);
+ continue;
+ }
else if (!strcmp (cmd, "help"))
{
- puts ("Available commands:\n"
- "/echo ARGS Echo ARGS.\n"
- "/definqfile NAME FILE\n"
- " Use content of FILE for inquiries with NAME.\n"
- " NAME may be \"*\" to match any inquiry.\n"
- "/definqprog NAME PGM\n"
- " Run PGM for inquiries matching NAME and pass the\n"
- " entire line to it as arguments.\n"
- "/showdef Print all definitions.\n"
- "/cleardef Delete all definitions.\n"
+ puts (
+"Available commands:\n"
+"/echo ARGS Echo ARGS.\n"
+"/definqfile NAME FILE\n"
+" Use content of FILE for inquiries with NAME.\n"
+" NAME may be \"*\" to match any inquiry.\n"
+"/definqprog NAME PGM\n"
+" Run PGM for inquiries matching NAME and pass the\n"
+" entire line to it as arguments.\n"
+"/showdef Print all definitions.\n"
+"/cleardef Delete all definitions.\n"
+"/sendfd FILE MODE Open FILE and pass descripor to server.\n"
+"/recvfd Receive FD from server and print. \n"
"/help Print this help.");
}
else
@@ -352,7 +466,7 @@ main (int argc, char **argv)
continue;
}
if (*line == '#' || !*line)
- continue; /* Don't expect a response for a coment line. */
+ continue; /* Don't expect a response for a comment line. */
rc = read_and_print_response (ctx);
if (rc)
@@ -471,6 +585,12 @@ read_and_print_response (assuan_context_t ctx)
rc = assuan_read_line (ctx, &line, &linelen);
if (rc)
return rc;
+
+ if (opt.verbose > 1 && *line == '#')
+ {
+ fwrite (line, linelen, 1, stdout);
+ putchar ('\n');
+ }
}
while (*line == '#' || !linelen);