mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Various fixes and new features.
Enhanced gpg-connect-agent.
This commit is contained in:
parent
90af581b08
commit
9577dd45ab
@ -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.
|
||||
|
16
NEWS
16
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)
|
||||
-------------------------------------------------
|
||||
|
@ -1,4 +1,4 @@
|
||||
If you are building from CVS, run the script
|
||||
If you are building from Subversion, run the script
|
||||
|
||||
./autogen.sh
|
||||
|
@ -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).
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
42
autogen.sh
42
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 *******
|
||||
|
@ -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.
|
||||
|
207
doc/HACKING
207
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()
|
||||
xmalloc
|
||||
xmalloc_secure
|
||||
xtrymalloc
|
||||
xtrymalloc_secure
|
||||
xcalloc
|
||||
xcalloc_secure
|
||||
xtrycalloc
|
||||
xtrycalloc_secure
|
||||
xrealloc
|
||||
xtryrealloc
|
||||
xstrdup
|
||||
xtrystrdup
|
||||
xfree
|
||||
|
||||
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.
|
||||
|
||||
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]
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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. */
|
||||
|
14
sm/ChangeLog
14
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
|
||||
|
85
sm/gpgsm.c
85
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,51 +1522,42 @@ 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);
|
||||
case aDumpSecretKeys:
|
||||
{
|
||||
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 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);
|
||||
break;
|
||||
|
||||
case aKeygen: /* generate a key */
|
||||
log_error ("this function is not yet available from the commandline\n");
|
||||
|
@ -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;
|
||||
}
|
||||
|
57
sm/server.c
57
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);
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
{
|
||||
rc = assuan_socket_connect (&ctx, opt.raw_socket, 0);
|
||||
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_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);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user