diff options
45 files changed, 1300 insertions, 325 deletions
@@ -1,3 +1,12 @@ +Sat Feb 14 15:37:55 1998 Werner Koch (wk@isil.d.shuttle.de) + + * configure.in (mpi_config_done): Removed asm links caching. + +Sat Feb 14 14:02:20 1998 Werner Koch (wk@isil.d.shuttle.de) + + * configure.in (PRINTABLE_OS_NAME): New. + * acconfig.h: Likewise. + Fri Feb 13 19:43:41 1998 Werner Koch (wk@isil.d.shuttle.de) * configure.in : Fixed zlib stuff @@ -7,7 +7,7 @@ Configure options for G10 --with-zlib Forces usage of the local zlib sources. Default is to use the (sahred) library of the system. ---without-nls Disable NLS support +--disable-nls Disable NLS support --enable-m-debug Compile with the integrated malloc debugging stuff. This makes the program slower but is checks every @@ -22,7 +22,7 @@ Problems ======== If you have compile problems, use the configure options "--with-zlib" and -"--without-nls". +"--disable-nls". I cant check alls assembles files; so if you have problems assembling them (or the program crashes), simply delete the files in the mpi/<cpu> directory. @@ -1,3 +1,12 @@ +Noteworthy changes in version 0.2.7 +----------------------------------- + + * new option --dearmot for g10maint + + * option --version now conforming to the GNU standards and lists + the available ciphers, message digests and public key algorithms. + + Noteworthy changes in version 0.2.6 ----------------------------------- @@ -9,6 +9,7 @@ Daniel Eisenbud eisenbud@cs.swarthmore.edu Detlef Lannert lannert@lannert.rz.uni-duesseldorf.de Ernst Molitor ernst.molitor@uni-bonn.de Hendrik Buschkamp buschkamp@rheumanet.org +James Troup J.J.Troup@scm.brad.ac.uk Jean-loup Gailly gzip@prep.ai.mit.edu Jens Bachem bachem@rrz.uni-koeln.de Mark Adler madler@alumni.caltech.edu @@ -21,7 +22,6 @@ Walter Koch walterk@ddorf.rhein-ruhr.de Werner Koch werner.koch@guug.de Wim Vandeputte bunbun@reptile.rug.ac.be - Thanks to the German Unix User Group for providing FTP space and Martin Hamilton for hosting the mailing list. @@ -4,7 +4,6 @@ * add a way to difference between errors and eof in the underflow/flush function of iobuf. * add checking of armor trailers - * look for a way to reuse RSA signatures * remove all "Fixmes" * speed up the RIPE-MD-160 * add signal handling @@ -34,4 +33,6 @@ them to your key and because the user id which is signed by others has also be signed by you, all user-ids are bound together. + * create directory .g10 + @@ -1 +1 @@ -0.2.6 +0.2.6a diff --git a/acconfig.h b/acconfig.h index 11096eedd..1cdf9bef4 100644 --- a/acconfig.h +++ b/acconfig.h @@ -31,6 +31,7 @@ #undef VERSION #undef PACKAGE #undef G10_LOCALEDIR +#undef PRINTABLE_OS_NAME /* Define if your locale.h file contains LC_MESSAGES. */ #undef HAVE_LC_MESSAGES diff --git a/cipher/ChangeLog b/cipher/ChangeLog index e69de29bb..e915c3bcc 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -0,0 +1,7 @@ +Mon Feb 16 10:08:47 1998 Werner Koch (wk@isil.d.shuttle.de) + + * misc.c (cipher_algo_to_string): New + (pubkey_algo_to_string): New. + (digest_algo_to_string): New. + + diff --git a/cipher/Makefile.am b/cipher/Makefile.am index ad6722876..2967363b4 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -27,8 +27,7 @@ libcipher_a_SOURCES = blowfish.c \ misc.c \ smallprime.c +libcipher_a_DEPENDENCIES = @CIPHER_EXTRA_OBJS@ libcipher_a_LIBADD = @CIPHER_EXTRA_OBJS@ -$(LIBRARIES): @CIPHER_EXTRA_OBJS@ - diff --git a/cipher/Makefile.in b/cipher/Makefile.in index b8fe2a1bb..6264a0d59 100644 --- a/cipher/Makefile.in +++ b/cipher/Makefile.in @@ -112,6 +112,7 @@ libcipher_a_SOURCES = blowfish.c \ misc.c \ smallprime.c +libcipher_a_DEPENDENCIES = @CIPHER_EXTRA_OBJS@ libcipher_a_LIBADD = @CIPHER_EXTRA_OBJS@ mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = ../config.h @@ -123,7 +124,6 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ -libcipher_a_DEPENDENCIES = libcipher_a_OBJECTS = blowfish.o elgamal.o gost.o md5.o primegen.o \ random.o rmd160.o sha1.o dsa.o md.o misc.o smallprime.o AR = ar @@ -316,8 +316,6 @@ installdirs mostlyclean-generic distclean-generic clean-generic \ maintainer-clean-generic clean mostlyclean distclean maintainer-clean -$(LIBRARIES): @CIPHER_EXTRA_OBJS@ - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/cipher/misc.c b/cipher/misc.c index 7c8f2e3c7..6dcd20245 100644 --- a/cipher/misc.c +++ b/cipher/misc.c @@ -75,6 +75,21 @@ string_to_cipher_algo( const char *string ) /**************** + * Map a cipher algo to a string + */ +const char * +cipher_algo_to_string( int algo ) +{ + int i; + + for(i=0; cipher_names[i].name; i++ ) + if( cipher_names[i].algo == algo ) + return cipher_names[i].name; + return NULL; +} + + +/**************** * Map a string to the pubkey algo */ int @@ -89,6 +104,23 @@ string_to_pubkey_algo( const char *string ) return 0; } + +/**************** + * Map a pubkey algo to a string + */ +const char * +pubkey_algo_to_string( int algo ) +{ + int i; + + for(i=0; pubkey_names[i].name; i++ ) + if( pubkey_names[i].algo == algo ) + return pubkey_names[i].name; + return NULL; +} + + + /**************** * Map a string to the digest algo */ @@ -104,6 +136,24 @@ string_to_digest_algo( const char *string ) return 0; } + +/**************** + * Map a digest algo to a string + */ +const char * +digest_algo_to_string( int algo ) +{ + int i; + + for(i=0; digest_names[i].name; i++ ) + if( digest_names[i].algo == algo ) + return digest_names[i].name; + return NULL; +} + + + + /**************** * Return 0 if the cipher algo is available */ diff --git a/config.h.in b/config.h.in index 082e5c56f..5405256d6 100644 --- a/config.h.in +++ b/config.h.in @@ -77,6 +77,7 @@ #undef VERSION #undef PACKAGE #undef G10_LOCALEDIR +#undef PRINTABLE_OS_NAME /* Define if your locale.h file contains LC_MESSAGES. */ #undef HAVE_LC_MESSAGES diff --git a/configure.in b/configure.in index 1a29bf7a2..1270b7f04 100644 --- a/configure.in +++ b/configure.in @@ -64,15 +64,17 @@ case "${target}" in CPP="i386--mingw32-gcc -E" RANLIB="i386--mingw32-ranlib" ac_cv_have_dev_random=no + PRINTABLE_OS_NAME="MingW32" ;; *) AC_PROG_RANLIB AC_PROG_INSTALL AC_PROG_CC AC_PROG_CPP + PRINTABLE_OS_NAME=`uname -s || echo "Unknown"` ;; esac - +AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME") dnl Checks for libraries. @@ -131,13 +133,6 @@ fi dnl setup assembler stuff AC_MSG_CHECKING(for mpi assembler functions) -mpi_config_done="no" -AC_CACHE_VAL(ac_cv_mpi_config_done, - [ ac_cv_mpi_config_done="$mpi_config_done" ]) -if test "$ac_cv_mpi_config_done" = yes; then - AC_MSG_RESULT(done) -else -ac_cv_mpi_config_done="" if test -f $srcdir/mpi/config.links ; then . $srcdir/mpi/config.links WK_LINK_FILES($mpi_ln_src, $mpi_ln_dst) @@ -148,7 +143,6 @@ else AC_MSG_RESULT(failed) AC_MSG_ERROR([mpi/config.links missing!]) fi -fi MPI_EXTRA_ASM_OBJS="" if test "$ac_cv_mpi_extra_asm_modules" != ""; then WK_MSG_PRINT([mpi extra asm functions:]) @@ -163,7 +157,7 @@ AC_SUBST(MPI_EXTRA_ASM_OBJS) dnl Do we have zlib? Must do it here because Solaris failed dnl when compiling a conftest (due to the "-lz" from LIBS). if test "$g10_force_zlib" = "yes"; then - ZLIBS="-L\${top_srcdir}/zlib -lzlib" + ZLIBS="../zlib/libzlib.a" AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, true) WK_LINK_FILES(zlib/zlib.h, zlib.h ) WK_LINK_FILES(zlib/zconf.h, zconf.h ) @@ -174,7 +168,7 @@ if test "$ac_cv_header_zlib_h" = yes ; then ZLIBS= AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, false) else - ZLIBS="-L\${top_srcdir}/zlib -lzlib" + ZLIBS="../zlib/libzlib.a" AM_CONDITIONAL(ENABLE_LOCAL_ZLIB, true) WK_LINK_FILES(zlib/zlib.h, zlib.h ) WK_LINK_FILES(zlib/zconf.h, zconf.h ) diff --git a/g10/ChangeLog b/g10/ChangeLog index 2bfa48b74..4e1cf4329 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,51 @@ +Mon Feb 16 20:02:03 1998 Werner Koch (wk@isil.d.shuttle.de) + + * kbnode.c (commit_kbnode): New. + (delete_kbnode): removed unused first arg. Changed all Callers. + + * ringedit.c (keyblock_resource_name): New. + (get_keyblock_handle): NULL for filename returns default resource. + +Mon Feb 16 19:38:48 1998 Werner Koch (wk@isil.d.shuttle.de) + + * sig-check.s (check_key_signature): Now uses the supplied + public key to check the signature and not any more the one + from the getkey.c + (do_check): New. + (check_signature): Most work moved to do_check. + +Mon Feb 16 14:48:57 1998 Werner Koch (wk@isil.d.shuttle.de) + + * armor.c (find_header): Fixed another bug. + +Mon Feb 16 12:18:34 1998 Werner Koch (wk@isil.d.shuttle.de) + + * getkey.c (scan_keyring): Add handling of compressed keyrings. + +Mon Feb 16 10:44:51 1998 Werner Koch (wk@isil.d.shuttle.de) + + * g10.c, g10maint.c (strusage): Rewrote. + (build_list): New + +Mon Feb 16 08:58:41 1998 Werner Koch (wk@isil.d.shuttle.de) + + * armor.c (use_armor): New. + +Sat Feb 14 14:30:57 1998 Werner Koch (wk@isil.d.shuttle.de) + + * mainproc.c (proc_tree): Sigclass fix. + +Sat Feb 14 14:16:33 1998 Werner Koch (wk@isil.d.shuttle.de) + + * armor.c (armor_filter): Changed version and comment string. + * encode.c, sign.c, keygen.c: Changed all comment packet strings. + +Sat Feb 14 12:39:24 1998 Werner Koch (wk@isil.d.shuttle.de) + + * g10.c (aGenRevoke): New command. + * revoke.c: New. + * sign.c (make_keysig_packet): Add support for sigclass 0x20. + Fri Feb 13 20:18:14 1998 Werner Koch (wk@isil.d.shuttle.de) * ringedit.c (enum_keyblocks, keyring_enum): New. diff --git a/g10/Makefile.am b/g10/Makefile.am index 128d594cd..e200fcd1d 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -45,6 +45,7 @@ common_source = \ plaintext.c \ encr-data.c \ encode.c \ + revoke.c \ sig-check.c g10_SOURCES = g10.c \ @@ -53,6 +54,7 @@ g10_SOURCES = g10.c \ g10maint_SOURCES = g10maint.c \ + dearmor.c \ $(common_source) LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@ diff --git a/g10/Makefile.in b/g10/Makefile.in index afbeebf8f..953b13b6b 100644 --- a/g10/Makefile.in +++ b/g10/Makefile.in @@ -131,6 +131,7 @@ common_source = \ plaintext.c \ encr-data.c \ encode.c \ + revoke.c \ sig-check.c g10_SOURCES = g10.c \ @@ -138,6 +139,7 @@ g10_SOURCES = g10.c \ keygen.c g10maint_SOURCES = g10maint.c \ + dearmor.c \ $(common_source) LDADD = @INTLLIBS@ $(needed_libs) @ZLIBS@ @@ -156,17 +158,17 @@ pkclist.o skclist.o ringedit.o kbnode.o mainproc.o armor.o mdfilter.o \ textfilter.o cipher.o elg.o rsa.o openfile.o keyid.o trustdb.o \ parse-packet.o passphrase.o pubkey-enc.o seckey-cert.o seskey.o \ import.o export.o comment.o status.o sign.o plaintext.o encr-data.o \ -encode.o sig-check.o keygen.o +encode.o revoke.o sig-check.o keygen.o g10_LDADD = $(LDADD) g10_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \ ../util/libutil.a g10_LDFLAGS = -g10maint_OBJECTS = g10maint.o build-packet.o compress.o free-packet.o \ -getkey.o pkclist.o skclist.o ringedit.o kbnode.o mainproc.o armor.o \ -mdfilter.o textfilter.o cipher.o elg.o rsa.o openfile.o keyid.o \ -trustdb.o parse-packet.o passphrase.o pubkey-enc.o seckey-cert.o \ -seskey.o import.o export.o comment.o status.o sign.o plaintext.o \ -encr-data.o encode.o sig-check.o +g10maint_OBJECTS = g10maint.o dearmor.o build-packet.o compress.o \ +free-packet.o getkey.o pkclist.o skclist.o ringedit.o kbnode.o \ +mainproc.o armor.o mdfilter.o textfilter.o cipher.o elg.o rsa.o \ +openfile.o keyid.o trustdb.o parse-packet.o passphrase.o pubkey-enc.o \ +seckey-cert.o seskey.o import.o export.o comment.o status.o sign.o \ +plaintext.o encr-data.o encode.o revoke.o sig-check.o g10maint_LDADD = $(LDADD) g10maint_DEPENDENCIES = ../cipher/libcipher.a ../mpi/libmpi.a \ ../util/libutil.a @@ -182,15 +184,15 @@ DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) TAR = tar GZIP = --best DEP_FILES = .deps/armor.P .deps/build-packet.P .deps/cipher.P \ -.deps/comment.P .deps/compress.P .deps/elg.P .deps/encode.P \ -.deps/encr-data.P .deps/export.P .deps/free-packet.P .deps/g10.P \ -.deps/g10maint.P .deps/getkey.P .deps/import.P .deps/kbnode.P \ -.deps/keygen.P .deps/keyid.P .deps/mainproc.P .deps/mdfilter.P \ -.deps/openfile.P .deps/parse-packet.P .deps/passphrase.P \ -.deps/pkclist.P .deps/plaintext.P .deps/pubkey-enc.P .deps/ringedit.P \ -.deps/rsa.P .deps/seckey-cert.P .deps/seskey.P .deps/sig-check.P \ -.deps/sign.P .deps/skclist.P .deps/status.P .deps/textfilter.P \ -.deps/trustdb.P +.deps/comment.P .deps/compress.P .deps/dearmor.P .deps/elg.P \ +.deps/encode.P .deps/encr-data.P .deps/export.P .deps/free-packet.P \ +.deps/g10.P .deps/g10maint.P .deps/getkey.P .deps/import.P \ +.deps/kbnode.P .deps/keygen.P .deps/keyid.P .deps/mainproc.P \ +.deps/mdfilter.P .deps/openfile.P .deps/parse-packet.P \ +.deps/passphrase.P .deps/pkclist.P .deps/plaintext.P .deps/pubkey-enc.P \ +.deps/revoke.P .deps/ringedit.P .deps/rsa.P .deps/seckey-cert.P \ +.deps/seskey.P .deps/sig-check.P .deps/sign.P .deps/skclist.P \ +.deps/status.P .deps/textfilter.P .deps/trustdb.P SOURCES = $(g10_SOURCES) $(g10maint_SOURCES) OBJECTS = $(g10_OBJECTS) $(g10maint_OBJECTS) diff --git a/g10/armor.c b/g10/armor.c index 1b31f6263..17dc444b8 100644 --- a/g10/armor.c +++ b/g10/armor.c @@ -36,8 +36,6 @@ #include "status.h" - - #define CRCINIT 0xB704CE #define CRCPOLY 0X864CFB #define CRCUPDATE(a,c) do { \ @@ -163,6 +161,29 @@ is_armored( byte *buf ) return 1; } + +/**************** + * Try to check wether the iobuf is armored + * Returns true if this may be the case; the caller should use the + * filter to do further processing. + */ +int +use_armor_filter( IOBUF a ) +{ + byte buf[1]; + int n; + + n = iobuf_peek(a, buf, 1 ); + if( n == -1 ) + return 0; /* EOF, doesn't matter wether armored or not */ + if( !n ) + return 1; /* can't check it: try armored */ + return is_armored(buf); +} + + + + static void invalid_armor(void) { @@ -248,7 +269,9 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, c = 0; for(n=0; n < 28 && (c=iobuf_get2(a)) != -1 && c != '\n'; ) buf[n++] = c; - if( !n || c == -1 ) + if( !n && c == '\n' ) + state = fhdrCHECKBegin; + else if( !n || c == -1 ) state = fhdrNOArmor; /* too short */ else if( !is_armored( buf ) ) state = fhdrNOArmor; @@ -269,8 +292,12 @@ find_header( fhdr_state_t state, byte *buf, size_t *r_buflen, break; case fhdrINITSkip: - while( (c=iobuf_get2(a)) != -1 && c != '\n' ) - ; + if( c == '\n' ) + n = 0; + else { + while( (c=iobuf_get2(a)) != -1 && c != '\n' ) + ; + } state = c == -1? fhdrEOF : fhdrINIT; break; @@ -912,8 +939,9 @@ armor_filter( void *opaque, int control, iobuf_writestr(a, "-----"); iobuf_writestr(a, head_strings[afx->what] ); iobuf_writestr(a, "-----\n"); - iobuf_writestr(a, "Version: G10 pre-release " VERSION "\n"); - iobuf_writestr(a, "Comment: This is an alpha test version!\n\n"); + iobuf_writestr(a, "Version: G10 v" VERSION " (" + PRINTABLE_OS_NAME ")\n"); + iobuf_writestr(a, "Comment: This is an alpha version!\n\n"); afx->status++; afx->idx = 0; afx->idx2 = 0; @@ -1012,3 +1040,5 @@ armor_filter( void *opaque, int control, return rc; } + + diff --git a/g10/encode.c b/g10/encode.c index eea7345fa..5726bc2b7 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -106,7 +106,8 @@ encode_simple( const char *filename, int mode ) if( opt.armor ) iobuf_push_filter( out, armor_filter, &afx ); - write_comment( out, "#Created by G10 pre-release " VERSION ); + write_comment( out, "#created by G10 v" VERSION " (" + PRINTABLE_OS_NAME ")"); if( opt.compress ) iobuf_push_filter( out, compress_filter, &zfx ); @@ -192,7 +193,8 @@ encode_crypt( const char *filename, STRLIST remusr ) if( opt.armor ) iobuf_push_filter( out, armor_filter, &afx ); - write_comment( out, "#Created by G10 pre-release " VERSION ); + write_comment( out, "#created by G10 v" VERSION " (" + PRINTABLE_OS_NAME ")"); if( opt.compress ) iobuf_push_filter( out, compress_filter, &zfx ); diff --git a/g10/filter.h b/g10/filter.h index b49ce28b7..93e72ce9c 100644 --- a/g10/filter.h +++ b/g10/filter.h @@ -79,6 +79,7 @@ int md_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len); void free_md_filter_context( md_filter_context_t *mfx ); /*-- armor.c --*/ +int use_armor_filter( IOBUF a ); int armor_filter( void *opaque, int control, IOBUF chain, byte *buf, size_t *ret_len); @@ -61,6 +61,7 @@ static ARGPARSE_OPTS opts[] = { { 505, "delete-key",0, N_("remove key from the public keyring")}, { 524, "edit-sig" ,0, N_("edit a key signature")}, { 525, "change-passphrase", 0, N_("change the passphrase of your secret keyring")}, + { 542, "gen-revoke",0, N_("generate a revocation certificate")}, { 537, "export" , 0, N_("export keys") }, { 530, "import", 0 , N_("import/merge keys")}, @@ -119,49 +120,90 @@ enum cmd_values { aNull = 0, aSym, aStore, aEncr, aKeygen, aSign, aSignEncr, aSignKey, aClearsign, aListPackets, aEditSig, aKMode, aKModeC, aChangePass, aImport, - aExport, aCheckKeys, + aExport, aCheckKeys, aGenRevoke, aNOP }; +static char *build_list( const char *text, + const char *(*mapf)(int), int (*chkf)(int) ); static void set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd ); const char * strusage( int level ) { + static char *digests, *pubkeys, *ciphers; const char *p; switch( level ) { - case 10: - case 0: p = "g10 - v" VERSION "; " - "Copyright 1998 Werner Koch (dd9jn)\n" ; break; - case 13: p = "g10"; break; - case 14: p = VERSION; break; + case 11: p = "g10"; break; + case 13: p = VERSION; break; + case 17: p = PRINTABLE_OS_NAME; break; + case 19: p = _( +"Please report bugs to <g10-bugs@isil.d.shuttle.de>." + ); break; case 1: - case 11: p = "Usage: g10 [options] [files] (-h for help)"; - break; - case 2: - case 12: p = - _("Syntax: g10 [options] [files]\n" - "sign, check, encrypt or decrypt\n" - "default operation depends on the input data\n"); break; - - case 26: - p = _("Please report bugs to <g10-bugs@isil.d.shuttle.de>.\n"); + case 40: p = _( +"Usage: g10 [options] [files] (-h for help)" + ); break; + case 41: p = _( +"Syntax: g10 [options] [files]\n" +"sign, check, encrypt or decrypt\n" +"default operation depends on the input data\n" + ); break; + + case 31: p = "\n"; break; + case 32: + if( !ciphers ) + ciphers = build_list("Supported ciphers: ", cipher_algo_to_string, + check_cipher_algo ); + p = ciphers; break; - - #if defined(HAVE_RSA_CIPHER) - case 30: p = _( - "WARNING: This version has RSA support! Your are not allowed to\n" - " use it inside the Unites States before Sep 30, 2000!\n" ); - #else - case 30: p = ""; - #endif + case 33: + if( !pubkeys ) + pubkeys = build_list("Supported pubkeys: ", pubkey_algo_to_string, + check_pubkey_algo ); + p = pubkeys; + break; + case 34: + if( !digests ) + digests = build_list("Supported digests: ", digest_algo_to_string, + check_digest_algo ); + p = digests; break; + default: p = default_strusage(level); } return p; } + +static char * +build_list( const char *text, const char * (*mapf)(int), int (*chkf)(int) ) +{ + int i; + const char *s; + size_t n=strlen(text)+2; + char *list, *p; + + for(i=1; i < 100; i++ ) + if( !chkf(i) && (s=mapf(i)) ) + n += strlen(s) + 2; + list = m_alloc( 21 + n ); *list = 0; + for(p=NULL, i=1; i < 100; i++ ) { + if( !chkf(i) && (s=mapf(i)) ) { + if( !p ) + p = stpcpy( list, text ); + else + p = stpcpy( p, ", "); + p = stpcpy(p, s ); + } + } + if( p ) + p = stpcpy(p, "\n" ); + return list; +} + + static void i18n_init(void) { @@ -257,7 +299,6 @@ main( int argc, char **argv ) STRLIST sl, remusr= NULL, locusr=NULL; int nrings=0, sec_nrings=0; armor_filter_context_t afx; - const char *s; int detached_sig = 0; FILE *configfp = NULL; char *configname = NULL; @@ -405,6 +446,7 @@ main( int argc, char **argv ) case 539: set_cmd( &cmd, aClearsign); break; case 540: secmem_set_flags( secmem_get_flags() | 1 ); break; case 541: set_cmd( &cmd, aNOP); break; + case 542: set_cmd( &cmd, aGenRevoke); break; default : errors++; pargs.err = configfp? 1:2; break; } } @@ -420,10 +462,8 @@ main( int argc, char **argv ) g10_exit(2); if( greeting ) { - if( *(s=strusage(10)) ) - tty_printf("%s", s); - if( *(s=strusage(30)) ) - tty_printf("%s", s); + tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) ); + tty_printf("%s", strusage(15) ); } /* initialize the secure memory. */ @@ -630,6 +670,12 @@ main( int argc, char **argv ) free_strlist(sl); break; + case aGenRevoke: + if( argc != 1 ) + wrong_args("--gen-revoke user-id"); + gen_revoke( *argv ); + break; + case aNOP: break; @@ -642,9 +688,10 @@ main( int argc, char **argv ) log_error(_("can't open '%s'\n"), fname_print); else { if( !opt.no_armor ) { - /* push the armor filter, so it can peek at the input data */ - memset( &afx, 0, sizeof afx); - iobuf_push_filter( a, armor_filter, &afx ); + if( use_armor_filter( a ) ) { + memset( &afx, 0, sizeof afx); + iobuf_push_filter( a, armor_filter, &afx ); + } } if( cmd == aListPackets ) { set_packet_list_mode(1); diff --git a/g10/g10maint.c b/g10/g10maint.c index bc64eb04d..618acc8fa 100644 --- a/g10/g10maint.c +++ b/g10/g10maint.c @@ -43,51 +43,92 @@ enum cmd_values { aNull = 0, aPrimegen, aPrintMDs, aListPackets, aKMode, aKModeC, - aListTrustDB, aListTrustPath, + aListTrustDB, aListTrustPath, aDeArmor, aTest }; +static char *build_list( const char *text, + const char *(*mapf)(int), int (*chkf)(int) ); static void set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd ); static void print_hex( byte *p, size_t n ); static void print_mds( const char *fname ); static void do_test(int); + const char * strusage( int level ) { + static char *digests, *pubkeys, *ciphers; const char *p; switch( level ) { - case 10: - case 0: p = "g10maint - v" VERSION "; " - "Copyright 1997 Werner Koch (dd9jn)\n" ; break; - case 13: p = "g10"; break; - case 14: p = VERSION; break; + case 11: p = "g10maint"; break; + case 13: p = VERSION; break; + case 17: p = PRINTABLE_OS_NAME; break; + case 19: p = _( +"Please report bugs to <g10-bugs@isil.d.shuttle.de>." + ); break; case 1: - case 11: p = "Usage: g10main [options] (-h for help)"; - break; - case 2: - case 12: p = - _("Syntax: g10maint [options]\n" - "The G10 maintenace utility\n"); break; - - case 26: - p = _("Please report bugs to <g10-bugs@isil.d.shuttle.de>.\n"); + case 40: p = _( +"Usage: g10maint [options] [files] (-h for help)" + ); break; + case 41: p = _( +"Syntax: g10maint [options] [files]\n" +"G10 maintenance utility\n" + ); break; + + case 31: p = "\n"; break; + case 32: + if( !ciphers ) + ciphers = build_list("Supported ciphers: ", cipher_algo_to_string, + check_cipher_algo ); + p = ciphers; break; - - #if defined(HAVE_RSA_CIPHER) - case 30: p = _( - "WARNING: This version has RSA support! Your are not allowed to\n" - " use it inside the Unites States before Sep 30, 2000!\n" ); - #else - case 30: p = ""; - #endif + case 33: + if( !pubkeys ) + pubkeys = build_list("Supported pubkeys: ", pubkey_algo_to_string, + check_pubkey_algo ); + p = pubkeys; break; + case 34: + if( !digests ) + digests = build_list("Supported digests: ", digest_algo_to_string, + check_digest_algo ); + p = digests; + break; + default: p = default_strusage(level); } return p; } + +static char * +build_list( const char *text, const char * (*mapf)(int), int (*chkf)(int) ) +{ + int i; + const char *s; + size_t n=strlen(text)+2; + char *list, *p; + + for(i=1; i < 100; i++ ) + if( !chkf(i) && (s=mapf(i)) ) + n += strlen(s) + 2; + list = m_alloc( 21 + n ); *list = 0; + for(p=NULL, i=1; i < 100; i++ ) { + if( !chkf(i) && (s=mapf(i)) ) { + if( !p ) + p = stpcpy( list, text ); + else + p = stpcpy( p, ", "); + p = stpcpy(p, s ); + } + } + if( p ) + p = stpcpy(p, "\n" ); + return list; +} + static void i18n_init(void) { @@ -178,6 +219,7 @@ main( int argc, char **argv ) { 535, "completes-needed", 1, N_("(default is 1)")}, { 536, "marginals-needed", 1, N_("(default is 3)")}, { 538, "trustdb-name", 2, "\r" }, + { 540, "dearmor", 0, N_("De-Armor a file or stdin") }, {0} }; ARGPARSE_ARGS pargs; @@ -189,7 +231,6 @@ main( int argc, char **argv ) STRLIST remusr= NULL, locusr=NULL; int nrings=0, sec_nrings=0; armor_filter_context_t afx; - const char *s; FILE *configfp = NULL; char *configname = NULL; unsigned configlineno; @@ -308,6 +349,7 @@ main( int argc, char **argv ) case 535: opt.completes_needed = pargs.r.ret_int; break; case 536: opt.marginals_needed = pargs.r.ret_int; break; case 538: trustdb_name = pargs.r.ret_str; break; + case 540: set_cmd( &cmd, aDeArmor); break; default : errors++; pargs.err = configfp? 1:2; break; } } @@ -360,10 +402,8 @@ main( int argc, char **argv ) if( opt.verbose > 1 ) set_packet_list_mode(1); if( greeting ) { - if( *(s=strusage(10)) ) - tty_printf("%s", s); - if( *(s=strusage(30)) ) - tty_printf("%s", s); + tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) ); + tty_printf("%s", strusage(15) ); } if( !sec_nrings || default_keyring ) { /* add default secret rings */ @@ -436,6 +476,15 @@ main( int argc, char **argv ) usage(1); break; + case aDeArmor: + if( argc > 1 ) + wrong_args("--dearmor [file]"); + rc = dearmor_file( argc? *argv: NULL ); + if( rc ) + log_error(_("dearmoring failed: %s\n"), g10_errstr(rc)); + break; + + case aPrimegen: if( argc == 1 ) { mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1); diff --git a/g10/getkey.c b/g10/getkey.c index 7182f4d4f..8f92f0a45 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -460,6 +460,7 @@ static int scan_keyring( PKT_public_cert *pkc, u32 *keyid, const char *name, const char *filename ) { + compress_filter_context_t cfx; int rc=0; int found = 0; IOBUF a; @@ -499,6 +500,19 @@ scan_keyring( PKT_public_cert *pkc, u32 *keyid, log_error("Hmmm, pubkey without an user id in '%s'\n", filename); goto leave; } + else if( pkt.pkttype == PKT_COMPRESSED ) { + memset( &cfx, 0, sizeof cfx ); + if( pkt.pkt.compressed->algorithm == 1 ) + cfx.pgpmode = 1; + else if( pkt.pkt.compressed->algorithm != 2 ){ + rc = G10ERR_COMPR_ALGO; + log_error("compressed keyring: %s\n", g10_errstr(rc) ); + break; + } + + pkt.pkt.compressed->buf = NULL; + iobuf_push_filter( a, compress_filter, &cfx ); + } else if( keyid && pkt.pkttype == PKT_PUBLIC_CERT ) { switch( pkt.pkt.public_cert->pubkey_algo ) { case PUBKEY_ALGO_ELGAMAL: diff --git a/g10/import.c b/g10/import.c index 0474152d7..ce2655bfb 100644 --- a/g10/import.c +++ b/g10/import.c @@ -32,6 +32,15 @@ #include "memory.h" #include "util.h" #include "trustdb.h" +#include "main.h" + + +static int read_block( IOBUF a, compress_filter_context_t *cfx, + PACKET **pending_pkt, KBNODE *ret_root ); +static int import_one( const char *fname, KBNODE keyblock ); +static int chk_self_sigs( const char *fname, KBNODE keyblock, + PKT_public_cert *pkc, u32 *keyid ); +static int delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid ); /**************** @@ -40,11 +49,11 @@ * least one userid. Only user ids which are self signed will be imported. * Other signatures are not not checked. * - * Actually this functtion does a merge, it works like this: + * Actually this functtion does a merge. It works like this: * FIXME: add handling for revocation certs * * - get the keyblock - * - check self-signatures and remove all userids and their isgnatures + * - check self-signatures and remove all userids and their signatures * without/invalid self-signatures. * - reject the keyblock, if we have no valid userid. * - See wether we have this key already in one of our pubrings. @@ -55,7 +64,7 @@ * - See wether we have only non-self-signature on one user id; if not * ask the user what to do. * - compare the signatures: If we already have this signature, check - * that they compare okay, if not issue a warning and ask the user. + * that they compare okay; if not, issue a warning and ask the user. * (consider to look at the timestamp and use the newest?) * - Simply add the signature. Can't verify here because we may not have * the signatures public key yet; verification is done when putting it @@ -65,10 +74,298 @@ * */ int -import_pubkeys( const char *filename ) +import_pubkeys( const char *fname ) +{ + armor_filter_context_t afx; + compress_filter_context_t cfx; + PACKET *pending_pkt = NULL; + IOBUF inp = NULL; + KBNODE keyblock; + int rc = 0; + + memset( &afx, 0, sizeof afx); + memset( &cfx, 0, sizeof cfx); + + /* open file */ + inp = iobuf_open(fname); + if( !fname ) + fname = "[stdin]"; + if( !inp ) { + log_error("%s: can't open file: %s\n", fname, strerror(errno) ); + return G10ERR_OPEN_FILE; + } + + if( !opt.no_armor ) /* armored reading is not diabled */ + iobuf_push_filter( inp, armor_filter, &afx ); + + while( !(rc = read_block( inp, &cfx, &pending_pkt, &keyblock) )) { + if( keyblock->pkt->pkttype == PKT_PUBLIC_CERT ) + rc = import_one( fname, keyblock ); + else + log_info("%s: skipping block of type %d\n", + fname, keyblock->pkt->pkttype ); + release_kbnode(keyblock); + if( rc ) + break; + } + if( rc == -1 ) + rc = 0; + else if( rc ) + log_error("%s: read error: %s\n", fname, g10_errstr(rc)); + + iobuf_close(inp); + return rc; +} + + +/**************** + * Read the next keyblock from stream A, CFX is used to handle + * compressed keyblocks. PENDING_PKT should be initialzed to NULL + * and not chnaged form the caller. + * Retunr: 0 = okay, -1 no more blocks or another errorcode. + */ +static int +read_block( IOBUF a, compress_filter_context_t *cfx, + PACKET **pending_pkt, KBNODE *ret_root ) { - log_fatal("Not yet implemented"); + int rc; + PACKET *pkt; + KBNODE root = NULL; + int in_cert = 0; + + if( *pending_pkt ) { + root = new_kbnode( *pending_pkt ); + *pending_pkt = NULL; + } + pkt = m_alloc( sizeof *pkt ); + init_packet(pkt); + while( (rc=parse_packet(a, pkt)) != -1 ) { + if( rc ) { /* ignore errors */ + if( rc != G10ERR_UNKNOWN_PACKET ) { + log_error("read_block: read error: %s\n", g10_errstr(rc) ); + rc = G10ERR_INV_KEYRING; + goto ready; + } + free_packet( pkt ); + init_packet(pkt); + continue; + } + /* make a linked list of all packets */ + switch( pkt->pkttype ) { + case PKT_COMPRESSED: + if( pkt->pkt.compressed->algorithm == 1 ) + cfx->pgpmode = 1; + else if( pkt->pkt.compressed->algorithm != 2 ){ + rc = G10ERR_COMPR_ALGO; + goto ready; + } + pkt->pkt.compressed->buf = NULL; + iobuf_push_filter( a, compress_filter, cfx ); + free_packet( pkt ); + init_packet(pkt); + break; + + case PKT_PUBLIC_CERT: + case PKT_SECRET_CERT: + if( in_cert ) { /* store this packet */ + *pending_pkt = pkt; + pkt = NULL; + goto ready; + } + in_cert = 1; + default: + if( !root ) + root = new_kbnode( pkt ); + else + add_kbnode( root, new_kbnode( pkt ) ); + pkt = m_alloc( sizeof *pkt ); + init_packet(pkt); + break; + } + } + ready: + if( rc == -1 && root ) + rc = 0; + + if( rc ) + release_kbnode( root ); + else + *ret_root = root; + free_packet( pkt ); + m_free( pkt ); + return rc; +} + + +/**************** + * Try to import one keyblock. Return an error only in serious cases, but + * never for an invalid keyblock. It uses log_error to increase the + * internal errorcount, so that invalid input can be detected by programs + * which called g10. + */ +static int +import_one( const char *fname, KBNODE keyblock ) +{ + PKT_public_cert *pkc; + PKT_public_cert *pkc_orig; + KBNODE node, uidnode; + KBPOS kbpos; + u32 keyid[2]; + int rc = 0; + + /* get the key and print some infos about it */ + node = find_kbnode( keyblock, PKT_PUBLIC_CERT ); + if( !node ) { + log_error("%s: Oops; public key not found anymore!\n", fname); + return G10ERR_GENERAL; /* really serious */ + } + + pkc = node->pkt->pkt.public_cert; + keyid_from_pkc( pkc, keyid ); + uidnode = find_next_kbnode( keyblock, PKT_USER_ID ); + + if( opt.verbose ) { + log_info("%s: pub %4u%c/%08lX %s ", fname, + nbits_from_pkc( pkc ), + pubkey_letter( pkc->pubkey_algo ), + (ulong)keyid[1], datestr_from_pkc(pkc) ); + if( uidnode ) + print_string( stderr, uidnode->pkt->pkt.user_id->name, + uidnode->pkt->pkt.user_id->len ); + putc('\n', stderr); + } + if( !uidnode ) { + log_error("%s: No user id for key %08lX\n", fname, (ulong)keyid[1]); + return 0; + } + + clear_kbnode_flags( keyblock ); + rc = chk_self_sigs( fname, keyblock , pkc, keyid ); + if( rc ) + return rc== -1? 0:rc; + if( !delete_inv_parts( fname, keyblock, keyid ) ) { + log_info("%s: key %08lX, no valid user ids left over\n", + fname, (ulong)keyid[1]); + return 0; + } + + /* do we have this key already in one of our pubrings ? */ + pkc_orig = m_alloc( sizeof *pkc_orig ); + rc = get_pubkey( pkc_orig, keyid ); + if( rc && rc != G10ERR_NO_PUBKEY ) { + log_error("%s: key %08lX, public key not found: %s\n", + fname, (ulong)keyid[1], g10_errstr(rc)); + } + else if( rc ) { /* inset this key */ + /* get default resource */ + if( get_keyblock_handle( NULL, 0, &kbpos ) ) { + log_error("no default public keyring\n"); + return G10ERR_GENERAL; + } + if( opt.verbose > 1 ) + log_info("%s: writing to '%s'\n", + fname, keyblock_resource_name(&kbpos) ); + if( (rc=lock_keyblock( &kbpos )) ) + log_error("can't lock public keyring '%s': %s\n", + keyblock_resource_name(&kbpos), g10_errstr(rc) ); + else if( (rc=insert_keyblock( &kbpos, keyblock )) ) + log_error("%s: can't write to '%s': %s\n", fname, + keyblock_resource_name(&kbpos), g10_errstr(rc) ); + unlock_keyblock( &kbpos ); + /* we are ready */ + if( opt.verbose ) + log_info("%s: key %08lX imported\n", fname, (ulong)keyid[1]); + } + else { + /* merge + * o Compare the key and the self-signatures of the new and the one in + * our keyring. If they are different something weird is going on; + * ask what to do. + * o See wether we have only non-self-signature on one user id; if not + * ask the user what to do. + * o compare the signatures: If we already have this signature, check + * that they compare okay; if not, issue a warning and ask the user. + * (consider to look at the timestamp and use the newest?) + * o Simply add the signature. Can't verify here because we may not have + * the signatures public key yet; verification is done when putting it + * into the trustdb, which is done automagically as soon as this pubkey + * is used. + */ + log_error("nyi\n"); + } + + free_public_cert( pkc_orig ); + return rc; +} + +/**************** + * loop over the keyblock an check all self signatures. + * Mark all user-ids with a self-signature by setting flag bit 0. + * Mark all user-ids with an invalid self-signature by setting bit 1. + */ +static int +chk_self_sigs( const char *fname, KBNODE keyblock, + PKT_public_cert *pkc, u32 *keyid ) +{ + KBNODE n, unode; + PKT_signature *sig; + int rc; + + for( n=keyblock; (n = find_next_kbnode(n, 0)); ) { + if( n->pkt->pkttype != PKT_SIGNATURE ) + continue; + sig = n->pkt->pkt.signature; + if( keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1] ) { + unode = find_prev_kbnode( keyblock, n, PKT_USER_ID ); + if( !unode ) { + log_error("%s: key %08lX, no user-id for signature\n", + fname, (ulong)keyid[1]); + return -1; /* the complete keyblock is invalid */ + } + rc = check_key_signature( keyblock, n, NULL); + if( rc ) { + log_error("%s: key %08lX, invalid self-signature\n", + fname, (ulong)keyid[1]); + unode->flag |= 2; /* mark as invalid */ + } + unode->flag |= 1; /* mark that user-id checked */ + } + } return 0; } +/**************** + * delete all parts which are invalid. + * returns: true if at least one valid user-id is left over. + */ +static int +delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid ) +{ + KBNODE node; + int nvalid=0; + for(node=keyblock->next; node; node = node->next ) { + if( node->pkt->pkttype == PKT_USER_ID ) { + if( (node->flag & 2) || !(node->flag & 1) ) { + log_info("%s: key %08lX, removed userid '", + fname, (ulong)keyid[1]); + print_string( stderr, node->pkt->pkt.user_id->name, + node->pkt->pkt.user_id->len ); + fputs("'\n", stderr ); + delete_kbnode( node ); /* the user-id */ + /* and all following packets up to the next user-id */ + while( node->next && node->next->pkt->pkttype != PKT_USER_ID ){ + delete_kbnode( node->next ); + node = node->next; + } + } + else + nvalid++; + } + } + + /* note: because keyblock is the public key, ist is never marked + * for deletion and so the keyblock cannot chnage */ + commit_kbnode( &keyblock ); + return nvalid; +} diff --git a/g10/kbnode.c b/g10/kbnode.c index 83ec50742..c28748b6e 100644 --- a/g10/kbnode.c +++ b/g10/kbnode.c @@ -61,7 +61,7 @@ release_kbnode( KBNODE n ) * Note: This does only work with walk_kbnode!! */ void -delete_kbnode( KBNODE root, KBNODE node ) +delete_kbnode( KBNODE node ) { node->private_flag |= 1; } @@ -196,3 +196,29 @@ clear_kbnode_flags( KBNODE n ) } } + +/**************** + * Commit changes made to the kblist at ROOT. Note that ROOT my change, + * and it is therefor passed by reference. + * The function has the effect of removing all nodes marked as deleted. + * returns true, if any node has been changed + */ +int +commit_kbnode( KBNODE *root ) +{ + KBNODE n, n2; + int changed = 0; + + for(n=*root; n; n = n2 ) { + n2 = n->next; + if( (n->private_flag & 1) ) { + if( n == *root ) + *root = n2; + free_packet( n->pkt ); + m_free( n ); + changed = 1; + } + } + return changed; +} + diff --git a/g10/keydb.h b/g10/keydb.h index ca54020cd..643632a40 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -128,7 +128,7 @@ byte *fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len ); /*-- kbnode.c --*/ KBNODE new_kbnode( PACKET *pkt ); void release_kbnode( KBNODE n ); -void delete_kbnode( KBNODE root, KBNODE node ); +void delete_kbnode( KBNODE node ); void add_kbnode( KBNODE root, KBNODE node ); void insert_kbnode( KBNODE root, KBNODE node, int pkttype ); KBNODE find_prev_kbnode( KBNODE root, KBNODE node, int pkttype ); @@ -136,9 +136,11 @@ KBNODE find_next_kbnode( KBNODE node, int pkttype ); KBNODE find_kbnode( KBNODE node, int pkttype ); KBNODE walk_kbnode( KBNODE root, KBNODE *context, int all ); void clear_kbnode_flags( KBNODE n ); +int commit_kbnode( KBNODE *root ); /*-- ringedit.c --*/ int add_keyblock_resource( const char *filename, int force, int secret ); +const char *keyblock_resource_name( KBPOS *kbpos ); int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos ); int find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos ); int find_keyblock_byname( KBPOS *kbpos, const char *username ); diff --git a/g10/keygen.c b/g10/keygen.c index 1c9a2efbe..89fd852e1 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -538,8 +538,8 @@ generate_keypair() * The first packet is a dummy comment packet which we flag * as deleted. The very first packet must always be a CERT packet. */ - pub_root = make_comment_node("#"); delete_kbnode(pub_root, pub_root); - sec_root = make_comment_node("#"); delete_kbnode(sec_root, sec_root); + pub_root = make_comment_node("#"); delete_kbnode(pub_root); + sec_root = make_comment_node("#"); delete_kbnode(sec_root); tty_printf(_( "We need to generate a lot of random bytes. It is a good idea to perform\n" @@ -559,9 +559,11 @@ generate_keypair() BUG(); if( !rc ) { add_kbnode( pub_root, - make_comment_node("#created by G10 release " VERSION )); + make_comment_node("#created by G10 v" VERSION " (" + PRINTABLE_OS_NAME ")")); add_kbnode( sec_root, - make_comment_node("#created by G10 release " VERSION )); + make_comment_node("#created by G10 v" VERSION " (" + PRINTABLE_OS_NAME ")")); } if( !rc ) write_uid(pub_root, uid ); diff --git a/g10/main.h b/g10/main.h index 0c59de222..8761a1c59 100644 --- a/g10/main.h +++ b/g10/main.h @@ -89,6 +89,10 @@ void g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, int import_pubkeys( const char *filename ); /*-- export.c --*/ int export_pubkeys( STRLIST users ); +/* dearmor.c --*/ +int dearmor_file( const char *fname ); +/*-- revoke.c --*/ +int gen_revoke( const char *uname ); #endif /*G10_MAIN_H*/ diff --git a/g10/mainproc.c b/g10/mainproc.c index a7c17f9c8..7e19f12c1 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -619,15 +619,17 @@ proc_tree( CTX c, KBNODE node ) else if( node->pkt->pkttype == PKT_SIGNATURE ) { PKT_signature *sig = node->pkt->pkt.signature; - log_info("proc_tree: old style signature\n"); - if( !c->have_data ) { - free_md_filter_context( &c->mfx ); - c->mfx.md = md_open(digest_algo_from_sig(sig), 0); - rc = ask_for_detached_datafile( &c->mfx, - iobuf_get_fname(c->iobuf)); - if( rc ) { - log_error("can't hash datafile: %s\n", g10_errstr(rc)); - return; + if( !c->have_data && (sig->sig_class&~3) == 0x10 ) { + log_info("old style signature\n"); + if( !c->have_data ) { + free_md_filter_context( &c->mfx ); + c->mfx.md = md_open(digest_algo_from_sig(sig), 0); + rc = ask_for_detached_datafile( &c->mfx, + iobuf_get_fname(c->iobuf)); + if( rc ) { + log_error("can't hash datafile: %s\n", g10_errstr(rc)); + return; + } } } diff --git a/g10/revoke.c b/g10/revoke.c new file mode 100644 index 000000000..2a8c5fc5c --- /dev/null +++ b/g10/revoke.c @@ -0,0 +1,199 @@ +/* revoke.c + * Copyright (c) 1998 by Werner Koch (dd9jn) + * + * This file is part of G10. + * + * G10 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. + * + * G10 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 + */ + +#include <config.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> + +#include "options.h" +#include "packet.h" +#include "errors.h" +#include "keydb.h" +#include "memory.h" +#include "util.h" +#include "main.h" +#include "ttyio.h" + + +/**************** + * Generate a revocation certificate for UNAME + */ +int +gen_revoke( const char *uname ) +{ + int rc = 0; + armor_filter_context_t afx; + compress_filter_context_t zfx; + PACKET pkt; + PKT_secret_cert *skc; /* used as pointer into a kbnode */ + PKT_public_cert *pkc = NULL; + PKT_signature *sig = NULL; + u32 skc_keyid[2]; + IOBUF out = NULL; + KBNODE keyblock = NULL; + KBNODE node; + KBPOS kbpos; + char *answer; + int yes; + + if( opt.batch ) { + log_error("sorry, can't do this in batch mode\n"); + return G10ERR_GENERAL; + } + + + memset( &afx, 0, sizeof afx); + memset( &zfx, 0, sizeof zfx); + init_packet( &pkt ); + + + /* search the userid */ + rc = find_secret_keyblock_byname( &kbpos, uname ); + if( rc ) { + log_error("secret key for user '%s' not found\n", uname ); + goto leave; + } + + /* read the keyblock */ + rc = read_keyblock( &kbpos, &keyblock ); + if( rc ) { + log_error("error reading the certificate: %s\n", g10_errstr(rc) ); + goto leave; + } + + /* get the keyid from the keyblock */ + node = find_kbnode( keyblock, PKT_SECRET_CERT ); + if( !node ) { /* maybe better to use log_bug ? */ + log_error("Oops; secret key not found anymore!\n"); + rc = G10ERR_GENERAL; + goto leave; + } + + /* FIXME: should make a function out of this stuff, + * it's used all over the source */ + skc = node->pkt->pkt.secret_cert; + keyid_from_skc( skc, skc_keyid ); + tty_printf("\nsec %4u%c/%08lX %s ", + nbits_from_skc( skc ), + pubkey_letter( skc->pubkey_algo ), + skc_keyid[1], datestr_from_skc(skc) ); + { + size_t n; + char *p = get_user_id( skc_keyid, &n ); + tty_print_string( p, n ); + m_free(p); + tty_printf("\n"); + } + /* the the pkc */ + pkc = m_alloc_clear( sizeof *pkc ); + rc = get_pubkey( pkc, skc_keyid ); + if( rc ) { + log_error("no corresponding public key: %s\n", g10_errstr(rc) ); + goto leave; + } + if( cmp_public_secret_cert( pkc, skc ) ) { + log_error("public key does not match secret key!\n" ); + rc = G10ERR_GENERAL; + goto leave; + } + + tty_printf("\n"); + answer = tty_get("Create a revocation certificate for this key? "); + tty_kill_prompt(); + yes = answer_is_yes(answer); + m_free(answer); + if( !yes ) { + rc = 0; + goto leave; + } + + switch( is_secret_key_protected( skc ) ) { + case -1: + log_error("unknown protection algorithm\n"); + rc = G10ERR_PUBKEY_ALGO; + break; + case 0: + tty_printf("Warning: This key is not protected!\n"); + break; + default: + rc = check_secret_key( skc ); + break; + } + if( rc ) + goto leave; + + + if( !opt.armor ) + tty_printf("ASCII armored output forced.\n"); + + if( !(out = open_outfile( NULL, 0 )) ) { + rc = G10ERR_CREATE_FILE; + goto leave; + } + + afx.what = 1; + iobuf_push_filter( out, armor_filter, &afx ); + if( opt.compress ) + iobuf_push_filter( out, compress_filter, &zfx ); + + + /* create it */ + rc = make_keysig_packet( &sig, pkc, NULL, skc, 0x20, DIGEST_ALGO_RMD160); + if( rc ) { + log_error("make_keysig_packet failed: %s\n", g10_errstr(rc)); + goto leave; + } + init_packet( &pkt ); + pkt.pkttype = PKT_SIGNATURE; + pkt.pkt.signature = sig; + + rc = build_packet( out, &pkt ); + if( rc ) { + log_error("build_packet failed: %s\n", g10_errstr(rc) ); + goto leave; + } + + /* and issue a usage notice */ + tty_printf("Revocation certificate created.\n\n" +"Please move it to a media, which you can hide away; if Mallory gets\n" +"access to this certificate he can use it to make your key unusable.\n" +"It is clever to print this certificate and store it away, just in the case\n" +"your media gets unreadable. But have some caution: The printer system of\n" +"your machine might store the data and make it availabe to others!\n"); + + + + leave: + if( pkc ) + free_public_cert( pkc ); + if( sig ) + free_seckey_enc( sig ); + release_kbnode( keyblock ); + if( rc ) + iobuf_cancel(out); + else + iobuf_close(out); + return rc; +} + + diff --git a/g10/ringedit.c b/g10/ringedit.c index adba3db0b..6d3fc14bb 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -123,10 +123,24 @@ add_keyblock_resource( const char *filename, int force, int secret ) return 0; } +/**************** + * Return the resource name of the keyblock associated with KBPOS. + */ +const char * +keyblock_resource_name( KBPOS *kbpos ) +{ + RESTBL *rentry; + + if( !(rentry = check_pos( kbpos )) || !rentry->fname ) + log_bug("no name for keyblock resource %d\n", kbpos->resno ); + return rentry->fname; +} + /**************** * Get a keyblock handle KBPOS from a filename. This can be used * to get a handle for insert_keyblock for a new keyblock. + * Using a filename of NULL returns the default resource */ int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos ) @@ -136,7 +150,7 @@ get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos ) for(i=0; i < MAX_RESOURCES; i++ ) if( resource_table[i].used && !resource_table[i].secret == !secret ) { /* fixme: dos needs case insensitive file compare */ - if( !strcmp( resource_table[i].fname, filename ) ) { + if( !filename || !strcmp( resource_table[i].fname, filename ) ) { memset( kbpos, 0, sizeof *kbpos ); kbpos->resno = i; return 0; @@ -598,6 +612,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root ) } kbpos->count++; free_packet( pkt ); + init_packet( pkt ); continue; } /* make a linked list of all packets */ @@ -660,6 +675,7 @@ keyring_enum( KBPOS *kbpos, KBNODE *ret_root ) goto ready; } free_packet( pkt ); + init_packet( pkt ); continue; } /* make a linked list of all packets */ diff --git a/g10/seskey.c b/g10/seskey.c index 1488620cd..f157032d5 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -121,7 +121,8 @@ do_encode_md( MD_HANDLE md, int algo, size_t len, unsigned nbits, MPI a; if( len + asnlen + 4 > nframe ) - log_bug("can't encode a %d bit MD into a %d bits frame\n",len*8, nbits); + log_bug("can't encode a %d bit MD into a %d bits frame\n", + (int)(len*8), (int)nbits); /* We encode the MD in this way: * diff --git a/g10/sig-check.c b/g10/sig-check.c index dac3f4b74..4615c46e0 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -32,6 +32,10 @@ #include "main.h" +static int do_check( PKT_public_cert *pkc, PKT_signature *sig, + MD_HANDLE digest ); + + /**************** * Check the signature which is contained in the rsa_integer. * The md5handle should be currently open, so that this function @@ -41,14 +45,23 @@ int signature_check( PKT_signature *sig, MD_HANDLE digest ) { PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc ); - MPI result = NULL; int rc=0; - - if( get_pubkey( pkc, sig->keyid ) ) { + if( get_pubkey( pkc, sig->keyid ) ) rc = G10ERR_NO_PUBKEY; - goto leave; - } + else + rc = do_check( pkc, sig, digest ); + + free_public_cert( pkc ); + return rc; +} + + +static int +do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest ) +{ + MPI result = NULL; + int rc=0; if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { ELG_public_key pkey; @@ -164,8 +177,6 @@ signature_check( PKT_signature *sig, MD_HANDLE digest ) leave: - if( pkc ) - free_public_cert( pkc ); mpi_free( result ); return rc; } @@ -217,7 +228,7 @@ check_key_signature( KBNODE root, KBNODE node, int *is_selfsig ) md = md_open( algo, 0 ); hash_public_cert( md, pkc ); md_write( md, uid->name, uid->len ); - rc = signature_check( sig, md ); + rc = do_check( pkc, sig, md ); md_close(md); } else { diff --git a/g10/sign.c b/g10/sign.c index d6777442a..6040f4caf 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -152,7 +152,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, if( opt.armor && !outfile ) iobuf_push_filter( out, armor_filter, &afx ); - write_comment( out, "#Created by G10 pre-release " VERSION ); + write_comment( out, "#created by G10 v" VERSION " (" + PRINTABLE_OS_NAME ")"); if( opt.compress && !outfile ) iobuf_push_filter( out, compress_filter, &zfx ); @@ -629,7 +630,7 @@ remove_keysigs( KBNODE keyblock, int all ) for( kbctx=NULL; (node=walk_kbnode( keyblock, &kbctx, 1)) ; ) { if( node->flag & 128) - delete_kbnode( keyblock, node ); + delete_kbnode(node ); } return 1; @@ -969,6 +970,7 @@ change_passphrase( const char *username ) /**************** * Create a signature packet for the given public key certificate * and the user id and return it in ret_sig. User signature class SIGCLASS + * user-id is not used (and may be NULL if sigclass is 0x20) */ int make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc, @@ -979,11 +981,12 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_cert *pkc, int rc=0; MD_HANDLE md; - assert( sigclass >= 0x10 && sigclass <= 0x13 ); + assert( (sigclass >= 0x10 && sigclass <= 0x13) || sigclass == 0x20 ); md = md_open( digest_algo, 0 ); /* hash the public key certificate and the user id */ hash_public_cert( md, pkc ); - md_write( md, uid->name, uid->len ); + if( sigclass != 0x20 ) + md_write( md, uid->name, uid->len ); /* and make the signature packet */ sig = m_alloc_clear( sizeof *sig ); sig->pubkey_algo = skc->pubkey_algo; diff --git a/include/cipher.h b/include/cipher.h index 7262d5c66..d0fe788ae 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -73,6 +73,9 @@ int cipher_debug_mode; int string_to_cipher_algo( const char *string ); int string_to_pubkey_algo( const char *string ); int string_to_digest_algo( const char *string ); +const char * cipher_algo_to_string( int algo ); +const char * pubkey_algo_to_string( int algo ); +const char * digest_algo_to_string( int algo ); int check_cipher_algo( int algo ); int check_pubkey_algo( int algo ); int check_digest_algo( int algo ); diff --git a/include/iobuf.h b/include/iobuf.h index a57d7a9ab..61c765395 100644 --- a/include/iobuf.h +++ b/include/iobuf.h @@ -89,6 +89,7 @@ int iobuf_seek( IOBUF a, ulong newpos ); int iobuf_readbyte(IOBUF a); int iobuf_read(IOBUF a, byte *buf, unsigned buflen ); +int iobuf_peek(IOBUF a, byte *buf, unsigned buflen ); int iobuf_writebyte(IOBUF a, unsigned c); int iobuf_write(IOBUF a, byte *buf, unsigned buflen ); int iobuf_writestr(IOBUF a, const char *buf ); diff --git a/mpi/ChangeLog b/mpi/ChangeLog index e69de29bb..f05c13e17 100644 --- a/mpi/ChangeLog +++ b/mpi/ChangeLog @@ -0,0 +1,5 @@ +Mon Feb 16 13:00:27 1998 Werner Koch (wk@isil.d.shuttle.de) + + * config.links : Add detection of m68k cpus + + diff --git a/mpi/Makefile.am b/mpi/Makefile.am index 2801a7519..759b33b1e 100644 --- a/mpi/Makefile.am +++ b/mpi/Makefile.am @@ -43,7 +43,6 @@ common_asm_objects = mpih-mul1.o \ mpih-sub1.o \ mpih-shift.o +libmpi_a_DEPENDENCIES = $(common_asm_objects) @MPI_EXTRA_ASM_OBJS@ libmpi_a_LIBADD = $(common_asm_objects) @MPI_EXTRA_ASM_OBJS@ -$(LIBRARIES): $(common_asm_objects) @MPI_EXTRA_ASM_OBJS@ - diff --git a/mpi/Makefile.in b/mpi/Makefile.in index 87976eebe..e11c23c96 100644 --- a/mpi/Makefile.in +++ b/mpi/Makefile.in @@ -125,6 +125,7 @@ common_asm_objects = mpih-mul1.o \ mpih-sub1.o \ mpih-shift.o +libmpi_a_DEPENDENCIES = $(common_asm_objects) @MPI_EXTRA_ASM_OBJS@ libmpi_a_LIBADD = $(common_asm_objects) @MPI_EXTRA_ASM_OBJS@ mkinstalldirs = $(SHELL) $(top_srcdir)/scripts/mkinstalldirs CONFIG_HEADER = ../config.h @@ -136,8 +137,6 @@ DEFS = @DEFS@ -I. -I$(srcdir) -I.. CPPFLAGS = @CPPFLAGS@ LDFLAGS = @LDFLAGS@ LIBS = @LIBS@ -libmpi_a_DEPENDENCIES = mpih-mul1.o mpih-mul2.o mpih-mul3.o mpih-add1.o \ -mpih-sub1.o mpih-shift.o libmpi_a_OBJECTS = mpi-add.o mpi-bit.o mpi-cmp.o mpi-div.o mpi-gcd.o \ mpi-inv.o mpi-mul.o mpi-pow.o mpi-mpow.o mpi-scan.o mpicoder.o \ mpih-cmp.o mpih-add.o mpih-sub.o mpih-div.o mpih-mul.o mpiutil.o @@ -334,8 +333,6 @@ maintainer-clean-generic clean mostlyclean distclean maintainer-clean CFLAGS += -O2 -$(LIBRARIES): $(common_asm_objects) @MPI_EXTRA_ASM_OBJS@ - # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: diff --git a/mpi/config.links b/mpi/config.links index 4c7cbf259..83c6b71eb 100644 --- a/mpi/config.links +++ b/mpi/config.links @@ -68,6 +68,39 @@ case "${target}" in path="sparc32" mpi_extra_modules="udiv" ;; + + # Motorola 68k configurations. Let m68k mean 68020-68040. + # mc68000 or mc68060 configurations need to be specified explicitly + m680[234]0*-*-linuxaout* | m68k*-*-linuxaout*) + echo '#define MIT_SYNTAX' >./mpi/asm-syntax.h + cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h + path="m68k/mc68020 m68k" + ;; + m68060*-*-linuxaout*) + echo '#define MIT_SYNTAX' >./mpi/asm-syntax.h + cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h + path="m68k" + ;; + m680[234]0*-*-linux* | m68k*-*-linux*) + echo '#define ELF_SYNTAX' >./mpi/asm-syntax.h + cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h + path="m68k/mc68020 m68k" + ;; + m68060*-*-linux*) + echo '#define ELF_SYNTAX' >./mpi/asm-syntax.h + cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h + path="m68k" + ;; + m68000*-*-* | m68060*-*-*) + echo '#define MIT_SYNTAX' >./mpi/asm-syntax.h + cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h + path="m68k/mc68000" + ;; + m680[234]0*-*-* | m68k*-*-*) + echo '#define MIT_SYNTAX' >./mpi/asm-syntax.h + cat $srcdir/mpi/m68k/syntax.h >>./mpi/asm-syntax.h + path="m68k/mc68020 m68k" + ;; *) echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h path="" diff --git a/mpi/m68k/distfiles b/mpi/m68k/distfiles new file mode 100644 index 000000000..88494d955 --- /dev/null +++ b/mpi/m68k/distfiles @@ -0,0 +1 @@ +syntax.h diff --git a/mpi/m68k/mc68020/distfiles b/mpi/m68k/mc68020/distfiles new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/mpi/m68k/mc68020/distfiles diff --git a/mpi/m68k/syntax.h b/mpi/m68k/syntax.h new file mode 100644 index 000000000..9d6f3522b --- /dev/null +++ b/mpi/m68k/syntax.h @@ -0,0 +1,177 @@ +/* asm.h -- Definitions for 68k syntax variations. + +Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc. + +This file is part of the GNU MP Library. + +The GNU MP Library is free software; you can redistribute it and/or modify +it under the terms of the GNU Library General Public License as published by +the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +The GNU MP Library 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 Library General Public +License for more details. + +You should have received a copy of the GNU Library General Public License +along with the GNU MP Library; see the file COPYING.LIB. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, +MA 02111-1307, USA. */ + +#undef ALIGN + +#ifdef MIT_SYNTAX +#define PROLOG(name) +#define EPILOG(name) +#define R(r)r +#define MEM(base)base@ +#define MEM_DISP(base,displacement)base@(displacement) +#define MEM_INDX(base,idx,size_suffix)base@(idx:size_suffix) +#define MEM_INDX1(base,idx,size_suffix,scale)base@(idx:size_suffix:scale) +#define MEM_PREDEC(memory_base)memory_base@- +#define MEM_POSTINC(memory_base)memory_base@+ +#define L(label) label +#define TEXT .text +#define ALIGN .even +#define GLOBL .globl +#define moveql moveq +/* Use variable sized opcodes. */ +#define bcc jcc +#define bcs jcs +#define bls jls +#define beq jeq +#define bne jne +#define bra jra +#endif + +#ifdef SONY_SYNTAX +#define PROLOG(name) +#define EPILOG(name) +#define R(r)r +#define MEM(base)(base) +#define MEM_DISP(base,displacement)(displacement,base) +#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix) +#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale) +#define MEM_PREDEC(memory_base)-(memory_base) +#define MEM_POSTINC(memory_base)(memory_base)+ +#define L(label) label +#define TEXT .text +#define ALIGN .even +#define GLOBL .globl +#endif + +#ifdef MOTOROLA_SYNTAX +#define PROLOG(name) +#define EPILOG(name) +#define R(r)r +#define MEM(base)(base) +#define MEM_DISP(base,displacement)(displacement,base) +#define MEM_INDX(base,idx,size_suffix)(base,idx.size_suffix) +#define MEM_INDX1(base,idx,size_suffix,scale)(base,idx.size_suffix*scale) +#define MEM_PREDEC(memory_base)-(memory_base) +#define MEM_POSTINC(memory_base)(memory_base)+ +#define L(label) label +#define TEXT +#define ALIGN +#define GLOBL XDEF +#define lea LEA +#define movel MOVE.L +#define moveml MOVEM.L +#define moveql MOVEQ.L +#define cmpl CMP.L +#define orl OR.L +#define clrl CLR.L +#define eorw EOR.W +#define lsrl LSR.L +#define lsll LSL.L +#define roxrl ROXR.L +#define roxll ROXL.L +#define addl ADD.L +#define addxl ADDX.L +#define addql ADDQ.L +#define subl SUB.L +#define subxl SUBX.L +#define subql SUBQ.L +#define negl NEG.L +#define mulul MULU.L +#define bcc BCC +#define bcs BCS +#define bls BLS +#define beq BEQ +#define bne BNE +#define bra BRA +#define dbf DBF +#define rts RTS +#define d0 D0 +#define d1 D1 +#define d2 D2 +#define d3 D3 +#define d4 D4 +#define d5 D5 +#define d6 D6 +#define d7 D7 +#define a0 A0 +#define a1 A1 +#define a2 A2 +#define a3 A3 +#define a4 A4 +#define a5 A5 +#define a6 A6 +#define a7 A7 +#define sp SP +#endif + +#ifdef ELF_SYNTAX +#define PROLOG(name) .type name,@function +#define EPILOG(name) .size name,.-name +#define MEM(base)(R(base)) +#define MEM_DISP(base,displacement)(displacement,R(base)) +#define MEM_PREDEC(memory_base)-(R(memory_base)) +#define MEM_POSTINC(memory_base)(R(memory_base))+ +#ifdef __STDC__ +#define R_(r)%##r +#define R(r)R_(r) +#define MEM_INDX_(base,idx,size_suffix)(R(base),R(idx##.##size_suffix)) +#define MEM_INDX(base,idx,size_suffix)MEM_INDX_(base,idx,size_suffix) +#define MEM_INDX1_(base,idx,size_suffix,scale)(R(base),R(idx##.##size_suffix*scale)) +#define MEM_INDX1(base,idx,size_suffix,scale)MEM_INDX1_(base,idx,size_suffix,scale) +#define L(label) .##label +#else +#define R(r)%/**/r +#define MEM_INDX(base,idx,size_suffix)(R(base),R(idx).size_suffix) +#define MEM_INDX1(base,idx,size_suffix,scale)(R(base),R(idx).size_suffix*scale) +#define L(label) ./**/label +#endif +#define TEXT .text +#define ALIGN .align 2 +#define GLOBL .globl +#define bcc jbcc +#define bcs jbcs +#define bls jbls +#define beq jbeq +#define bne jbne +#define bra jbra +#endif + +#if defined (SONY_SYNTAX) || defined (ELF_SYNTAX) +#define movel move.l +#define moveml movem.l +#define moveql moveq.l +#define cmpl cmp.l +#define orl or.l +#define clrl clr.l +#define eorw eor.w +#define lsrl lsr.l +#define lsll lsl.l +#define roxrl roxr.l +#define roxll roxl.l +#define addl add.l +#define addxl addx.l +#define addql addq.l +#define subl sub.l +#define subxl subx.l +#define subql subq.l +#define negl neg.l +#define mulul mulu.l +#endif diff --git a/util/ChangeLog b/util/ChangeLog index c72c6b80f..770fe9e90 100644 --- a/util/ChangeLog +++ b/util/ChangeLog @@ -1,3 +1,12 @@ +Mon Feb 16 10:07:28 1998 Werner Koch (wk@isil.d.shuttle.de) + + * argparse.c (show_version, show_help, default_strusage): Changed + according to GNU standards. + +Mon Feb 16 08:58:25 1998 Werner Koch (wk@isil.d.shuttle.de) + + * iobuf.c (iobuf_peek): New + Fri Feb 13 19:34:59 1998 Werner Koch (wk@isil.d.shuttle.de) * iobuf.c (iobuf_seek): Set counters to new offset. diff --git a/util/argparse.c b/util/argparse.c index 620211e31..a9965d836 100644 --- a/util/argparse.c +++ b/util/argparse.c @@ -376,11 +376,12 @@ arg_parse( ARGPARSE_ARGS *arg, ARGPARSE_OPTS *opts) if( !opts[i].short_opt && !strcmp( "help", s+2) ) show_help(opts, arg->flags); - else if( !opts[i].short_opt && !strcmp( "version", s+2) ) + else if( !opts[i].short_opt && !strcmp( "version", s+2) ) { show_version(); + exit(0); + } else if( !opts[i].short_opt && !strcmp( "warranty", s+2) ) { - puts( strusage(10) ); - puts( strusage(31) ); + puts( strusage(16) ); exit(0); } @@ -525,13 +526,9 @@ show_help( ARGPARSE_OPTS *opts, unsigned flags ) { const char *s; - s = strusage(10); - fputs( s, stdout ); - if( *s && s[strlen(s)-1] != '\n' ) - putchar( '\n' ); - s = strusage(12); - if( *s == '\n' ) - s++; + show_version(); + putchar('\n'); + s = strusage(41); puts(s); if( opts[0].description ) { /* auto format the option description */ int i,j, indent; @@ -591,11 +588,7 @@ show_help( ARGPARSE_OPTS *opts, unsigned flags ) if( flags & 32 ) puts("\n(A single dash may be used instead of the double ones)"); } - if( *(s=strusage(26)) ) { /* bug reports to ... */ - putchar('\n'); - fputs(s, stdout); - } - if( *(s=strusage(30)) ) { /* special notes */ + if( (s=strusage(19)) ) { /* bug reports to ... */ putchar('\n'); fputs(s, stdout); } @@ -607,189 +600,96 @@ static void show_version() { const char *s; - printf("%s version %s (%s", strusage(13), strusage(14), strusage(45) ); - if( (s = strusage(24)) && *s ) { - #ifdef DEBUG - printf(", %s, dbg)\n", s); - #else - printf(", %s)\n", s); - #endif - } - else { - #ifdef DEBUG - printf(", dbg)\n"); - #else - printf(")\n"); - #endif - } + int i; + /* version line */ + fputs(strusage(11), stdout); + if( (s=strusage(12)) ) + printf(" (%s)", s ); + printf(" %s\n", strusage(13) ); + /* additional version lines */ + for(i=20; i < 30; i++ ) + if( (s=strusage(i)) ) + printf("%s\n", s ); + /* copyright string */ + if( (s=strusage(14)) ) + printf("%s\n", s ); + /* copying conditions */ + if( (s=strusage(15)) ) + fputs(s, stdout); + /* thanks */ + if( (s=strusage(18)) ) + fputs(s, stdout); + /* additional program info */ + for(i=30; i < 40; i++ ) + if( (s=strusage(i)) ) + fputs(s, stdout); fflush(stdout); - exit(0); } - void usage( int level ) { - static int sentinel=0; - - if( sentinel ) - return; - - sentinel++; if( !level ) { - fputs( strusage(level), stderr ); putc( '\n', stderr ); - fputs( strusage(31), stderr); - #if DEBUG - fprintf(stderr, "%s (%s - Debug)\n", strusage(32), strusage(24) ); - #else - fprintf(stderr, "%s (%s)\n", strusage(32), strusage(24) ); - #endif + fprintf(stderr,"%s %s; %s\n", strusage(11), strusage(13), + strusage(14) ); fflush(stderr); } else if( level == 1 ) { - fputs(strusage(level),stderr);putc('\n',stderr); - exit(2);} + fputs(strusage(40),stderr); + exit(2); + } else if( level == 2 ) { - puts(strusage(level)); exit(0);} - sentinel--; + puts(strusage(41)); + exit(0); + } } - +/* Level + * 0: Copyright String auf stderr ausgeben + * 1: Kurzusage auf stderr ausgeben und beenden + * 2: Langusage auf stdout ausgeben und beenden + * 11: name of program + * 12: optional name of package which includes this program. + * 13: version string + * 14: copyright string + * 15: Short copying conditions (with LFs) + * 16: Long copying conditions (with LFs) + * 17: Optional printable OS name + * 18: Optional thanks list (with LFs) + * 19: Bug report info + *20..29: Additional lib version strings. + *30..39: Additional program infos (with LFs) + * 40: short usage note (with LF) + * 41: long usage note (with LF) + */ const char * default_strusage( int level ) { - const char *p; + const char *p = NULL; switch( level ) { - case 0: p = strusage(10); break; - case 1: p = strusage(11); break; - case 2: p = strusage(12); break; - case 10: p = "WkLib" - #if DOS386 && __WATCOMC__ - " (DOS4G)" - #elif DOS386 - " (DOSX)" - #elif DOS16RM - " (DOS16RM)" - #elif M_I86VM - " (VCM)" - #elif UNIX || POSIX - " (Posix)" - #elif OS2 - " (OS/2)" - #elif WINNT && __CYGWIN32__ - " (CygWin)" - #elif WINNT - " (WinNT)" - #elif NETWARE - " (Netware)" - #elif VMS - " (VMS)" - #endif - "; Copyright (c) 1997 by Werner Koch (dd9jn)" ; break; - case 11: p = "usage: ?"; break; - case 16: - case 15: p = "[Untitled]"; break; - case 23: p = "[unknown]"; break; - case 24: p = ""; break; - case 26: p = ""; break; - case 12: p = - "This is free software; you can redistribute it and/or modify\n" - "it under the terms of the GNU General Public License as published by\n" - "the Free Software Foundation; either version 2 of the License, or\n" - "(at your option) any later version.\n\n" - "It is distributed in the hope that it will be useful,\n" - "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" - "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" - "GNU General Public License for more details.\n\n" - "You should have received a copy of the GNU General Public License\n" - "along with this program; if not, write to the Free Software\n" - "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307," - " USA.\n" ; + case 11: p = "foo"; break; + case 13: p = "0.0"; break; + case 14: p = "Copyright (C) 1998 Werner Koch (dd9jn)" ; break; + case 15: p = +"This program comes with ABSOLUTELY NO WARRANTY.\n" +"This is free software, and you are welcome to redistribute it\n" +"under certain conditions. See the file COPYING for details.\n"; break; + case 16: p = +"This is free software; you can redistribute it and/or modify\n" +"it under the terms of the GNU General Public License as published by\n" +"the Free Software Foundation; either version 2 of the License, or\n" +"(at your option) any later version.\n\n" +"It is distributed in the hope that it will be useful,\n" +"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +"GNU General Public License for more details.\n\n" +"You should have received a copy of the GNU General Public License\n" +"along with this program; if not, write to the Free Software\n" +"Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"; break; - case 22: - #if MSDOS - #if USE_EMS - p = "MSDOS+EMS"; - #else - p = "MSDOS"; - #endif - #elif OS2 - p = "OS/2"; - #elif WINNT && __CYGWIN32__ - p = "CygWin"; - #elif WINNT - p = "WinNT"; - #elif DOS386 - p = "DOS386"; - #elif EMX - p = "EMX"; - #elif DOS16RM - p = "DOS16RM"; - #elif NETWARE - p = "Netware"; - #elif __linux__ - p = "Linux"; - #elif UNIX || M_UNIX || M_XENIX - p = "UNIX"; - #elif VMS - p = "VMS"; - #else - p = "UnknownOS"; - #endif - break; - case 30: p = ""; break; - case 31: p = - "This program comes with ABSOLUTELY NO WARRANTY.\n" - "This is free software, and you are welcome to redistribute it\n" - "under certain conditions. See the file COPYING for details.\n"; - break; - case 32: p = "[" - #if MSDOS - "MSDOS Version" - #elif DOS386 && __ZTC__ - "32-Bit MSDOS Version (Zortech's DOSX)" - #elif DOS386 - "32-Bit MSDOS Version" - #elif OS20 && EMX - "OS/2 2.x EMX Version" - #elif OS20 - "OS/2 2.x Version" - #elif OS2 - "OS/2 1.x Version" - #elif WINNT && __CYGWIN32__ - "Cygnus WinAPI Version" - #elif WINNT - "Windoze NT Version" - #elif EMX - "EMX Version" - #elif NETWARE - "NLM Version" - #elif DOS16RM - "DOS16RM Version" - #elif __linux__ - "Linux Version" - #elif VMS - "OpenVMS Version" - #elif POSIX - "POSIX Version" - #elif M_UNIX || M_XENIX - "*IX Version" - #endif - "]"; - break; - case 33: p = - #ifdef MULTI_THREADED - "mt" - #else - "" - #endif - ; break; - case 42: - case 43: - case 44: - case 45: p = ""; break; - default: p = "?"; + case 40: /* short and long usage */ + case 41: p = ""; break; } return p; diff --git a/util/iobuf.c b/util/iobuf.c index cc3288d7e..5815cb538 100644 --- a/util/iobuf.c +++ b/util/iobuf.c @@ -741,6 +741,29 @@ iobuf_read(IOBUF a, byte *buf, unsigned buflen ) } +/**************** + * Have a look at the iobuf. + * NOTE: This does only work in special cases. + */ +int +iobuf_peek(IOBUF a, byte *buf, unsigned buflen ) +{ + int n=0; + + if( !(a->d.start < a->d.len) ) { + if( underflow(a) == -1 ) + return -1; + /* and unget this character */ + assert(a->d.start == 1); + a->d.start = 0; + } + + for(n=0 ; n < buflen && (a->d.start+n) < a->d.len ; n++, buf++ ) + *buf = a->d.buf[n]; + return n; +} + + int |