some import functionality

This commit is contained in:
Werner Koch 1998-02-16 20:05:02 +00:00
parent f477447d9a
commit 82464369f6
45 changed files with 1299 additions and 324 deletions

View File

@ -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

View File

@ -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.

9
NEWS
View File

@ -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
-----------------------------------

2
THANKS
View File

@ -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.

3
TODO
View File

@ -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

View File

@ -1 +1 @@
0.2.6
0.2.6a

View File

@ -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

View File

@ -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.

View File

@ -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@

View File

@ -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:

View File

@ -74,6 +74,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
*/
@ -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
*/

View File

@ -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

View File

@ -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 )

View File

@ -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.

View File

@ -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@

View File

@ -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)

View File

@ -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;
}

View File

@ -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 );

View File

@ -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);

109
g10/g10.c
View File

@ -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 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 26:
p = _("Please report bugs to <g10-bugs@isil.d.shuttle.de>.\n");
case 31: p = "\n"; break;
case 32:
if( !ciphers )
ciphers = build_list("Supported ciphers: ", cipher_algo_to_string,
check_cipher_algo );
p = ciphers;
break;
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;
#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
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);

View File

@ -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 40: p = _(
"Usage: g10maint [options] [files] (-h for help)"
); break;
case 41: p = _(
"Syntax: g10maint [options] [files]\n"
"G10 maintenance utility\n"
); break;
case 26:
p = _("Please report bugs to <g10-bugs@isil.d.shuttle.de>.\n");
case 31: p = "\n"; break;
case 32:
if( !ciphers )
ciphers = build_list("Supported ciphers: ", cipher_algo_to_string,
check_cipher_algo );
p = ciphers;
break;
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;
#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
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);

View File

@ -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:

View File

@ -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 )
{
log_fatal("Not yet implemented");
return 0;
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 )
{
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;
}

View File

@ -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;
}

View File

@ -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 );

View File

@ -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 );

View File

@ -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*/

View File

@ -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;
}
}
}

199
g10/revoke.c Normal file
View File

@ -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;
}

View File

@ -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 */

View File

@ -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:
*

View File

@ -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 {

View File

@ -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;

View File

@ -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 );

View File

@ -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 );

View File

@ -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

View File

@ -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@

View File

@ -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:

View File

@ -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=""

1
mpi/m68k/distfiles Normal file
View File

@ -0,0 +1 @@
syntax.h

View File

177
mpi/m68k/syntax.h Normal file
View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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