diff options
Diffstat (limited to '')
-rw-r--r-- | kbx/kbxutil.c | 371 |
1 files changed, 300 insertions, 71 deletions
diff --git a/kbx/kbxutil.c b/kbx/kbxutil.c index abca4faa9..19d356007 100644 --- a/kbx/kbxutil.c +++ b/kbx/kbxutil.c @@ -1,5 +1,5 @@ /* kbxutil.c - The Keybox utility - * Copyright (C) 2000, 2001 Free Software Foundation, Inc. + * Copyright (C) 2000, 2001, 2004 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -15,7 +15,8 @@ * * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. */ #include <config.h> @@ -24,11 +25,15 @@ #include <stdlib.h> #include <string.h> #include <ctype.h> +#include <sys/stat.h> #include <unistd.h> +#include <assert.h> +#define JNLIB_NEED_LOG_LOGV #include "../jnlib/logging.h" #include "../jnlib/argparse.h" #include "../jnlib/stringhelp.h" +#include "../jnlib/utf8conv.h" #include "../common/i18n.h" #include "keybox-defs.h" @@ -47,6 +52,8 @@ enum cmd_and_opt_values { aFindByFpr, aFindByKid, aFindByUid, + aStats, + aImportOpenPGP, oDebug, oDebugAll, @@ -61,15 +68,17 @@ enum cmd_and_opt_values { static ARGPARSE_OPTS opts[] = { { 300, NULL, 0, N_("@Commands:\n ") }, - { aFindByFpr, "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" }, - { aFindByKid, "find-by-kid", 0, "|KID| find key using it's keyid" }, - { aFindByUid, "find-by-uid", 0, "|NAME| find key by user name" }, +/* { aFindByFpr, "find-by-fpr", 0, "|FPR| find key using it's fingerprnt" }, */ +/* { aFindByKid, "find-by-kid", 0, "|KID| find key using it's keyid" }, */ +/* { aFindByUid, "find-by-uid", 0, "|NAME| find key by user name" }, */ + { aStats, "stats", 0, "show key statistics" }, + { aImportOpenPGP, "import-openpgp", 0, "import OpenPGP keyblocks"}, { 301, NULL, 0, N_("@\nOptions:\n ") }, - { oArmor, "armor", 0, N_("create ascii armored output")}, - { oArmor, "armour", 0, "@" }, - { oOutput, "output", 2, N_("use as output file")}, +/* { oArmor, "armor", 0, N_("create ascii armored output")}, */ +/* { oArmor, "armour", 0, "@" }, */ +/* { oOutput, "output", 2, N_("use as output file")}, */ { oVerbose, "verbose", 0, N_("verbose") }, { oQuiet, "quiet", 0, N_("be somewhat more quiet") }, { oDryRun, "dry-run", 0, N_("do not make any changes") }, @@ -117,22 +126,37 @@ my_strusage( int level ) static void i18n_init(void) { - #ifdef USE_SIMPLE_GETTEXT - set_gettext_file( PACKAGE ); - #else - #ifdef ENABLE_NLS - #ifdef HAVE_LC_MESSAGES - setlocale( LC_TIME, "" ); - setlocale( LC_MESSAGES, "" ); - #else - setlocale( LC_ALL, "" ); - #endif - bindtextdomain( PACKAGE, LOCALEDIR ); - textdomain( PACKAGE ); - #endif - #endif +#ifdef USE_SIMPLE_GETTEXT + set_gettext_file( PACKAGE_GT ); +#else +#ifdef ENABLE_NLS + setlocale( LC_ALL, "" ); + bindtextdomain( PACKAGE_GT, LOCALEDIR ); + textdomain( PACKAGE_GT ); +#endif +#endif } +/* Used by gcry for logging */ +static void +my_gcry_logger (void *dummy, int level, const char *fmt, va_list arg_ptr) +{ + /* Map the log levels. */ + switch (level) + { + case GCRY_LOG_CONT: level = JNLIB_LOG_CONT; break; + case GCRY_LOG_INFO: level = JNLIB_LOG_INFO; break; + case GCRY_LOG_WARN: level = JNLIB_LOG_WARN; break; + case GCRY_LOG_ERROR:level = JNLIB_LOG_ERROR; break; + case GCRY_LOG_FATAL:level = JNLIB_LOG_FATAL; break; + case GCRY_LOG_BUG: level = JNLIB_LOG_BUG; break; + case GCRY_LOG_DEBUG:level = JNLIB_LOG_DEBUG; break; + default: level = JNLIB_LOG_ERROR; break; + } + log_logv (level, fmt, arg_ptr); +} + + /* static void */ /* wrong_args( const char *text ) */ @@ -213,6 +237,181 @@ format_keyid ( const char *s, u32 *kid ) } #endif +static char * +read_file (const char *fname, size_t *r_length) +{ + FILE *fp; + char *buf; + size_t buflen; + + if (!strcmp (fname, "-")) + { + size_t nread, bufsize = 0; + + fp = stdin; + buf = NULL; + buflen = 0; +#define NCHUNK 8192 + do + { + bufsize += NCHUNK; + if (!buf) + buf = xtrymalloc (bufsize); + else + buf = xtryrealloc (buf, bufsize); + if (!buf) + log_fatal ("can't allocate buffer: %s\n", strerror (errno)); + + nread = fread (buf+buflen, 1, NCHUNK, fp); + if (nread < NCHUNK && ferror (fp)) + { + log_error ("error reading `[stdin]': %s\n", strerror (errno)); + xfree (buf); + return NULL; + } + buflen += nread; + } + while (nread == NCHUNK); +#undef NCHUNK + + } + else + { + struct stat st; + + fp = fopen (fname, "rb"); + if (!fp) + { + log_error ("can't open `%s': %s\n", fname, strerror (errno)); + return NULL; + } + + if (fstat (fileno(fp), &st)) + { + log_error ("can't stat `%s': %s\n", fname, strerror (errno)); + fclose (fp); + return NULL; + } + + buflen = st.st_size; + buf = xtrymalloc (buflen+1); + if (!buf) + log_fatal ("can't allocate buffer: %s\n", strerror (errno)); + if (fread (buf, buflen, 1, fp) != 1) + { + log_error ("error reading `%s': %s\n", fname, strerror (errno)); + fclose (fp); + xfree (buf); + return NULL; + } + fclose (fp); + } + + *r_length = buflen; + return buf; +} + + +static void +dump_fpr (const unsigned char *buffer, size_t len) +{ + int i; + + for (i=0; i < len; i++, buffer++) + { + if (len == 20) + { + if (i == 10) + putchar (' '); + printf (" %02X%02X", buffer[0], buffer[1]); + i++; buffer++; + } + else + { + if (i && !(i % 8)) + putchar (' '); + printf (" %02X", buffer[0]); + } + } +} + + +static void +dump_openpgp_key (keybox_openpgp_info_t info, const unsigned char *image) +{ + printf ("pub %02X%02X%02X%02X", + info->primary.keyid[4], info->primary.keyid[5], + info->primary.keyid[6], info->primary.keyid[7] ); + dump_fpr (info->primary.fpr, info->primary.fprlen); + putchar ('\n'); + if (info->nsubkeys) + { + struct _keybox_openpgp_key_info *k; + + k = &info->subkeys; + do + { + printf ("sub %02X%02X%02X%02X", + k->keyid[4], k->keyid[5], + k->keyid[6], k->keyid[7] ); + dump_fpr (k->fpr, k->fprlen); + putchar ('\n'); + k = k->next; + } + while (k); + } + if (info->nuids) + { + struct _keybox_openpgp_uid_info *u; + + u = &info->uids; + do + { + printf ("uid\t\t%.*s\n", u->len, image + u->off); + u = u->next; + } + while (u); + } +} + + +static void +import_openpgp (const char *filename) +{ + gpg_error_t err; + char *buffer; + size_t buflen, nparsed; + unsigned char *p; + struct _keybox_openpgp_info info; + + buffer = read_file (filename, &buflen); + if (!buffer) + return; + p = (unsigned char *)buffer; + for (;;) + { + err = _keybox_parse_openpgp (p, buflen, &nparsed, &info); + assert (nparsed <= buflen); + if (err) + { + if (gpg_err_code (err) == GPG_ERR_NO_DATA) + break; + log_info ("%s: failed to parse OpenPGP keyblock: %s\n", + filename, gpg_strerror (err)); + } + else + { + dump_openpgp_key (&info, p); + _keybox_destroy_openpgp_info (&info); + } + p += nparsed; + buflen -= nparsed; + } + xfree (buffer); +} + + + int main( int argc, char **argv ) @@ -221,19 +420,22 @@ main( int argc, char **argv ) enum cmd_and_opt_values cmd = 0; set_strusage( my_strusage ); - /*log_set_name("kbxutil"); fixme */ -#if 0 - /* check that the libraries are suitable. Do it here because - * the option parse may need services of the library */ - if ( !gcry_check_version ( "1.1.4" ) ) + gcry_control (GCRYCTL_DISABLE_SECMEM); + log_set_prefix ("kbxutil", 1); + set_native_charset (NULL); + i18n_init (); + + /* Check that the libraries are suitable. Do it here because + the option parsing may need services of the library. */ + if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) ) { - log_fatal(_("libgcrypt is too old (need %s, have %s)\n"), - "1.1.4", gcry_check_version(NULL) ); + log_fatal( _("libgcrypt is too old (need %s, have %s)\n"), + NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) ); } -#endif + + gcry_set_log_handler (my_gcry_logger, NULL); /*create_dotlock(NULL); register locking cleanup */ - i18n_init(); /* We need to use the gcry malloc function because jnlib does use them */ keybox_set_malloc_hooks (gcry_malloc, gcry_realloc, gcry_free); @@ -261,9 +463,11 @@ main( int argc, char **argv ) case aFindByFpr: case aFindByKid: case aFindByUid: + case aStats: + case aImportOpenPGP: cmd = pargs.r_opt; break; - + default: pargs.err = 2; break; @@ -273,52 +477,77 @@ main( int argc, char **argv ) myexit(2); if (!cmd) - { /* default is to list a KBX file */ - if (!argc) - _keybox_dump_file (NULL, stdout); - else - { - for (; argc; argc--, argv++) - _keybox_dump_file (*argv, stdout); - } + { /* Default is to list a KBX file */ + if (!argc) + _keybox_dump_file (NULL, 0, stdout); + else + { + for (; argc; argc--, argv++) + _keybox_dump_file (*argv, 0, stdout); + } + } + else if (cmd == aStats ) + { + if (!argc) + _keybox_dump_file (NULL, 1, stdout); + else + { + for (; argc; argc--, argv++) + _keybox_dump_file (*argv, 1, stdout); + } + } + else if (cmd == aImportOpenPGP) + { + if (!argc) + import_openpgp ("-"); + else + { + for (; argc; argc--, argv++) + import_openpgp (*argv); + } } #if 0 - else if ( cmd == aFindByFpr ) { - char *fpr; - if ( argc != 2 ) - wrong_args ("kbxfile foingerprint"); - fpr = format_fingerprint ( argv[1] ); - if ( !fpr ) - log_error ("invalid formatted fingerprint\n"); - else { - kbxfile_search_by_fpr ( argv[0], fpr ); - gcry_free ( fpr ); - } + else if ( cmd == aFindByFpr ) + { + char *fpr; + if ( argc != 2 ) + wrong_args ("kbxfile foingerprint"); + fpr = format_fingerprint ( argv[1] ); + if ( !fpr ) + log_error ("invalid formatted fingerprint\n"); + else + { + kbxfile_search_by_fpr ( argv[0], fpr ); + gcry_free ( fpr ); + } } - else if ( cmd == aFindByKid ) { - u32 kid[2]; - int mode; - - if ( argc != 2 ) - wrong_args ("kbxfile short-or-long-keyid"); - mode = format_keyid ( argv[1], kid ); - if ( !mode ) - log_error ("invalid formatted keyID\n"); - else { - kbxfile_search_by_kid ( argv[0], kid, mode ); + else if ( cmd == aFindByKid ) + { + u32 kid[2]; + int mode; + + if ( argc != 2 ) + wrong_args ("kbxfile short-or-long-keyid"); + mode = format_keyid ( argv[1], kid ); + if ( !mode ) + log_error ("invalid formatted keyID\n"); + else + { + kbxfile_search_by_kid ( argv[0], kid, mode ); } } - else if ( cmd == aFindByUid ) { - if ( argc != 2 ) - wrong_args ("kbxfile userID"); - kbxfile_search_by_uid ( argv[0], argv[1] ); + else if ( cmd == aFindByUid ) + { + if ( argc != 2 ) + wrong_args ("kbxfile userID"); + kbxfile_search_by_uid ( argv[0], argv[1] ); } #endif - else - log_error ("unsupported action\n"); - - myexit(0); - return 8; /*NEVER REACHED*/ + else + log_error ("unsupported action\n"); + + myexit(0); + return 8; /*NEVER REACHED*/ } |