mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
added some stuff for signing keys
This commit is contained in:
parent
68ea0f4353
commit
15426c6d96
26
INSTALL
26
INSTALL
@ -0,0 +1,26 @@
|
||||
|
||||
1) Configure for your machine:
|
||||
|
||||
./configure
|
||||
|
||||
or use
|
||||
|
||||
./configure --enable-m-debug
|
||||
|
||||
to ebanle the integrated malloc debugging stuff.
|
||||
|
||||
|
||||
2) Run make:
|
||||
|
||||
make
|
||||
|
||||
|
||||
3) Install
|
||||
|
||||
make install
|
||||
|
||||
|
||||
4) You end up with a binary "g10" in /usr/local/bin
|
||||
|
||||
|
||||
|
50
README
50
README
@ -0,0 +1,50 @@
|
||||
|
||||
G10 - The GNU Enryption and Signing Tool
|
||||
------------------------------------------
|
||||
|
||||
|
||||
THIS IS VERSION IS ONLY a TEST VERSION ! YOU SHOULD NOT
|
||||
USE IT FOR OTHER PURPOSES THAN EVALUATING THE CURRENT CODE.
|
||||
|
||||
* The data format may change in the next version!
|
||||
|
||||
* The code to generate keys is not secure!
|
||||
|
||||
* Some features are not implemented
|
||||
|
||||
|
||||
I provide this version as a reality check to start discussion.
|
||||
Please subscribe to g10@net.lut.ac.uk be sending a mail with
|
||||
the word "subscribe" in the body to "g10-request@net.lut.ac.uk".
|
||||
|
||||
|
||||
See the file COPYING for copyright and warranty information.
|
||||
|
||||
|
||||
Due to the fact that G10 does not use use any patented algorithm,
|
||||
it cannot be compatible to old PGP versions, because those use
|
||||
IDEA (which is worldwide patented) and RSA (which is patented in
|
||||
the United States until Sep 20, 2000). I'm sorry about this, but
|
||||
this is the world we have created (e.g. by using propiertary software).
|
||||
|
||||
|
||||
Because the OpenPGP standard is still a draft, G10 is not yet
|
||||
compatible to it (or PGP 5) - but it will. The data structures
|
||||
used are compatible with PGP 2.x, so it can parse an list such files
|
||||
and PGP should be able to parse data created by G10 and complain
|
||||
about unsupported alogorithms.
|
||||
|
||||
The default algorithms used by G10 are ElGamal for public-key
|
||||
encryption and signing; Blowfish with a 160 bit key for protecting
|
||||
the secret-key components, conventional and session encryption;
|
||||
RIPE MD-160 to create message digest. DSA, SHA-1 and CAST are
|
||||
also implemented, but not used on default. I decided not
|
||||
to use DSA as default signing algorithm, cecause it allows only for
|
||||
1024 bit keys and this may be not enough in a couple of years.
|
||||
|
||||
Key generation takes a long time and should be improved!
|
||||
|
||||
|
||||
|
||||
|
||||
|
12
TODO
12
TODO
@ -8,14 +8,10 @@
|
||||
* keyring editing
|
||||
* add trust stuff
|
||||
* make ttyio.c work (hide passwords etc..)
|
||||
* add option file handling.
|
||||
* use correct ASN values for DEK encoding
|
||||
* add checking of armor trailers
|
||||
* add real secure memory
|
||||
* look for a way to reuse RSA signatures
|
||||
* find a way to remove the armor filter after it
|
||||
has detected, that the data is not armored.
|
||||
* Use the Chinese Remainder Theorem to speed up RSA calculations.
|
||||
* remove all "Fixmes"
|
||||
* speed up the RIPE-MD-160
|
||||
* add signal handling
|
||||
@ -33,3 +29,11 @@
|
||||
* complete cipher/cast.c
|
||||
* complete cipher/dsa.c
|
||||
|
||||
* define a standard way to specify keyid/userid and other stuff
|
||||
to identify a user. We could look at the first character and
|
||||
say: If it's a digit, a keyid follows (need to add a zero in
|
||||
case the keyid starts with A..F); if it is a left angle bracket,
|
||||
this is a email address and should be used, all others are substrings
|
||||
of the userid.
|
||||
[can be handles in get_pubkey_by_name()]
|
||||
|
||||
|
@ -24,6 +24,6 @@ cipher_SOURCES = blowfish.c \
|
||||
md.c \
|
||||
smallprime.c
|
||||
|
||||
cipher_LIBADD = rsa.o
|
||||
##cipher_LIBADD = rsa.o
|
||||
|
||||
|
||||
|
@ -60,8 +60,6 @@ cipher_SOURCES = blowfish.c \
|
||||
dsa.c \
|
||||
md.c \
|
||||
smallprime.c
|
||||
|
||||
cipher_LIBADD = rsa.o
|
||||
mkinstalldirs = $(top_srcdir)/scripts/mkinstalldirs
|
||||
CONFIG_HEADER = ../config.h
|
||||
LIBRARIES = $(noinst_LIBRARIES)
|
||||
@ -80,6 +78,7 @@ LIBS = @LIBS@
|
||||
|
||||
COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
|
||||
LINK = $(CC) $(LDFLAGS) -o $@
|
||||
cipher_LIBADD =
|
||||
cipher_OBJECTS = blowfish.o elgamal.o gost.o md5.o primegen.o random.o \
|
||||
rmd160.o sha1.o dsa.o md.o smallprime.o
|
||||
EXTRA_cipher_SOURCES =
|
||||
|
16
configure.in
16
configure.in
@ -22,21 +22,20 @@ fi
|
||||
CFLAGS="-g"
|
||||
|
||||
dnl
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_SYSTEM
|
||||
AC_MSG_CHECKING(cached information)
|
||||
hostcheck="$host"
|
||||
hostcheck="$target"
|
||||
AC_CACHE_VAL(ac_cv_mpi_hostcheck, [ ac_cv_mpi_hostcheck="$hostcheck" ])
|
||||
if test "$ac_cv_mpi_hostcheck" != "$hostcheck"; then
|
||||
AC_MSG_RESULT(changed)
|
||||
AC_MSG_WARN(config.cache exists!)
|
||||
AC_MSG_ERROR(you must do 'make distclean' first to compile for
|
||||
different host or different parameters.)
|
||||
different target or different parameters.)
|
||||
else
|
||||
AC_MSG_RESULT(ok)
|
||||
fi
|
||||
|
||||
|
||||
|
||||
dnl Checks for programs.
|
||||
|
||||
AC_PROG_MAKE_SET
|
||||
@ -71,8 +70,12 @@ AC_CHECK_FUNCS(strerror strtol strtoul)
|
||||
|
||||
|
||||
dnl setup assembler stuff
|
||||
|
||||
|
||||
if test -f ./mpi/config.links ; then
|
||||
. ./mpi/config.links
|
||||
AC_LINK_FILES( ${mpi_ln_src}, ${mpi_ln_dst} )
|
||||
else
|
||||
AC_MSG_ERROR([mpi/config.links missing!])
|
||||
fi
|
||||
|
||||
|
||||
|
||||
@ -91,6 +94,7 @@ fi
|
||||
AC_SUBST(add_cipher_SOURCES)
|
||||
|
||||
AC_OUTPUT([ Makefile scripts/Makefile util/Makefile mpi/Makefile \
|
||||
mpi/generic/Makefile mpi/i386/Makefile \
|
||||
cipher/Makefile \
|
||||
include/Makefile \
|
||||
g10/Makefile tools/Makefile ],
|
||||
|
@ -218,7 +218,7 @@ encode_crypt( const char *filename, STRLIST remusr )
|
||||
pkc = m_alloc_clear( sizeof *pkc );
|
||||
pkc->pubkey_algo = DEFAULT_PUBKEY_ALGO;
|
||||
|
||||
if( (rc = get_pubkey_by_name( pkc, remusr->d )) ) {
|
||||
if( (rc = get_pubkey_byname( pkc, remusr->d )) ) {
|
||||
last_rc = rc;
|
||||
log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) );
|
||||
continue;
|
||||
|
47
g10/g10.c
47
g10/g10.c
@ -125,20 +125,21 @@ main( int argc, char **argv )
|
||||
{ 510, "debug" ,4|16, "set debugging flags" },
|
||||
{ 511, "debug-all" ,0, "enable full debugging"},
|
||||
{ 512, "cache-all" ,0, "hold everything in memory"},
|
||||
{ 513, "gen-prime" , 1, "\rgenerate a prime of length n" },
|
||||
{ 514, "test" , 0, "\rdevelopment usage" },
|
||||
{ 513, "gen-prime" , 1, "\r" },
|
||||
{ 514, "test" , 0, "\r" },
|
||||
{ 515, "change-passphrase", 0, "change the passphrase of your secret keyring"},
|
||||
{ 515, "fingerprint", 0, "show the fingerprints"},
|
||||
{ 516, "print-mds" , 0, "print all message digests"},
|
||||
{ 517, "secret-keyring" ,2, "add this secret keyring to the list" },
|
||||
{ 518, "config" , 2, "use this config file" },
|
||||
{ 519, "no-armor", 0, "\r"},
|
||||
|
||||
{0} };
|
||||
ARGPARSE_ARGS pargs;
|
||||
IOBUF a;
|
||||
int rc;
|
||||
enum { aNull, aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
|
||||
aTest, aPrintMDs,
|
||||
aTest, aPrintMDs, aSignKey,
|
||||
} action = aNull;
|
||||
int orig_argc;
|
||||
char **orig_argv;
|
||||
@ -189,7 +190,7 @@ main( int argc, char **argv )
|
||||
configfp = fopen( configname, "r" );
|
||||
if( !configfp ) {
|
||||
if( default_config ) {
|
||||
if( parse_verbose )
|
||||
if( parse_verbose > 1 )
|
||||
log_info("note: no default option file '%s'\n", configname );
|
||||
}
|
||||
else
|
||||
@ -197,7 +198,7 @@ main( int argc, char **argv )
|
||||
configname, strerror(errno) );
|
||||
m_free(configname); configname = NULL;
|
||||
}
|
||||
if( parse_verbose )
|
||||
if( parse_verbose > 1 )
|
||||
log_info("reading options from '%s'\n", configname );
|
||||
default_config = 0;
|
||||
}
|
||||
@ -209,7 +210,7 @@ main( int argc, char **argv )
|
||||
opt.list_sigs=1;
|
||||
break;
|
||||
case 'z': opt.compress = pargs.r.ret_int; break;
|
||||
case 'a': opt.armor = 1; break;
|
||||
case 'a': opt.armor = 1; opt.no_armor=0; break;
|
||||
case 'c': action = aSym; break;
|
||||
case 'o': opt.outfile = pargs.r.ret_str;
|
||||
if( opt.outfile[0] == '-' && !opt.outfile[1] )
|
||||
@ -235,6 +236,7 @@ main( int argc, char **argv )
|
||||
case 501: opt.answer_yes = 1; break;
|
||||
case 502: opt.answer_no = 1; break;
|
||||
case 503: action = aKeygen; break;
|
||||
case 506: action = aSignKey; break;
|
||||
case 507: action = aStore; break;
|
||||
case 508: opt.check_sigs = 1; opt.list_sigs = 1; break;
|
||||
case 509: add_keyring(pargs.r.ret_str); nrings++; break;
|
||||
@ -254,6 +256,7 @@ main( int argc, char **argv )
|
||||
goto next_pass;
|
||||
}
|
||||
break;
|
||||
case 519: opt.no_armor=1; opt.armor=0; break;
|
||||
default : errors++; pargs.err = configfp? 1:2; break;
|
||||
}
|
||||
}
|
||||
@ -270,7 +273,7 @@ main( int argc, char **argv )
|
||||
set_debug();
|
||||
if( opt.verbose > 1 )
|
||||
set_packet_list_mode(1);
|
||||
if( !opt.batch && isatty(fileno(stdin)) ) {
|
||||
if( opt.verbose && isatty(fileno(stdin)) ) {
|
||||
if( *(s=strusage(10)) )
|
||||
fputs(s, stderr);
|
||||
if( *(s=strusage(30)) )
|
||||
@ -278,11 +281,14 @@ main( int argc, char **argv )
|
||||
}
|
||||
|
||||
if( !sec_nrings ) { /* add default secret rings */
|
||||
add_keyring("../keys/secring.g10");
|
||||
char *p = make_filename("~/.g10", "secring.g10", NULL );
|
||||
add_secret_keyring(p);
|
||||
m_free(p);
|
||||
}
|
||||
if( !nrings ) { /* add default rings */
|
||||
add_keyring("../keys/ring.pgp");
|
||||
add_keyring("../keys/pubring.g10");
|
||||
if( !nrings ) { /* add default ring */
|
||||
char *p = make_filename("~/.g10", "pubring.g10", NULL );
|
||||
add_keyring(p);
|
||||
m_free(p);
|
||||
}
|
||||
|
||||
if( argc ) {
|
||||
@ -323,10 +329,21 @@ main( int argc, char **argv )
|
||||
log_error("sign_file('%s'): %s\n", fname_print, g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
|
||||
case aSignEncr: /* sign and encrypt the given file */
|
||||
usage(1); /* FIXME */
|
||||
break;
|
||||
|
||||
|
||||
case aSignKey: /* sign the key given as argument */
|
||||
if( argc != 1 )
|
||||
usage(1);
|
||||
/* note: fname is the user id! */
|
||||
if( (rc = sign_key(fname, locusr)) )
|
||||
log_error("sign_key('%s'): %s\n", fname_print, g10_errstr(rc) );
|
||||
break;
|
||||
|
||||
|
||||
case aPrimegen:
|
||||
if( argc )
|
||||
usage(1);
|
||||
@ -356,9 +373,11 @@ main( int argc, char **argv )
|
||||
usage(1);
|
||||
if( !(a = iobuf_open(fname)) )
|
||||
log_fatal("can't open '%s'\n", fname_print);
|
||||
/* 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( !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 );
|
||||
}
|
||||
proc_packets( a );
|
||||
iobuf_close(a);
|
||||
break;
|
||||
|
13
g10/getkey.c
13
g10/getkey.c
@ -83,9 +83,9 @@ add_keyring( const char *name )
|
||||
* combine it with the keyblock stuff from ringedit.c
|
||||
* For now we will simple add the filename as keyblock resource
|
||||
*/
|
||||
rc = add_keyblock_resource( name );
|
||||
rc = add_keyblock_resource( name, 0 );
|
||||
if( rc )
|
||||
log_error("keyblock resource '%s': %s\n", name, rc );
|
||||
log_error("keyblock resource '%s': %s\n", name, g10_errstr(rc) );
|
||||
}
|
||||
|
||||
void
|
||||
@ -245,7 +245,7 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid )
|
||||
* a pubkey with that algo.
|
||||
*/
|
||||
int
|
||||
get_pubkey_by_name( PKT_public_cert *pkc, const char *name )
|
||||
get_pubkey_byname( PKT_public_cert *pkc, const char *name )
|
||||
{
|
||||
int internal = 0;
|
||||
int rc = 0;
|
||||
@ -304,7 +304,7 @@ get_seckey( PKT_secret_cert *skc, u32 *keyid )
|
||||
* If NAME is NULL use the default certificate
|
||||
*/
|
||||
int
|
||||
get_seckey_by_name( PKT_secret_cert *skc, const char *name )
|
||||
get_seckey_byname( PKT_secret_cert *skc, const char *name, int unprotect )
|
||||
{
|
||||
STRLIST sl;
|
||||
int rc=0;
|
||||
@ -319,8 +319,9 @@ get_seckey_by_name( PKT_secret_cert *skc, const char *name )
|
||||
/* get the secret key (this may prompt for a passprase to
|
||||
* unlock the secret key
|
||||
*/
|
||||
if( (rc = check_secret_key( skc )) )
|
||||
goto leave;
|
||||
if( unprotect )
|
||||
if( (rc = check_secret_key( skc )) )
|
||||
goto leave;
|
||||
|
||||
leave:
|
||||
return rc;
|
||||
|
63
g10/kbnode.c
63
g10/kbnode.c
@ -56,6 +56,36 @@ release_kbnode( KBNODE n )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Append NODE to ROOT, ROOT must exist!
|
||||
*/
|
||||
void
|
||||
add_kbnode( KBNODE root, KBNODE node )
|
||||
{
|
||||
KBNODE n1;
|
||||
|
||||
for(n1=root; n1->next; n1 = n1->next)
|
||||
;
|
||||
n1->next = node;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Append NODE to ROOT as child of ROOT
|
||||
*/
|
||||
void
|
||||
add_kbnode_as_child( KBNODE root, KBNODE node )
|
||||
{
|
||||
KBNODE n1;
|
||||
|
||||
if( !(n1=root->child) )
|
||||
root->child = node;
|
||||
else {
|
||||
for( ; n1->next; n1 = n1->next)
|
||||
;
|
||||
n1->next = node;
|
||||
}
|
||||
}
|
||||
|
||||
/****************
|
||||
* Return the parent node of KBNODE from the tree with ROOT
|
||||
*/
|
||||
@ -72,8 +102,39 @@ find_kbparent( KBNODE root, KBNODE node )
|
||||
}
|
||||
}
|
||||
}
|
||||
log_bug(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Walk through a tree of kbnodes. This functions returns
|
||||
* the next kbnode for each call; before using the function the first
|
||||
* time, the caller must set CONTEXT to NULL (This has simply the effect
|
||||
* to start with ROOT).
|
||||
*/
|
||||
KBNODE
|
||||
walk_kbtree( KBNODE root, KBNODE *context )
|
||||
{
|
||||
KBNODE n;
|
||||
|
||||
if( !*context ) {
|
||||
*context = root;
|
||||
return root;
|
||||
}
|
||||
|
||||
n = *context;
|
||||
if( n->child ) {
|
||||
n = n->child;
|
||||
*context = n;
|
||||
}
|
||||
else if( n->next ) {
|
||||
n = n->next;
|
||||
*context = n;
|
||||
}
|
||||
else if( (n = find_kbparent( root, n )) ) {
|
||||
n = n->next;
|
||||
*context = n;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
13
g10/keydb.h
13
g10/keydb.h
@ -66,13 +66,14 @@ void add_secret_keyring( const char *name );
|
||||
void cache_public_cert( PKT_public_cert *pkc );
|
||||
void cache_user_id( PKT_user_id *uid, u32 *keyid );
|
||||
int get_pubkey( PKT_public_cert *pkc, u32 *keyid );
|
||||
int get_pubkey_by_name( PKT_public_cert *pkc, const char *name );
|
||||
int get_pubkey_byname( PKT_public_cert *pkc, const char *name );
|
||||
int get_seckey( PKT_secret_cert *skc, u32 *keyid );
|
||||
int get_seckey_by_name( PKT_secret_cert *skc, const char *name );
|
||||
int get_seckey_byname( PKT_secret_cert *skc, const char *name, int unlock );
|
||||
char*get_user_id_string( u32 *keyid );
|
||||
char*get_user_id( u32 *keyid, size_t *rn );
|
||||
|
||||
/*-- keyid.c --*/
|
||||
int pubkey_letter( int algo );
|
||||
u32 keyid_from_skc( PKT_secret_cert *skc, u32 *keyid );
|
||||
u32 keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid );
|
||||
u32 keyid_from_sig( PKT_signature *sig, u32 *keyid );
|
||||
@ -87,14 +88,18 @@ 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 add_kbnode( KBNODE root, KBNODE node );
|
||||
void add_kbnode_as_child( KBNODE root, KBNODE node );
|
||||
KBNODE find_kbparent( KBNODE root, KBNODE node );
|
||||
KBNODE walk_kbtree( KBNODE root, KBNODE *context );
|
||||
|
||||
/*-- ringedit.c --*/
|
||||
int add_keyblock_resource( const char *filename );
|
||||
int add_keyblock_resource( const char *filename, int force );
|
||||
int get_keyblock_handle( const char *filename, KBPOS *kbpos );
|
||||
int search_keyblock( PACKET *pkt, KBPOS *kbpos );
|
||||
int search_keyblock_byname( KBPOS *kbpos, const char *username );
|
||||
int lock_keyblock( KBPOS *kbpos );
|
||||
int unlock_keyblock( KBPOS *kbpos );
|
||||
void unlock_keyblock( KBPOS *kbpos );
|
||||
int read_keyblock( KBPOS *kbpos, KBNODE *ret_root );
|
||||
int insert_keyblock( KBPOS *kbpos, KBNODE root );
|
||||
int delete_keyblock( KBPOS *kbpos );
|
||||
|
363
g10/keygen.c
363
g10/keygen.c
@ -30,6 +30,7 @@
|
||||
#include "cipher.h"
|
||||
#include "ttyio.h"
|
||||
#include "options.h"
|
||||
#include "keydb.h"
|
||||
|
||||
#if 0
|
||||
#define TEST_ALGO 1
|
||||
@ -88,52 +89,128 @@ checksum_mpi( MPI a )
|
||||
|
||||
|
||||
static void
|
||||
write_uid( IOBUF out, const char *s, PKT_user_id **upkt )
|
||||
write_uid( KBNODE root, const char *s )
|
||||
{
|
||||
PACKET pkt;
|
||||
PACKET *pkt = m_alloc_clear(sizeof *pkt );
|
||||
size_t n = strlen(s);
|
||||
int rc;
|
||||
|
||||
pkt.pkttype = PKT_USER_ID;
|
||||
pkt.pkt.user_id = m_alloc( sizeof *pkt.pkt.user_id + n - 1 );
|
||||
pkt.pkt.user_id->len = n;
|
||||
strcpy(pkt.pkt.user_id->name, s);
|
||||
if( (rc = build_packet( out, &pkt )) )
|
||||
log_error("build_packet(user_id) failed: %s\n", g10_errstr(rc) );
|
||||
if( upkt ) {
|
||||
*upkt = pkt.pkt.user_id;
|
||||
pkt.pkt.user_id = NULL;
|
||||
}
|
||||
free_packet( &pkt );
|
||||
pkt->pkttype = PKT_USER_ID;
|
||||
pkt->pkt.user_id = m_alloc( sizeof *pkt->pkt.user_id + n - 1 );
|
||||
pkt->pkt.user_id->len = n;
|
||||
strcpy(pkt->pkt.user_id->name, s);
|
||||
add_kbnode( root, new_kbnode( pkt ) );
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
write_selfsig( IOBUF out, PKT_public_cert *pkc, PKT_user_id *uid,
|
||||
PKT_secret_cert *skc )
|
||||
write_selfsig( KBNODE root, KBNODE pub_root, PKT_secret_cert *skc )
|
||||
{
|
||||
PACKET pkt;
|
||||
PACKET *pkt;
|
||||
PKT_signature *sig;
|
||||
PKT_user_id *uid;
|
||||
int rc=0;
|
||||
KBNODE kbctx, node;
|
||||
PKT_public_cert *pkc;
|
||||
|
||||
if( opt.verbose )
|
||||
log_info("writing self signature\n");
|
||||
|
||||
/* get the uid packet from the tree */
|
||||
for( kbctx=NULL; (node=walk_kbtree( root, &kbctx)) ; ) {
|
||||
if( node->pkt->pkttype == PKT_USER_ID )
|
||||
break;
|
||||
}
|
||||
if( !node )
|
||||
log_bug(NULL); /* no user id packet in tree */
|
||||
uid = node->pkt->pkt.user_id;
|
||||
/* get the pkc packet from the pub_tree */
|
||||
for( kbctx=NULL; (node=walk_kbtree( pub_root, &kbctx)) ; ) {
|
||||
if( node->pkt->pkttype == PKT_PUBLIC_CERT )
|
||||
break;
|
||||
}
|
||||
if( !node )
|
||||
log_bug(NULL);
|
||||
pkc = node->pkt->pkt.public_cert;
|
||||
|
||||
/* and make the signature */
|
||||
rc = make_keysig_packet( &sig, pkc, uid, skc, 0x13, DIGEST_ALGO_RMD160 );
|
||||
if( rc ) {
|
||||
log_error("make_keysig_packet failed: %s\n", g10_errstr(rc) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
pkt.pkttype = PKT_SIGNATURE;
|
||||
pkt.pkt.signature = sig;
|
||||
if( (rc = build_packet( out, &pkt )) )
|
||||
log_error("build_packet(signature) failed: %s\n", g10_errstr(rc) );
|
||||
free_packet( &pkt );
|
||||
pkt = m_alloc_clear( sizeof *pkt );
|
||||
pkt->pkttype = PKT_SIGNATURE;
|
||||
pkt->pkt.signature = sig;
|
||||
add_kbnode( root, new_kbnode( pkt ) );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
PKT_secret_cert **ret_skc )
|
||||
{
|
||||
int rc;
|
||||
PACKET *pkt;
|
||||
PKT_secret_cert *skc;
|
||||
PKT_public_cert *pkc;
|
||||
ELG_public_key pk;
|
||||
ELG_secret_key sk;
|
||||
unsigned nbytes;
|
||||
|
||||
elg_generate( &pk, &sk, nbits );
|
||||
|
||||
skc = m_alloc( sizeof *skc );
|
||||
pkc = m_alloc( sizeof *pkc );
|
||||
skc->timestamp = pkc->timestamp = make_timestamp();
|
||||
skc->valid_days = pkc->valid_days = 0; /* fixme: make it configurable*/
|
||||
skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_ELGAMAL;
|
||||
memset(&pkc->mfx, 0, sizeof pkc->mfx);
|
||||
pkc->d.elg.p = pk.p;
|
||||
pkc->d.elg.g = pk.g;
|
||||
pkc->d.elg.y = pk.y;
|
||||
skc->d.elg.p = sk.p;
|
||||
skc->d.elg.g = sk.g;
|
||||
skc->d.elg.y = sk.y;
|
||||
skc->d.elg.x = sk.x;
|
||||
|
||||
skc->d.elg.csum = checksum_mpi( skc->d.elg.x );
|
||||
/* return an unprotected version of the skc */
|
||||
*ret_skc = copy_secret_cert( NULL, skc );
|
||||
|
||||
if( !dek ) {
|
||||
skc->d.elg.is_protected = 0;
|
||||
skc->d.elg.protect_algo = 0;
|
||||
}
|
||||
else {
|
||||
skc->d.elg.is_protected = 0;
|
||||
skc->d.elg.protect_algo = CIPHER_ALGO_BLOWFISH;
|
||||
randomize_buffer(skc->d.elg.protect.blowfish.iv, 8, 1);
|
||||
rc = protect_secret_key( skc, dek );
|
||||
if( rc ) {
|
||||
log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
|
||||
free_public_cert(pkc);
|
||||
free_secret_cert(skc);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
pkt = m_alloc_clear(sizeof *pkt);
|
||||
pkt->pkttype = PKT_PUBLIC_CERT;
|
||||
pkt->pkt.public_cert = pkc;
|
||||
add_kbnode(pub_root, new_kbnode( pkt ));
|
||||
|
||||
pkt = m_alloc_clear(sizeof *pkt);
|
||||
pkt->pkttype = PKT_SECRET_CERT;
|
||||
pkt->pkt.secret_cert = skc;
|
||||
add_kbnode(sec_root, new_kbnode( pkt ));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
static int
|
||||
gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
|
||||
@ -210,79 +287,12 @@ gen_rsa(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
|
||||
}
|
||||
#endif /*HAVE_RSA_CIPHER*/
|
||||
|
||||
|
||||
static int
|
||||
gen_elg(unsigned nbits, IOBUF pub_io, IOBUF sec_io, DEK *dek,
|
||||
PKT_public_cert **ret_pkc, PKT_secret_cert **ret_skc )
|
||||
gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
||||
PKT_secret_cert **ret_skc )
|
||||
{
|
||||
int rc;
|
||||
PACKET pkt1, pkt2;
|
||||
PKT_secret_cert *skc, *unprotected_skc;
|
||||
PKT_public_cert *pkc;
|
||||
ELG_public_key pk;
|
||||
ELG_secret_key sk;
|
||||
unsigned nbytes;
|
||||
|
||||
init_packet(&pkt1);
|
||||
init_packet(&pkt2);
|
||||
|
||||
elg_generate( &pk, &sk, nbits );
|
||||
|
||||
skc = m_alloc( sizeof *skc );
|
||||
pkc = m_alloc( sizeof *pkc );
|
||||
skc->timestamp = pkc->timestamp = make_timestamp();
|
||||
skc->valid_days = pkc->valid_days = 0; /* fixme: make it configurable*/
|
||||
skc->pubkey_algo = pkc->pubkey_algo = PUBKEY_ALGO_ELGAMAL;
|
||||
memset(&pkc->mfx, 0, sizeof pkc->mfx);
|
||||
pkc->d.elg.p = pk.p;
|
||||
pkc->d.elg.g = pk.g;
|
||||
pkc->d.elg.y = pk.y;
|
||||
skc->d.elg.p = sk.p;
|
||||
skc->d.elg.g = sk.g;
|
||||
skc->d.elg.y = sk.y;
|
||||
skc->d.elg.x = sk.x;
|
||||
|
||||
skc->d.elg.csum = checksum_mpi( skc->d.elg.x );
|
||||
unprotected_skc = copy_secret_cert( NULL, skc );
|
||||
if( !dek ) {
|
||||
skc->d.elg.is_protected = 0;
|
||||
skc->d.elg.protect_algo = 0;
|
||||
}
|
||||
else {
|
||||
skc->d.elg.is_protected = 0;
|
||||
skc->d.elg.protect_algo = CIPHER_ALGO_BLOWFISH;
|
||||
randomize_buffer(skc->d.elg.protect.blowfish.iv, 8, 1);
|
||||
rc = protect_secret_key( skc, dek );
|
||||
if( rc ) {
|
||||
log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
pkt1.pkttype = PKT_PUBLIC_CERT;
|
||||
pkt1.pkt.public_cert = pkc;
|
||||
pkt2.pkttype = PKT_SECRET_CERT;
|
||||
pkt2.pkt.secret_cert = skc;
|
||||
|
||||
if( (rc = build_packet( pub_io, &pkt1 )) ) {
|
||||
log_error("build public_cert packet failed: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
if( (rc = build_packet( sec_io, &pkt2 )) ) {
|
||||
log_error("build secret_cert packet failed: %s\n", g10_errstr(rc) );
|
||||
goto leave;
|
||||
}
|
||||
*ret_pkc = pkt1.pkt.public_cert;
|
||||
pkt1.pkt.public_cert = NULL;
|
||||
*ret_skc = unprotected_skc;
|
||||
unprotected_skc = NULL;
|
||||
|
||||
|
||||
leave:
|
||||
free_packet(&pkt1);
|
||||
free_packet(&pkt2);
|
||||
if( unprotected_skc )
|
||||
free_secret_cert( unprotected_skc );
|
||||
return rc;
|
||||
return G10ERR_GENERAL;
|
||||
}
|
||||
|
||||
|
||||
@ -295,14 +305,14 @@ generate_keypair()
|
||||
{
|
||||
char *answer;
|
||||
unsigned nbits;
|
||||
char *pub_fname = "./pubring.g10";
|
||||
char *sec_fname = "./secring.g10";
|
||||
char *pub_fname = NULL;
|
||||
char *sec_fname = NULL;
|
||||
char *uid = NULL;
|
||||
IOBUF pub_io = NULL;
|
||||
IOBUF sec_io = NULL;
|
||||
PKT_public_cert *pkc = NULL;
|
||||
KBNODE pub_root = NULL;
|
||||
KBNODE sec_root = NULL;
|
||||
PKT_secret_cert *skc = NULL;
|
||||
PKT_user_id *upkt = NULL;
|
||||
DEK *dek = NULL;
|
||||
int rc;
|
||||
int algo;
|
||||
@ -315,8 +325,9 @@ generate_keypair()
|
||||
tty_printf("Please select the algorithm to use:\n"
|
||||
" (1) ElGamal is the suggested one.\n"
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
" (2) RSA cannot be used inthe U.S.\n"
|
||||
" (2) RSA cannot be used in the U.S.\n"
|
||||
#endif
|
||||
" (3) DSA can only be used for signatures.\n"
|
||||
);
|
||||
#endif
|
||||
|
||||
@ -324,7 +335,11 @@ generate_keypair()
|
||||
#ifdef TEST_ALGO
|
||||
algo = TEST_ALGO;
|
||||
#else
|
||||
answer = tty_get("Your selection? (1,2) ");
|
||||
answer = tty_get("Your selection? (1"
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
",2"
|
||||
#endif
|
||||
",3) ");
|
||||
tty_kill_prompt();
|
||||
algo = *answer? atoi(answer): 1;
|
||||
m_free(answer);
|
||||
@ -341,6 +356,11 @@ generate_keypair()
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
else if( algo == 3 ) {
|
||||
algo = PUBKEY_ALGO_DSA;
|
||||
algo_name = "DSA";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -361,7 +381,9 @@ generate_keypair()
|
||||
nbits = *answer? atoi(answer): 1024;
|
||||
m_free(answer);
|
||||
#endif
|
||||
if( nbits < 128 ) /* FIXME: change this to 768 */
|
||||
if( algo == PUBKEY_ALGO_DSA && (nbits < 512 || nbits > 1024) )
|
||||
tty_printf("DSA does only allow keysizes from 512 to 1024\n");
|
||||
else if( nbits < 128 ) /* FIXME: change this to 768 */
|
||||
tty_printf("keysize too small; please select a larger one\n");
|
||||
else if( nbits > 2048 ) {
|
||||
tty_printf("Keysizes larger than 2048 are not suggested, because "
|
||||
@ -381,7 +403,11 @@ generate_keypair()
|
||||
break;
|
||||
}
|
||||
tty_printf("Requested keysize is %u bits\n", nbits );
|
||||
if( (nbits % 32) ) {
|
||||
if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) {
|
||||
nbits = ((nbits + 63) / 64) * 64;
|
||||
tty_printf("rounded up to %u bits\n", nbits );
|
||||
}
|
||||
else if( (nbits % 32) ) {
|
||||
nbits = ((nbits + 31) / 32) * 32;
|
||||
tty_printf("rounded up to %u bits\n", nbits );
|
||||
}
|
||||
@ -435,74 +461,103 @@ generate_keypair()
|
||||
}
|
||||
|
||||
|
||||
/* now check wether we a are allowed to write the keyrings */
|
||||
if( !(rc=overwrite_filep( pub_fname )) ) {
|
||||
if( !(pub_io = iobuf_create( pub_fname )) )
|
||||
log_error("can't create %s: %s\n", pub_fname, strerror(errno) );
|
||||
else if( opt.verbose )
|
||||
log_info("writing to '%s'\n", pub_fname );
|
||||
}
|
||||
else if( rc != -1 ) {
|
||||
log_error("Oops: overwrite_filep(%s): %s\n", pub_fname, g10_errstr(rc) );
|
||||
m_free(uid);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
m_free(uid);
|
||||
return;
|
||||
}
|
||||
if( !(rc=overwrite_filep( sec_fname )) ) {
|
||||
if( !(sec_io = iobuf_create( sec_fname )) )
|
||||
log_error("can't create %s: %s\n", sec_fname, strerror(errno) );
|
||||
else if( opt.verbose )
|
||||
log_info("writing to '%s'\n", sec_fname );
|
||||
}
|
||||
else if( rc != -1 ) {
|
||||
log_error("Oops: overwrite_filep(%s): %s\n", sec_fname, g10_errstr(rc) );
|
||||
m_free(uid);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
iobuf_cancel(pub_io);
|
||||
m_free(uid);
|
||||
return;
|
||||
/* now check wether we a are allowed to write to the keyrings */
|
||||
pub_fname = make_filename("~/.g10", "pubring.g10", NULL );
|
||||
sec_fname = make_filename("~/.g10", "secring.g10", NULL );
|
||||
if( opt.verbose ) {
|
||||
tty_printf("writing public certificate to '%s'\n", pub_fname );
|
||||
tty_printf("writing secret certificate to '%s'\n", sec_fname );
|
||||
}
|
||||
|
||||
write_comment( pub_io, "#public key created by G10 pre-release " VERSION );
|
||||
write_comment( sec_io, "#secret key created by G10 pre-release " VERSION );
|
||||
/* we create the packets as a tree of kbnodes. Because the structure
|
||||
* we create is known in advance we simply generate a linked list
|
||||
* The first packet is a comment packet, followed by the userid and
|
||||
* the self signature.
|
||||
*/
|
||||
pub_root = make_comment_node("#created by G10 pre-release " VERSION );
|
||||
sec_root = make_comment_node("#created by G10 pre-release " VERSION );
|
||||
|
||||
if( algo == PUBKEY_ALGO_ELGAMAL )
|
||||
rc = gen_elg(nbits, pub_io, sec_io, dek, &pkc, &skc);
|
||||
rc = gen_elg(nbits, pub_root, sec_root, dek, &skc );
|
||||
#ifdef HAVE_RSA_CIPHER
|
||||
else if( algo == PUBKEY_ALGO_RSA )
|
||||
rc = gen_rsa(nbits, pub_io, sec_io, dek, &pkc, &skc);
|
||||
rc = gen_rsa(nbits, pub_io, sec_io, dek, &skc );
|
||||
#endif
|
||||
else if( algo == PUBKEY_ALGO_DSA )
|
||||
rc = gen_dsa(nbits, pub_root, sec_root, dek, &skc );
|
||||
else
|
||||
log_bug(NULL);
|
||||
if( !rc )
|
||||
write_uid(pub_io, uid, &upkt );
|
||||
write_uid(pub_root, uid );
|
||||
if( !rc )
|
||||
write_uid(sec_io, uid, NULL );
|
||||
write_uid(sec_root, uid );
|
||||
if( !rc )
|
||||
rc = write_selfsig(pub_io, pkc, upkt, skc );
|
||||
rc = write_selfsig(pub_root, pub_root, skc);
|
||||
if( !rc )
|
||||
rc = write_selfsig(sec_root, pub_root, skc);
|
||||
|
||||
if( rc ) {
|
||||
iobuf_cancel(pub_io);
|
||||
iobuf_cancel(sec_io);
|
||||
if( !rc ) {
|
||||
KBPOS pub_kbpos;
|
||||
KBPOS sec_kbpos;
|
||||
int rc1 = -1;
|
||||
int rc2 = -1;
|
||||
|
||||
/* we can now write the certificates */
|
||||
/* FIXME: should we check wether the user-id already exists? */
|
||||
|
||||
if( get_keyblock_handle( pub_fname, &pub_kbpos ) ) {
|
||||
if( add_keyblock_resource( pub_fname, 1 ) ) {
|
||||
log_error("can add keyblock file '%s'\n", pub_fname );
|
||||
rc = G10ERR_CREATE_FILE;
|
||||
}
|
||||
else if( get_keyblock_handle( pub_fname, &pub_kbpos ) ) {
|
||||
log_error("can get keyblock handle for '%s'\n", pub_fname );
|
||||
rc = G10ERR_CREATE_FILE;
|
||||
}
|
||||
}
|
||||
if( rc )
|
||||
;
|
||||
else if( get_keyblock_handle( sec_fname, &sec_kbpos ) ) {
|
||||
if( add_keyblock_resource( sec_fname, 1 ) ) {
|
||||
log_error("can add keyblock file '%s'\n", sec_fname );
|
||||
rc = G10ERR_CREATE_FILE;
|
||||
}
|
||||
else if( get_keyblock_handle( sec_fname, &sec_kbpos ) ) {
|
||||
log_error("can get keyblock handle for '%s'\n", sec_fname );
|
||||
rc = G10ERR_CREATE_FILE;
|
||||
}
|
||||
}
|
||||
|
||||
if( rc )
|
||||
;
|
||||
else if( (rc=rc1=lock_keyblock( &pub_kbpos )) )
|
||||
log_error("can't lock public keyring: %s\n", g10_errstr(rc) );
|
||||
else if( (rc=rc2=lock_keyblock( &sec_kbpos )) )
|
||||
log_error("can't lock secret keyring: %s\n", g10_errstr(rc) );
|
||||
else if( (rc=insert_keyblock( &pub_kbpos, pub_root )) )
|
||||
log_error("can't write public key: %s\n", g10_errstr(rc) );
|
||||
else if( (rc=insert_keyblock( &sec_kbpos, sec_root )) )
|
||||
log_error("can't write secret key: %s\n", g10_errstr(rc) );
|
||||
else {
|
||||
tty_printf("public and secret key created and signed.\n" );
|
||||
}
|
||||
|
||||
if( !rc1 )
|
||||
unlock_keyblock( &pub_kbpos );
|
||||
if( !rc2 )
|
||||
unlock_keyblock( &sec_kbpos );
|
||||
}
|
||||
|
||||
|
||||
if( rc )
|
||||
tty_printf("Key generation failed: %s\n", g10_errstr(rc) );
|
||||
}
|
||||
else {
|
||||
iobuf_close(pub_io);
|
||||
iobuf_close(sec_io);
|
||||
tty_printf("public and secret key created and signed.\n" );
|
||||
}
|
||||
if( pkc )
|
||||
free_public_cert( pkc );
|
||||
if( skc )
|
||||
free_secret_cert( skc );
|
||||
if( upkt )
|
||||
free_user_id( upkt );
|
||||
release_kbnode( pub_root );
|
||||
release_kbnode( sec_root );
|
||||
if( skc ) /* the unprotected secret certificate */
|
||||
free_secret_cert(skc);
|
||||
m_free(uid);
|
||||
m_free(dek);
|
||||
m_free(pub_fname);
|
||||
m_free(sec_fname);
|
||||
}
|
||||
|
||||
|
12
g10/keyid.c
12
g10/keyid.c
@ -33,6 +33,18 @@
|
||||
#include "keydb.h"
|
||||
|
||||
|
||||
int
|
||||
pubkey_letter( int algo )
|
||||
{
|
||||
switch( algo ) {
|
||||
case PUBKEY_ALGO_RSA: return 'R' ;
|
||||
case PUBKEY_ALGO_RSA_E: return 'r' ;
|
||||
case PUBKEY_ALGO_RSA_S: return 's' ;
|
||||
case PUBKEY_ALGO_ELGAMAL: return 'G' ;
|
||||
case PUBKEY_ALGO_DSA: return 'D' ;
|
||||
default: return '?';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "types.h"
|
||||
#include "iobuf.h"
|
||||
#include "cipher.h"
|
||||
#include "keydb.h"
|
||||
|
||||
#define DEFAULT_CIPHER_ALGO CIPHER_ALGO_BLOWFISH
|
||||
#define DEFAULT_PUBKEY_ALGO PUBKEY_ALGO_ELGAMAL
|
||||
@ -34,6 +35,7 @@ int encode_crypt( const char *filename, STRLIST remusr );
|
||||
|
||||
/*-- sign.c --*/
|
||||
int sign_file( const char *filename, int detached, STRLIST locusr );
|
||||
int sign_key( const char *username, STRLIST locusr );
|
||||
|
||||
/*-- keygen.c --*/
|
||||
void generate_keypair(void);
|
||||
@ -49,5 +51,7 @@ MPI encode_rmd160_value( byte *md, unsigned len, unsigned nbits );
|
||||
MPI encode_md5_value( byte *md, unsigned len, unsigned nbits );
|
||||
MPI encode_md_value( MD_HANDLE *md, unsigned nbits );
|
||||
|
||||
/*-- comment.c --*/
|
||||
KBNODE make_comment_node( const char *s );
|
||||
|
||||
#endif /*G10_MAIN_H*/
|
||||
|
@ -56,19 +56,6 @@ typedef struct {
|
||||
static void list_node( CTX c, KBNODE node );
|
||||
static void proc_tree( CTX c, KBNODE node );
|
||||
|
||||
static int
|
||||
pubkey_letter( int algo )
|
||||
{
|
||||
switch( algo ) {
|
||||
case PUBKEY_ALGO_RSA: return 'R' ;
|
||||
case PUBKEY_ALGO_RSA_E: return 'r' ;
|
||||
case PUBKEY_ALGO_RSA_S: return 's' ;
|
||||
case PUBKEY_ALGO_ELGAMAL: return 'G' ;
|
||||
case PUBKEY_ALGO_DSA: return 'D' ;
|
||||
default: return '?';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
release_cert( CTX c )
|
||||
@ -509,7 +496,6 @@ proc_packets( IOBUF a )
|
||||
CTX c = m_alloc_clear( sizeof *c );
|
||||
PACKET *pkt = m_alloc( sizeof *pkt );
|
||||
int rc, result;
|
||||
char *ustr;
|
||||
int lvl0, lvl1;
|
||||
u32 keyid[2];
|
||||
int newpkt;
|
||||
|
@ -34,7 +34,7 @@ struct {
|
||||
int cache_all;
|
||||
int fingerprint; /* list fingerprints */
|
||||
int list_sigs; /* list signatures */
|
||||
int reserved4;
|
||||
int no_armor;
|
||||
int reserved5;
|
||||
int reserved6;
|
||||
int reserved7;
|
||||
|
130
g10/ringedit.c
130
g10/ringedit.c
@ -60,9 +60,10 @@ struct resource_table_struct {
|
||||
char *fname;
|
||||
IOBUF iobuf;
|
||||
};
|
||||
typedef struct resource_table_struct RESTBL;
|
||||
|
||||
#define MAX_RESOURCES 10
|
||||
static struct resource_table_struct resource_table[MAX_RESOURCES];
|
||||
static RESTBL resource_table[MAX_RESOURCES];
|
||||
|
||||
|
||||
static int keyring_search( PACKET *pkt, KBPOS *kbpos, IOBUF iobuf );
|
||||
@ -72,14 +73,14 @@ static int keyring_delete( KBPOS *kbpos );
|
||||
|
||||
|
||||
|
||||
static int
|
||||
static RESTBL *
|
||||
check_pos( KBPOS *kbpos )
|
||||
{
|
||||
if( kbpos->resno < 0 || kbpos->resno >= MAX_RESOURCES )
|
||||
return G10ERR_GENERAL;
|
||||
return NULL;
|
||||
if( !resource_table[kbpos->resno].used )
|
||||
return G10ERR_GENERAL;
|
||||
return 0;
|
||||
return NULL;
|
||||
return resource_table + kbpos->resno;
|
||||
}
|
||||
|
||||
|
||||
@ -92,7 +93,7 @@ check_pos( KBPOS *kbpos )
|
||||
* Register a resource (which currently may ionly be a keyring file).
|
||||
*/
|
||||
int
|
||||
add_keyblock_resource( const char *filename )
|
||||
add_keyblock_resource( const char *filename, int force )
|
||||
{
|
||||
IOBUF iobuf;
|
||||
int i;
|
||||
@ -104,7 +105,7 @@ add_keyblock_resource( const char *filename )
|
||||
return G10ERR_RESOURCE_LIMIT;
|
||||
|
||||
iobuf = iobuf_open( filename );
|
||||
if( !iobuf )
|
||||
if( !iobuf && !force )
|
||||
return G10ERR_OPEN_FILE;
|
||||
resource_table[i].used = 1;
|
||||
resource_table[i].fname = m_strdup(filename);
|
||||
@ -170,6 +171,31 @@ search_keyblock( PACKET *pkt, KBPOS *kbpos )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Combined function to search for a username and get the position
|
||||
* of the keyblock.
|
||||
*/
|
||||
int
|
||||
search_keyblock_byname( KBPOS *kbpos, const char *username )
|
||||
{
|
||||
PACKET pkt;
|
||||
PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc );
|
||||
int rc;
|
||||
|
||||
rc = get_pubkey_byname( pkc, username );
|
||||
if( rc ) {
|
||||
free_public_cert(pkc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
init_packet( &pkt );
|
||||
pkt.pkttype = PKT_PUBLIC_CERT;
|
||||
pkt.pkt.public_cert = pkc;
|
||||
rc = search_keyblock( &pkt, kbpos );
|
||||
free_public_cert(pkc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Lock the keyblock; wait until it's available
|
||||
@ -182,22 +208,19 @@ lock_keyblock( KBPOS *kbpos )
|
||||
{
|
||||
int rc;
|
||||
|
||||
if( (rc=check_pos(kbpos)) )
|
||||
return rc;
|
||||
if( !check_pos(kbpos) )
|
||||
return G10ERR_GENERAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Release a lock on a keyblock
|
||||
*/
|
||||
int
|
||||
void
|
||||
unlock_keyblock( KBPOS *kbpos )
|
||||
{
|
||||
int rc;
|
||||
|
||||
if( (rc=check_pos(kbpos)) )
|
||||
return rc;
|
||||
return 0;
|
||||
if( !check_pos(kbpos) )
|
||||
log_bug(NULL);
|
||||
}
|
||||
|
||||
/****************
|
||||
@ -206,10 +229,8 @@ unlock_keyblock( KBPOS *kbpos )
|
||||
int
|
||||
read_keyblock( KBPOS *kbpos, KBNODE *ret_root )
|
||||
{
|
||||
int rc;
|
||||
|
||||
if( (rc=check_pos(kbpos)) )
|
||||
return rc;
|
||||
if( !check_pos(kbpos) )
|
||||
return G10ERR_GENERAL;
|
||||
return keyring_read( kbpos, ret_root );
|
||||
}
|
||||
|
||||
@ -222,8 +243,8 @@ insert_keyblock( KBPOS *kbpos, KBNODE root )
|
||||
{
|
||||
int rc;
|
||||
|
||||
if( (rc=check_pos(kbpos)) )
|
||||
return rc;
|
||||
if( !check_pos(kbpos) )
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
rc = keyring_insert( kbpos, root );
|
||||
|
||||
@ -241,8 +262,8 @@ delete_keyblock( KBPOS *kbpos )
|
||||
{
|
||||
int rc;
|
||||
|
||||
if( (rc=check_pos(kbpos)) )
|
||||
return rc;
|
||||
if( !check_pos(kbpos) )
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
rc = keyring_delete( kbpos );
|
||||
|
||||
@ -358,13 +379,26 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
{
|
||||
PACKET *pkt;
|
||||
int rc;
|
||||
RESTBL *rentry;
|
||||
KBNODE root = NULL;
|
||||
KBNODE node, n1, n2;
|
||||
IOBUF a;
|
||||
|
||||
if( (rc=check_pos(kbpos)) )
|
||||
return rc;
|
||||
a = resource_table[kbpos->resno].iobuf;
|
||||
if( !(rentry=check_pos(kbpos)) )
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
a = iobuf_open( rentry->fname );
|
||||
if( !a ) {
|
||||
log_error("can't open '%s'\n", rentry->fname );
|
||||
return G10ERR_OPEN_FILE;
|
||||
}
|
||||
|
||||
if( iobuf_seek( a, kbpos->offset ) ) {
|
||||
log_error("can't seek to %lu: %s\n", kbpos->offset, g10_errstr(rc));
|
||||
iobuf_close(a);
|
||||
return G10ERR_KEYRING_OPEN;
|
||||
}
|
||||
|
||||
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
@ -377,7 +411,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
case PKT_PUBLIC_CERT:
|
||||
case PKT_SECRET_CERT:
|
||||
if( root )
|
||||
break;
|
||||
goto ready;
|
||||
root = new_kbnode( pkt );
|
||||
pkt = m_alloc( sizeof *pkt );
|
||||
init_packet(pkt);
|
||||
@ -386,8 +420,8 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
case PKT_USER_ID:
|
||||
if( !root ) {
|
||||
log_error("read_keyblock: orphaned user id\n" );
|
||||
rc = G10ERR_INV_KEYRING; /* or wron kbpos */
|
||||
break;
|
||||
rc = G10ERR_INV_KEYRING; /* or wrong kbpos */
|
||||
goto ready;
|
||||
}
|
||||
/* append the user id */
|
||||
node = new_kbnode( pkt );
|
||||
@ -434,6 +468,7 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
break;
|
||||
}
|
||||
}
|
||||
ready:
|
||||
kbpos->last_block = rc == -1; /* flag, that this is the last block */
|
||||
if( rc == -1 && root )
|
||||
rc = 0;
|
||||
@ -446,14 +481,49 @@ keyring_read( KBPOS *kbpos, KBNODE *ret_root )
|
||||
}
|
||||
free_packet( pkt );
|
||||
m_free( pkt );
|
||||
iobuf_close(a);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Insert the keyblock described by ROOT into the keyring described
|
||||
* by KBPOS. This actually appends the data to the keyfile.
|
||||
*/
|
||||
static int
|
||||
keyring_insert( KBPOS *kbpos, KBNODE root )
|
||||
{
|
||||
return -1;
|
||||
RESTBL *rentry;
|
||||
IOBUF fp;
|
||||
KBNODE kbctx, node;
|
||||
int rc;
|
||||
|
||||
if( !(rentry = check_pos( kbpos )) )
|
||||
return G10ERR_GENERAL;
|
||||
|
||||
/* FIXME: we must close the file if it's already open, due to
|
||||
* 2 reasons:
|
||||
* - cannot open the same file twice on DOSish OSes
|
||||
* - must sync with iobufs somehow
|
||||
*/
|
||||
/* open the file for append */
|
||||
fp = iobuf_append( rentry->fname );
|
||||
if( !fp ) {
|
||||
log_error("can't append to '%s'\n", rentry->fname );
|
||||
return G10ERR_OPEN_FILE;
|
||||
}
|
||||
|
||||
kbctx=NULL;
|
||||
while( (node = walk_kbtree( root, &kbctx )) ) {
|
||||
if( (rc = build_packet( fp, node->pkt )) ) {
|
||||
log_error("build_packet(%d) failed: %s\n",
|
||||
node->pkt->pkttype, g10_errstr(rc) );
|
||||
return G10ERR_WRITE_FILE;
|
||||
}
|
||||
}
|
||||
iobuf_close(fp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -49,7 +49,7 @@ make_session_key( DEK *dek )
|
||||
|
||||
/****************
|
||||
* Encode the session key. NBITS is the number of bits which should be used
|
||||
* for packing teh session key.
|
||||
* for packing the session key.
|
||||
* returns: A mpi with the session key (caller must free)
|
||||
*/
|
||||
MPI
|
||||
|
@ -64,6 +64,7 @@ IOBUF iobuf_alloc(int usage, size_t bufsize);
|
||||
IOBUF iobuf_temp(void);
|
||||
IOBUF iobuf_open( const char *fname );
|
||||
IOBUF iobuf_create( const char *fname );
|
||||
IOBUF iobuf_append( const char *fname );
|
||||
int iobuf_close( IOBUF iobuf );
|
||||
int iobuf_cancel( IOBUF iobuf );
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define G10_TTYIO_H
|
||||
|
||||
void tty_printf( const char *fmt, ... );
|
||||
void tty_print_string( byte *p, size_t n );
|
||||
char *tty_get( const char *prompt );
|
||||
char *tty_get_hidden( const char *prompt );
|
||||
void tty_kill_prompt(void);
|
||||
|
@ -5,6 +5,10 @@ CFLAGS += -O2
|
||||
|
||||
SUFFIXES = .S .s
|
||||
|
||||
SUBDIRS = generic i386
|
||||
EXTRA_DIST = config.links
|
||||
|
||||
|
||||
noinst_LIBRARIES = mpi
|
||||
noinst_HEADERS = sysdep.h
|
||||
|
||||
|
110
mpi/Makefile.in
110
mpi/Makefile.in
@ -42,6 +42,9 @@ INCLUDES = -I$(top_srcdir)/include
|
||||
|
||||
SUFFIXES = .S .s
|
||||
|
||||
SUBDIRS = generic i386
|
||||
EXTRA_DIST = config.links
|
||||
|
||||
noinst_LIBRARIES = mpi
|
||||
noinst_HEADERS = sysdep.h
|
||||
|
||||
@ -158,13 +161,45 @@ libmpi.a: $(mpi_OBJECTS) $(mpi_LIBADD)
|
||||
$(AR) cru libmpi.a $(mpi_OBJECTS) $(mpi_LIBADD)
|
||||
$(RANLIB) libmpi.a
|
||||
|
||||
ID: $(HEADERS) $(SOURCES)
|
||||
here=`pwd` && cd $(srcdir) && mkid -f$$here/ID $(SOURCES) $(HEADERS)
|
||||
# This directory's subdirectories are mostly independent; you can cd
|
||||
# into them and run `make' without going through this Makefile.
|
||||
# To change the values of `make' variables: instead of editing Makefiles,
|
||||
# (1) if the variable is set in `config.status', edit `config.status'
|
||||
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||
# (2) otherwise, pass the desired values on the `make' command line.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
all-recursive install-data-recursive install-exec-recursive \
|
||||
installdirs-recursive install-recursive uninstall-recursive \
|
||||
check-recursive installcheck-recursive info-recursive dvi-recursive \
|
||||
mostlyclean-recursive clean-recursive distclean-recursive \
|
||||
maintainer-clean-recursive:
|
||||
for subdir in $(SUBDIRS); do \
|
||||
target=`echo $@ | sed s/-recursive//`; \
|
||||
echo making $$target in $$subdir; \
|
||||
(cd $$subdir && $(MAKE) $$target) \
|
||||
|| case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \
|
||||
done && test -z "$$fail"
|
||||
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES)
|
||||
here=`pwd` && cd $(srcdir) && etags $(ETAGS_ARGS) $(SOURCES) $(HEADERS) -o $$here/TAGS
|
||||
tags-recursive:
|
||||
list="$(SUBDIRS)"; for subdir in $$list; do \
|
||||
(cd $$subdir && $(MAKE) tags); \
|
||||
done
|
||||
|
||||
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(CONFIG_HEADER) \
|
||||
$(TAGS_DEPENDENCIES)
|
||||
tags=; \
|
||||
here=`pwd`; \
|
||||
for subdir in $(SUBDIRS); do \
|
||||
test -f $$subdir/TAGS && { \
|
||||
tags="$$tags -i $$here/$$subdir/TAGS"; \
|
||||
}; \
|
||||
done; \
|
||||
test -z "$(ETAGS_ARGS)$(CONFIG_HEADER)$(SOURCES)$(HEADERS)$$tags" \
|
||||
|| etags $(ETAGS_ARGS) $$tags $(CONFIG_HEADER) $(SOURCES) $(HEADERS)
|
||||
|
||||
mostlyclean-tags:
|
||||
|
||||
@ -183,6 +218,14 @@ distdir: $(DEP_DISTFILES)
|
||||
|| ln $(srcdir)/$$file $(distdir)/$$file 2> /dev/null \
|
||||
|| cp -p $(srcdir)/$$file $(distdir)/$$file; \
|
||||
done
|
||||
for subdir in $(SUBDIRS); do \
|
||||
test -d $(distdir)/$$subdir \
|
||||
|| mkdir $(distdir)/$$subdir \
|
||||
|| exit 1; \
|
||||
chmod 777 $(distdir)/$$subdir; \
|
||||
(cd $$subdir && $(MAKE) distdir=../$(distdir)/$$subdir distdir) \
|
||||
|| exit 1; \
|
||||
done
|
||||
|
||||
# This fragment is probably only useful for maintainers. It relies on
|
||||
# GNU make and gcc. It is only included in the generated Makefile.in
|
||||
@ -210,28 +253,30 @@ $(srcdir)/.deps/%.P: $(srcdir)/%.c
|
||||
fi
|
||||
|
||||
# End of maintainer-only section
|
||||
info:
|
||||
info: info-recursive
|
||||
|
||||
dvi:
|
||||
dvi: dvi-recursive
|
||||
|
||||
check: all
|
||||
check: all check-recursive
|
||||
|
||||
installcheck:
|
||||
installcheck: installcheck-recursive
|
||||
|
||||
install-exec:
|
||||
all-am: $(LIBFILES) $(HEADERS) Makefile
|
||||
|
||||
install-data:
|
||||
install-exec: install-exec-recursive
|
||||
|
||||
install: install-exec install-data all
|
||||
install-data: install-data-recursive
|
||||
|
||||
install: install-recursive
|
||||
@:
|
||||
|
||||
uninstall:
|
||||
uninstall: uninstall-recursive
|
||||
|
||||
all: $(LIBFILES) $(HEADERS) Makefile
|
||||
all: all-recursive all-am
|
||||
|
||||
install-strip:
|
||||
$(MAKE) INSTALL_PROGRAM='$(INSTALL_PROGRAM) -s' install
|
||||
installdirs:
|
||||
installdirs: installdirs-recursive
|
||||
|
||||
|
||||
mostlyclean-generic:
|
||||
@ -247,29 +292,42 @@ distclean-generic:
|
||||
maintainer-clean-generic:
|
||||
test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
|
||||
test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
|
||||
mostlyclean: mostlyclean-noinstLIBRARIES mostlyclean-compile \
|
||||
mostlyclean-am: mostlyclean-noinstLIBRARIES mostlyclean-compile \
|
||||
mostlyclean-tags mostlyclean-generic
|
||||
|
||||
clean: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
|
||||
mostlyclean
|
||||
clean-am: clean-noinstLIBRARIES clean-compile clean-tags clean-generic \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-noinstLIBRARIES distclean-compile distclean-tags \
|
||||
distclean-generic clean
|
||||
distclean-am: distclean-noinstLIBRARIES distclean-compile \
|
||||
distclean-tags distclean-generic clean-am
|
||||
|
||||
maintainer-clean-am: maintainer-clean-noinstLIBRARIES \
|
||||
maintainer-clean-compile maintainer-clean-tags \
|
||||
maintainer-clean-generic distclean-am
|
||||
|
||||
mostlyclean: mostlyclean-am mostlyclean-recursive
|
||||
|
||||
clean: clean-am clean-recursive
|
||||
|
||||
distclean: distclean-am distclean-recursive
|
||||
rm -f config.status
|
||||
|
||||
maintainer-clean: maintainer-clean-noinstLIBRARIES \
|
||||
maintainer-clean-compile maintainer-clean-tags \
|
||||
maintainer-clean-generic distclean
|
||||
maintainer-clean: maintainer-clean-am maintainer-clean-recursive
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
|
||||
.PHONY: default mostlyclean-noinstLIBRARIES distclean-noinstLIBRARIES \
|
||||
clean-noinstLIBRARIES maintainer-clean-noinstLIBRARIES \
|
||||
mostlyclean-compile distclean-compile clean-compile \
|
||||
maintainer-clean-compile tags mostlyclean-tags distclean-tags \
|
||||
clean-tags maintainer-clean-tags distdir info dvi check installcheck \
|
||||
install-exec install-data install uninstall all installdirs \
|
||||
mostlyclean-generic distclean-generic clean-generic \
|
||||
maintainer-clean-compile install-data-recursive \
|
||||
uninstall-data-recursive install-exec-recursive \
|
||||
uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \
|
||||
all-recursive check-recursive installcheck-recursive info-recursive \
|
||||
dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \
|
||||
maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
|
||||
distclean-tags clean-tags maintainer-clean-tags distdir info dvi check \
|
||||
installcheck all-am install-exec install-data install uninstall all \
|
||||
installdirs mostlyclean-generic distclean-generic clean-generic \
|
||||
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
|
||||
|
||||
CFLAGS += -O2
|
||||
|
51
mpi/config.links
Normal file
51
mpi/config.links
Normal file
@ -0,0 +1,51 @@
|
||||
# sourced my ../configure to get the list of files to link
|
||||
# this should set $mpi_ln_src and mpi_ln_dst.
|
||||
# Note: this is called from the above directory.
|
||||
|
||||
echo '# created by config.links - do not edit' >./mpi/asm-syntax.h
|
||||
|
||||
case "${target}" in
|
||||
i[3456]86*-*-*)
|
||||
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
|
||||
echo '#include "./i386/syntax.h"' >>./mpi/asm-syntax.h
|
||||
path="i386"
|
||||
;;
|
||||
i[56]86*-*-* | pentium-*-* | pentiumpro-*-*)
|
||||
echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
|
||||
echo '#include "./i586/syntax.h"' >>./mpi/asm-syntax.h
|
||||
path="i586"
|
||||
;;
|
||||
*)
|
||||
echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
|
||||
path=""
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# fixme: grep these modules from Makefile.in
|
||||
mpi_ln_modules="mpih-add1 mpih-mul1 mpih-mul2 mpih-mul3 \
|
||||
mpih-shift mpih-sub1"
|
||||
|
||||
mpi_ln_objects=
|
||||
mpi_ln_src=
|
||||
mpi_ln_dst=
|
||||
|
||||
# try to get file to link from the assembler subdirectory and
|
||||
# if this fails get it from the generic subdirectory.
|
||||
path="$path generic"
|
||||
for fn in $mpi_ln_modules ; do
|
||||
mpi_ln_objects="$mpi_ln_objects $fn.o"
|
||||
for dir in $path ; do
|
||||
rm -f ./mpi/$fn.[Sc]
|
||||
if test -f ./mpi/$dir/$fn.S ; then
|
||||
mpi_ln_src="$mpi_ln_src mpi/$dir/$fn.S"
|
||||
mpi_ln_dst="$mpi_ln_dst mpi/$fn.S"
|
||||
break;
|
||||
elif test -f ./mpi/$dir/$fn.c ; then
|
||||
mpi_ln_src="$mpi_ln_src mpi/$dir/$fn.c"
|
||||
mpi_ln_dst="$mpi_ln_dst mpi/$fn.c"
|
||||
break;
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
@ -194,6 +194,7 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
|
||||
char keyword[100];
|
||||
char *buffer = NULL;
|
||||
size_t buflen = 0;
|
||||
int inverse=0;
|
||||
|
||||
if( !fp ) /* same as arg_parse() in this case */
|
||||
return arg_parse( arg, opts );
|
||||
@ -216,6 +217,8 @@ optfile_parse( FILE *fp, const char *filename, unsigned *lineno,
|
||||
break;
|
||||
index = i;
|
||||
arg->r_opt = opts[index].short_opt;
|
||||
if( inverse )
|
||||
arg->r_opt = -arg->r_opt;
|
||||
if( !opts[index].short_opt )
|
||||
arg->r_opt = -2; /* unknown option */
|
||||
else if( (opts[index].flags & 8) ) /* no optional argument */
|
||||
|
49
util/iobuf.c
49
util/iobuf.c
@ -370,6 +370,36 @@ iobuf_create( const char *fname )
|
||||
return a;
|
||||
}
|
||||
|
||||
/****************
|
||||
* append to a iobuf if the file does not exits; create it.
|
||||
* cannont be used for stdout.
|
||||
*/
|
||||
IOBUF
|
||||
iobuf_append( const char *fname )
|
||||
{
|
||||
IOBUF a;
|
||||
FILE *fp;
|
||||
file_filter_ctx_t *fcx;
|
||||
size_t len;
|
||||
|
||||
if( !fname )
|
||||
return NULL;
|
||||
else if( !(fp = fopen(fname, "ab")) )
|
||||
return NULL;
|
||||
a = iobuf_alloc(2, 8192 );
|
||||
fcx = m_alloc( sizeof *fcx + strlen(fname) );
|
||||
fcx->fp = fp;
|
||||
strcpy(fcx->fname, fname );
|
||||
a->filter = file_filter;
|
||||
a->filter_ov = fcx;
|
||||
file_filter( fcx, IOBUFCTRL_DESC, NULL, (byte*)&a->desc, &len );
|
||||
file_filter( fcx, IOBUFCTRL_INIT, NULL, NULL, &len );
|
||||
if( DBG_IOBUF )
|
||||
log_debug("iobuf-%d.%d: append '%s'\n", a->no, a->subno, a->desc );
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
/****************
|
||||
* Register an i/o filter.
|
||||
*/
|
||||
@ -709,8 +739,25 @@ iobuf_tell( IOBUF a )
|
||||
int
|
||||
iobuf_seek( IOBUF a, ulong newpos )
|
||||
{
|
||||
file_filter_ctx_t *b = NULL;
|
||||
|
||||
return -1;
|
||||
for( ; a; a = a->chain ) {
|
||||
if( !a->chain && a->filter == file_filter ) {
|
||||
b = a->filter_ov;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !a )
|
||||
return -1;
|
||||
|
||||
if( fseek( b->fp, newpos, SEEK_SET ) ) {
|
||||
log_error("can't seek to %lu: %s\n", newpos, strerror(errno) );
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* FIXME: flush all buffers (and remove filters?)*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -46,7 +46,7 @@ print_string( FILE *fp, byte *p, size_t n )
|
||||
else if( !*p )
|
||||
putc('0', fp);
|
||||
else
|
||||
printf("x%02x", *p );
|
||||
fprintf(fp, "x%02x", *p );
|
||||
}
|
||||
else
|
||||
putc(*p, fp);
|
||||
|
22
util/ttyio.c
22
util/ttyio.c
@ -60,6 +60,28 @@ tty_printf( const char *fmt, ... )
|
||||
}
|
||||
|
||||
|
||||
/****************
|
||||
* Print a string, but filter all control characters out.
|
||||
*/
|
||||
void
|
||||
tty_print_string( byte *p, size_t n )
|
||||
{
|
||||
for( ; n; n--, p++ )
|
||||
if( iscntrl( *p ) ) {
|
||||
putc('\\', stderr);
|
||||
if( *p == '\n' )
|
||||
putc('n', stderr);
|
||||
else if( !*p )
|
||||
putc('0', stderr);
|
||||
else
|
||||
fprintf(stderr, "x%02x", *p );
|
||||
}
|
||||
else
|
||||
putc(*p, stderr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
char *
|
||||
tty_get( const char *prompt )
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user