some cleanups
[gnupg.git] / g10 / g10.c
1 /* g10.c - The GNUPG utility (main for gpg)
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of GNUPG.
5  *
6  * GNUPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GNUPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 /****************
22  * We use cpp to generate the source g10maint.c (IS_G10MAINT) from this
23  * source; the main difference is, that g10maint can only work with public
24  * keys and does not need to lock memory or run suid.
25  */
26
27 #include <config.h>
28 #include <errno.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33
34
35 #include "packet.h"
36 #include "iobuf.h"
37 #include "memory.h"
38 #include "util.h"
39 #include "main.h"
40 #include "options.h"
41 #include "keydb.h"
42 #include "mpi.h"
43 #include "cipher.h"
44 #include "filter.h"
45 #include "trustdb.h"
46 #include "ttyio.h"
47 #include "i18n.h"
48 #include "status.h"
49
50 #ifndef IS_G10MAINT
51   #define IS_G10 1
52 #endif
53
54
55 static ARGPARSE_OPTS opts[] = {
56
57     { 300, NULL, 0, N_("\vCommands:\n ") },
58
59   #ifdef IS_G10
60     { 's', "sign",      0, N_("make a signature")},
61     { 539, "clearsign", 0, N_("make a clear text signature") },
62     { 'b', "detach-sign", 0, N_("make a detached signature")},
63     { 'e', "encrypt",   0, N_("encrypt data")},
64     { 'c', "symmetric", 0, N_("encryption only with symmetric cipher")},
65     { 507, "store",     0, N_("store only")},
66     { 'd', "decrypt",   0, N_("decrypt data (default)")},
67     { 550, "verify"   , 0, N_("verify a signature")},
68   #endif
69     { 551, "list-keys", 0, N_("list keys")},
70     { 552, "list-sigs", 0, N_("list keys and signatures")},
71     { 508, "check-sigs",0, N_("check key signatures")},
72     { 515, "fingerprint", 0, N_("list keys and fingerprints")},
73   #ifdef IS_G10
74     { 503, "gen-key",   0, N_("generate a new key pair")},
75     { 506, "sign-key"  ,0, N_("make a signature on a key in the keyring")},
76     { 505, "delete-key",0, N_("remove key from the public keyring")},
77     { 524, "edit-key"  ,0, N_("edit a key signature")},
78     { 525, "change-passphrase", 0, N_("change the passphrase of your secret keyring")},
79     { 542, "gen-revoke",0, N_("generate a revocation certificate")},
80   #endif
81     { 537, "export"          , 0, N_("export keys") },
82     { 530, "import",      0     , N_("import/merge keys")},
83     { 521, "list-packets",0,N_("list only the sequence of packets")},
84   #ifdef IS_G10MAINT
85     { 546, "dearmor", 0, N_("De-Armor a file or stdin") },
86     { 547, "enarmor", 0, N_("En-Armor a file or stdin") },
87     { 516, "print-mds" , 0, N_("print all message digests")},
88     { 513, "gen-prime" , 0, "\r" },
89     { 548, "gen-random" , 0, "\r" },
90   #endif
91
92     { 301, NULL, 0, N_("\v\nOptions:\n ") },
93
94   #ifdef IS_G10
95     { 'a', "armor",     0, N_("create ascii armored output")},
96     { 'u', "local-user",2, N_("use this user-id to sign or decrypt")},
97     { 'r', "remote-user", 2, N_("use this user-id for encryption")},
98     { 'z', NULL,        1, N_("set compress level (0 disables)") },
99     { 't', "textmode",  0, N_("use canonical text mode")},
100   #endif
101     { 'o', "output",    2, N_("use as output file")},
102     { 'v', "verbose",   0, N_("verbose") },
103     { 'n', "dry-run",   0, N_("do not make any changes") },
104     { 500, "batch",     0, N_("batch mode: never ask")},
105     { 501, "yes",       0, N_("assume yes on most questions")},
106     { 502, "no",        0, N_("assume no on most questions")},
107     { 509, "keyring"   ,2, N_("add this keyring to the list of keyrings")},
108     { 517, "secret-keyring" ,2, N_("add this secret keyring to the list")},
109     { 518, "options"   , 2, N_("read options from file")},
110
111     { 510, "debug"     ,4|16, N_("set debugging flags")},
112     { 511, "debug-all" ,0, N_("enable full debugging")},
113     { 512, "status-fd" ,1, N_("write status info to this fd") },
114     { 534, "no-comment", 0,   N_("do not write comment packets")},
115     { 535, "completes-needed", 1, N_("(default is 1)")},
116     { 536, "marginals-needed", 1, N_("(default is 3)")},
117   #ifdef IS_G10
118     { 527, "cipher-algo", 2 , N_("select default cipher algorithm")},
119     { 528, "pubkey-algo", 2 , N_("select default puplic key algorithm")},
120     { 529, "digest-algo", 2 , N_("select default message digest algorithm")},
121   #endif
122
123   #ifdef IS_G10
124     { 302, NULL, 0, N_("\v\nExamples:\n\n"
125     " -se -r Bob [file]          sign and encrypt for user Bob\n"
126     " -sat [file]                make a clear text signature\n"
127     " -sb  [file]                make a detached signature\n"
128     " -k   [userid]              show keys\n"
129     " -kc  [userid]              show fingerprint\n"  ) },
130   #endif
131
132   /* hidden options */
133   #ifdef IS_G10MAINT
134     { 514, "test"      , 0, "\r" },
135     { 531, "list-trustdb",0 , "\r"},
136     { 533, "list-trust-path",0, "\r"},
137   #endif
138   #ifdef IS_G10
139     { 'k', NULL,        0, "\r"},
140     { 504, "delete-secret-key",0, "\r" },
141     { 524, "edit-sig"  ,0, "\r"}, /* alias for edit-key */
142     { 523, "passphrase-fd",1, "\r" },
143   #endif
144     { 532, "quick-random", 0, "\r"},
145     { 526, "no-verbose", 0, "\r"},
146     { 538, "trustdb-name", 2, "\r" },
147     { 540, "no-secmem-warning", 0, "\r" }, /* used only by regression tests */
148     { 519, "no-armor",   0, "\r"},
149     { 520, "no-default-keyring", 0, "\r" },
150     { 522, "no-greeting", 0, "\r" },
151     { 541, "no-operation", 0, "\r" },      /* used by regression tests */
152     { 543, "no-options", 0, "\r" }, /* shortcut for --options /dev/null */
153     { 544, "homedir", 2, "\r" },   /* defaults to "~/.gnupg" */
154     { 545, "no-batch", 0, "\r" },
155     { 549, "with-colons", 0, "\r"},
156     { 551, "list-key", 0, "\r" }, /* alias */
157     { 552, "list-sig", 0, "\r" }, /* alias */
158     { 508, "check-sig",0, "\r" }, /* alias */
159
160
161 {0} };
162
163
164
165
166 enum cmd_values { aNull = 0,
167     aSym, aStore, aEncr, aKeygen, aSign, aSignEncr,
168     aSignKey, aClearsign, aListPackets, aEditSig, aDeleteKey, aDeleteSecretKey,
169     aKMode, aKModeC, aChangePass, aImport, aVerify, aDecrypt, aListKeys,
170     aListSigs,
171     aExport, aCheckKeys, aGenRevoke, aPrimegen, aPrintMDs,
172     aListTrustDB, aListTrustPath, aDeArmor, aEnArmor, aGenRandom, aTest,
173 aNOP };
174
175
176 static char *build_list( const char *text,
177                          const char *(*mapf)(int), int (*chkf)(int) );
178 static void set_cmd( enum cmd_values *ret_cmd,
179                         enum cmd_values new_cmd );
180 #ifdef IS_G10MAINT
181 static void print_hex( byte *p, size_t n );
182 static void print_mds( const char *fname );
183 static void do_test(int);
184 #endif
185
186 const char *
187 strusage( int level )
188 {
189   static char *digests, *pubkeys, *ciphers;
190     const char *p;
191     switch( level ) {
192       case 11: p =
193           #ifdef IS_G10MAINT
194             "gpgm (GNUPG)";
195           #else
196             "gpg (GNUPG)";
197           #endif
198         break;
199       case 13: p = VERSION; break;
200       case 17: p = PRINTABLE_OS_NAME; break;
201       case 19: p =
202             _("Please report bugs to <gnupg-bugs@isil.d.shuttle.de>.\n");
203         break;
204       case 1:
205       case 40:  p =
206           #ifdef IS_G10MAINT
207             _("Usage: gpgm [options] [files] (-h for help)");
208           #else
209             _("Usage: gpg [options] [files] (-h for help)");
210           #endif
211         break;
212       case 41:  p =
213           #ifdef IS_G10MAINT
214             _("Syntax: gpgm [options] [files]\n"
215               "GNUPG maintenance utility\n");
216           #else
217             _("Syntax: gpg [options] [files]\n"
218               "sign, check, encrypt or decrypt\n"
219               "default operation depends on the input data\n");
220           #endif
221         break;
222
223       case 31: p = "\n"; break;
224       case 32:
225         if( !ciphers )
226             ciphers = build_list("Supported ciphers: ", cipher_algo_to_string,
227                                                         check_cipher_algo );
228         p = ciphers;
229         break;
230       case 33:
231         if( !pubkeys )
232             pubkeys = build_list("Supported pubkeys: ", pubkey_algo_to_string,
233                                                         check_pubkey_algo );
234         p = pubkeys;
235         break;
236       case 34:
237         if( !digests )
238             digests = build_list("Supported digests: ", digest_algo_to_string,
239                                                         check_digest_algo );
240         p = digests;
241         break;
242
243       default:  p = default_strusage(level);
244     }
245     return p;
246 }
247
248
249 static char *
250 build_list( const char *text, const char * (*mapf)(int), int (*chkf)(int) )
251 {
252     int i;
253     const char *s;
254     size_t n=strlen(text)+2;
255     char *list, *p;
256
257     for(i=1; i < 100; i++ )
258         if( !chkf(i) && (s=mapf(i)) )
259             n += strlen(s) + 2;
260     list = m_alloc( 21 + n ); *list = 0;
261     for(p=NULL, i=1; i < 100; i++ ) {
262         if( !chkf(i) && (s=mapf(i)) ) {
263             if( !p )
264                 p = stpcpy( list, text );
265             else
266                 p = stpcpy( p, ", ");
267             p = stpcpy(p, s );
268         }
269     }
270     if( p )
271         p = stpcpy(p, "\n" );
272     return list;
273 }
274
275
276 static void
277 i18n_init(void)
278 {
279   #ifdef ENABLE_NLS
280     #ifdef HAVE_LC_MESSAGES
281        setlocale( LC_MESSAGES, "" );
282     #else
283        setlocale( LC_ALL, "" );
284     #endif
285     bindtextdomain( PACKAGE, G10_LOCALEDIR );
286     textdomain( PACKAGE );
287   #endif
288 }
289
290 static void
291 wrong_args( const char *text)
292 {
293   #ifdef IS_G10MAINT
294     fputs(_("usage: gpgm [options] "),stderr);
295   #else
296     fputs(_("usage: gpg [options] "),stderr);
297   #endif
298     fputs(text,stderr);
299     putc('\n',stderr);
300     g10_exit(2);
301 }
302
303 static void
304 set_debug(void)
305 {
306     if( opt.debug & DBG_MEMORY_VALUE )
307         memory_debug_mode = 1;
308     if( opt.debug & DBG_MEMSTAT_VALUE )
309         memory_stat_debug_mode = 1;
310     if( opt.debug & DBG_MPI_VALUE )
311         mpi_debug_mode = 1;
312     if( opt.debug & DBG_CIPHER_VALUE )
313         cipher_debug_mode = 1;
314     if( opt.debug & DBG_IOBUF_VALUE )
315         iobuf_debug_mode = 1;
316 }
317
318
319 static void
320 set_cmd( enum cmd_values *ret_cmd, enum cmd_values new_cmd )
321 {
322     enum cmd_values cmd = *ret_cmd;
323
324     if( !cmd || cmd == new_cmd )
325         cmd = new_cmd;
326     else if( cmd == aSign && new_cmd == aEncr )
327         cmd = aSignEncr;
328     else if( cmd == aEncr && new_cmd == aSign )
329         cmd = aSignEncr;
330     else if( cmd == aKMode && new_cmd == aSym )
331         cmd = aKModeC;
332     else if(    ( cmd == aSign     && new_cmd == aClearsign )
333              || ( cmd == aClearsign && new_cmd == aSign )  )
334         cmd = aClearsign;
335     else {
336         log_error(_("conflicting commands\n"));
337         g10_exit(2);
338     }
339
340     *ret_cmd = cmd;
341 }
342
343
344
345 static void
346 check_opts(void)
347 {
348     if( !opt.def_cipher_algo || check_cipher_algo(opt.def_cipher_algo) )
349         log_error(_("selected cipher algorithm is invalid\n"));
350     if( !opt.def_pubkey_algo || check_pubkey_algo(opt.def_pubkey_algo) )
351         log_error(_("selected pubkey algorithm is invalid\n"));
352     if( !opt.def_digest_algo || check_digest_algo(opt.def_digest_algo) )
353         log_error(_("selected digest algorithm is invalid\n"));
354     if( opt.completes_needed < 1 )
355         log_error(_("completes-needed must be greater than 0\n"));
356     if( opt.marginals_needed < 2 )
357         log_error(_("marginals-needed must be greater than 1\n"));
358 }
359
360
361
362
363 void
364 main( int argc, char **argv )
365 {
366     ARGPARSE_ARGS pargs;
367     IOBUF a;
368     int rc=0;
369     int orig_argc;
370     char **orig_argv;
371     const char *fname;
372     STRLIST sl, remusr= NULL, locusr=NULL;
373     int nrings=0, sec_nrings=0;
374     armor_filter_context_t afx;
375     int detached_sig = 0;
376     FILE *configfp = NULL;
377     char *configname = NULL;
378     unsigned configlineno;
379     int parse_debug = 0;
380     int default_config =1;
381     int errors=0;
382     int default_keyring = 1;
383     int greeting = 1;
384     enum cmd_values cmd = 0;
385     const char *trustdb_name = NULL;
386
387   #ifdef IS_G10MAINT
388     secmem_init( 0 );      /* disable use of secmem */
389     log_set_name("gpgm");
390   #else
391     /* Please note that we may running SUID(ROOT), so be very CAREFUL
392      * when adding any stuff between here and the call to
393      * secmem_init()  somewhere after the option parsing
394      */
395     log_set_name("gpg");
396     secure_random_alloc(); /* put random number into secure memory */
397     init_signals();
398   #endif
399     i18n_init();
400     opt.compress = -1; /* defaults to standard compress level */
401     opt.def_cipher_algo = CIPHER_ALGO_BLOWFISH;
402     opt.def_pubkey_algo = PUBKEY_ALGO_ELGAMAL;
403     opt.def_digest_algo = DIGEST_ALGO_RMD160;
404     opt.completes_needed = 1;
405     opt.marginals_needed = 3;
406     opt.homedir = getenv("GNUPGHOME");
407     if( !opt.homedir || !*opt.homedir ) {
408       #ifdef __MINGW32__
409         opt.homedir = "c:/gnupg";
410       #else
411         opt.homedir = "~/.gnupg";
412       #endif
413     }
414
415     /* check wether we have a config file on the commandline */
416     orig_argc = argc;
417     orig_argv = argv;
418     pargs.argc = &argc;
419     pargs.argv = &argv;
420     pargs.flags=  1;  /* do not remove the args */
421     while( arg_parse( &pargs, opts) ) {
422         if( pargs.r_opt == 510 || pargs.r_opt == 511 )
423             parse_debug++;
424         else if( pargs.r_opt == 518 ) {
425             /* yes there is one, so we do not try the default one, but
426              * read the option file when it is encountered at the commandline
427              */
428             default_config = 0;
429         }
430         else if( pargs.r_opt == 543 )
431             default_config = 0; /* --no-options */
432         else if( pargs.r_opt == 544 )
433             opt.homedir = pargs.r.ret_str;
434     }
435
436     if( default_config )
437         configname = make_filename(opt.homedir, "options", NULL );
438
439     argc = orig_argc;
440     argv = orig_argv;
441     pargs.argc = &argc;
442     pargs.argv = &argv;
443     pargs.flags=  1;  /* do not remove the args */
444   next_pass:
445     if( configname ) {
446         configlineno = 0;
447         configfp = fopen( configname, "r" );
448         if( !configfp ) {
449             if( default_config ) {
450                 if( parse_debug )
451                     log_info(_("note: no default option file '%s'\n"),
452                                                             configname );
453             }
454             else {
455                 log_error(_("option file '%s': %s\n"),
456                                     configname, strerror(errno) );
457                 g10_exit(1);
458             }
459             m_free(configname); configname = NULL;
460         }
461         if( parse_debug && configname )
462             log_info(_("reading options from '%s'\n"), configname );
463         default_config = 0;
464     }
465
466     while( optfile_parse( configfp, configname, &configlineno,
467                                                 &pargs, opts) ) {
468         switch( pargs.r_opt ) {
469
470         #ifdef IS_G10
471           case 'a': opt.armor = 1; opt.no_armor=0; break;
472           case 'b': detached_sig = 1; set_cmd( &cmd, aSign ); break;
473           case 'c': set_cmd( &cmd, aSym); break;
474           case 'd': set_cmd( &cmd, aDecrypt); break;
475           case 'e': set_cmd( &cmd, aEncr); break;
476           case 'r': /* store the remote users */
477             sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
478             strcpy(sl->d, pargs.r.ret_str);
479             sl->next = remusr;
480             remusr = sl;
481             break;
482           case 's': set_cmd( &cmd, aSign );  break;
483           case 't': opt.textmode=1;  break;
484           case 'u': /* store the local users */
485             sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
486             strcpy(sl->d, pargs.r.ret_str);
487             sl->next = locusr;
488             locusr = sl;
489             break;
490           case 'z': opt.compress = pargs.r.ret_int; break;
491           case 503: set_cmd( &cmd, aKeygen); break;
492           case 504: set_cmd( &cmd, aDeleteSecretKey); break;
493           case 505: set_cmd( &cmd, aDeleteKey); break;
494           case 506: set_cmd( &cmd, aSignKey); break;
495           case 507: set_cmd( &cmd, aStore); break;
496           case 523: set_passphrase_fd( pargs.r.ret_int ); break;
497           case 524: set_cmd( &cmd, aEditSig); break;
498           case 525: set_cmd( &cmd, aChangePass); break;
499           case 527:
500             opt.def_cipher_algo = string_to_cipher_algo(pargs.r.ret_str);
501             break;
502           case 528:
503             opt.def_pubkey_algo = string_to_pubkey_algo(pargs.r.ret_str);
504             break;
505           case 529:
506             opt.def_digest_algo = string_to_digest_algo(pargs.r.ret_str);
507             break;
508           case 539: set_cmd( &cmd, aClearsign); break;
509           case 540: secmem_set_flags( secmem_get_flags() | 1 ); break;
510           case 542: set_cmd( &cmd, aGenRevoke); break;
511           case 550: set_cmd( &cmd, aVerify); break;
512         #endif /* IS_G10 */
513
514         #ifdef IS_G10MAINT
515           case 513: set_cmd( &cmd, aPrimegen); break;
516           case 514: set_cmd( &cmd, aTest); break;
517           case 516: set_cmd( &cmd, aPrintMDs); break;
518           case 531: set_cmd( &cmd, aListTrustDB); break;
519           case 533: set_cmd( &cmd, aListTrustPath); break;
520           case 540: break; /* dummy */
521           case 546: set_cmd( &cmd, aDeArmor); break;
522           case 547: set_cmd( &cmd, aEnArmor); break;
523           case 548: set_cmd( &cmd, aGenRandom); break;
524         #endif /* IS_G10MAINT */
525
526           case 'o': opt.outfile = pargs.r.ret_str; break;
527           case 'v': opt.verbose++; opt.list_sigs=1; break;
528           case 'k': set_cmd( &cmd, aKMode ); break;
529
530           case 500: opt.batch = 1; greeting = 0; break;
531           case 501: opt.answer_yes = 1; break;
532           case 502: opt.answer_no = 1; break;
533           case 508: set_cmd( &cmd, aCheckKeys); break;
534           case 509: add_keyring(pargs.r.ret_str); nrings++; break;
535           case 510: opt.debug |= pargs.r.ret_ulong; break;
536           case 511: opt.debug = ~0; break;
537           case 512: set_status_fd( pargs.r.ret_int ); break;
538           case 515: opt.fingerprint = 1; break;
539           case 517: add_secret_keyring(pargs.r.ret_str); sec_nrings++; break;
540           case 518:
541             /* config files may not be nested (silently ignore them) */
542             if( !configfp ) {
543                 m_free(configname);
544                 configname = m_strdup(pargs.r.ret_str);
545                 goto next_pass;
546             }
547             break;
548           case 519: opt.no_armor=1; opt.armor=0; break;
549           case 520: default_keyring = 0; break;
550           case 521: set_cmd( &cmd, aListPackets); break;
551           case 522: greeting = 0; break;
552           case 526: opt.verbose = 0; opt.list_sigs=0; break;
553           case 530: set_cmd( &cmd, aImport); break;
554           case 532: quick_random_gen(1); break;
555           case 534: opt.no_comment=1; break;
556           case 535: opt.completes_needed = pargs.r.ret_int; break;
557           case 536: opt.marginals_needed = pargs.r.ret_int; break;
558           case 537: set_cmd( &cmd, aExport); break;
559           case 538: trustdb_name = pargs.r.ret_str; break;
560           case 541: set_cmd( &cmd, aNOP); break;
561           case 543: break; /* no-options */
562           case 544: opt.homedir = pargs.r.ret_str; break;
563           case 545: opt.batch = 0; break;
564           case 549: opt.with_colons=':'; break;
565           case 551: set_cmd( &cmd, aListKeys); break;
566           case 552: set_cmd( &cmd, aListSigs); break;
567           default : errors++; pargs.err = configfp? 1:2; break;
568         }
569     }
570     if( configfp ) {
571         fclose( configfp );
572         configfp = NULL;
573         m_free(configname); configname = NULL;
574         goto next_pass;
575     }
576     m_free( configname ); configname = NULL;
577     check_opts();
578     if( log_get_errorcount(0) )
579         g10_exit(2);
580
581     if( greeting ) {
582         tty_printf("%s %s; %s\n", strusage(11), strusage(13), strusage(14) );
583         tty_printf("%s\n", strusage(15) );
584     }
585
586   #ifdef IS_G10
587     /* initialize the secure memory. */
588     secmem_init( 16384 );
589     /* Okay, we are now working under our real uid */
590   #endif
591
592     /*write_status( STATUS_ENTER );*/
593
594     set_debug();
595     if( !cmd && opt.fingerprint )
596         set_cmd( &cmd, aListKeys);
597
598     if( cmd == aKMode || cmd == aKModeC ) { /* kludge to be compatible to pgp */
599         if( cmd == aKModeC ) {
600             opt.fingerprint = 1;
601             cmd = aKMode;
602         }
603         opt.list_sigs = 0;
604         if( opt.verbose > 2 )
605             opt.check_sigs++;
606         if( opt.verbose > 1 )
607             opt.list_sigs++;
608
609         opt.verbose = opt.verbose > 1;
610     }
611
612
613     /* kludge to let -sat generate a clear text signature */
614     if( opt.textmode && !detached_sig && opt.armor && cmd == aSign )
615         cmd = aClearsign;
616
617     if( opt.verbose > 1 )
618         set_packet_list_mode(1);
619
620     /* add the keyrings, but not for some special commands and
621      * not in case of "-kvv userid keyring" */
622     if( cmd != aDeArmor && cmd != aEnArmor
623         && !(cmd == aKMode && argc == 2 ) ) {
624         if( !sec_nrings || default_keyring )  /* add default secret rings */
625             add_secret_keyring("secring.gpg");
626         if( !nrings || default_keyring )  /* add default ring */
627             add_keyring("pubring.gpg");
628     }
629
630     if( argc )
631         fname = *argv;
632     else {
633         fname = NULL;
634         if( get_passphrase_fd() == 0 ) {
635             /* reading data and passphrase form stdin:
636              * we assume the first line is the passphrase, so
637              * we better should read it now.
638              */
639             /* FIXME: doit */
640         }
641     }
642
643     switch( cmd ) {
644       case aPrimegen:
645       case aPrintMDs:
646       case aGenRandom:
647       case aDeArmor:
648       case aEnArmor:
649         break;
650       case aKMode:
651       case aListKeys:
652       case aCheckKeys:
653         break;
654       case aListTrustDB: rc = init_trustdb( argc? 1:0, trustdb_name ); break;
655       default: rc = init_trustdb(1, trustdb_name ); break;
656     }
657     if( rc )
658         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
659
660
661     switch( cmd ) {
662       case aStore: /* only store the file */
663         if( argc > 1 )
664             wrong_args(_("--store [filename]"));
665         if( (rc = encode_store(fname)) )
666             log_error("%s: store failed: %s\n",
667                                  print_fname_stdin(fname), g10_errstr(rc) );
668         break;
669     #ifdef IS_G10
670       case aSym: /* encrypt the given file only with the symmetric cipher */
671         if( argc > 1 )
672             wrong_args(_("--symmetric [filename]"));
673         if( (rc = encode_symmetric(fname)) )
674             log_error("%s: symmetric encryption failed: %s\n",
675                             print_fname_stdin(fname), g10_errstr(rc) );
676         break;
677
678       case aEncr: /* encrypt the given file */
679         if( argc > 1 )
680             wrong_args(_("--encrypt [filename]"));
681         if( (rc = encode_crypt(fname,remusr)) )
682             log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
683         break;
684
685       case aSign: /* sign the given file */
686         sl = NULL;
687         if( detached_sig ) { /* sign all files */
688             for( ; argc; argc--, argv++ )
689                 add_to_strlist( &sl, *argv );
690         }
691         else {
692             if( argc > 1 )
693                 wrong_args(_("--sign [filename]"));
694             if( argc ) {
695                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
696                 strcpy(sl->d, fname);
697             }
698         }
699         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
700             log_error("signing failed: %s\n", g10_errstr(rc) );
701         free_strlist(sl);
702         break;
703
704       case aSignEncr: /* sign and encrypt the given file */
705         if( argc > 1 )
706             wrong_args(_("--sign --encrypt [filename]"));
707         if( argc ) {
708             sl = m_alloc_clear( sizeof *sl + strlen(fname));
709             strcpy(sl->d, fname);
710         }
711         else
712             sl = NULL;
713         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
714             log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
715         free_strlist(sl);
716         break;
717
718       case aClearsign: /* make a clearsig */
719         if( argc > 1 )
720             wrong_args(_("--clearsign [filename]"));
721         if( (rc = clearsign_file(fname, locusr, NULL)) )
722             log_error("%s: clearsign failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
723         break;
724
725       case aVerify:
726         if( (rc = verify_signatures( argc, argv ) ))
727             log_error("verify signatures failed: %s\n", g10_errstr(rc) );
728         break;
729
730       case aDecrypt:
731         if( argc > 1 )
732             wrong_args(_("--decrypt [filename]"));
733         if( (rc = decrypt_message( fname ) ))
734             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
735         break;
736
737
738       case aSignKey: /* sign the key given as argument */
739         if( argc != 1 )
740             wrong_args(_("--sign-key username"));
741         /* note: fname is the user id! */
742         if( (rc = sign_key(fname, locusr)) )
743             log_error("%s: sign key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
744         break;
745
746       case aEditSig: /* Edit a key signature */
747         if( argc != 1 )
748             wrong_args(_("--edit-sig username"));
749         /* note: fname is the user id! */
750         if( (rc = edit_keysigs(fname)) )
751             log_error("%s: edit signature failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
752         break;
753
754       case aDeleteSecretKey:
755         if( argc != 1 )
756             wrong_args(_("--delete-secret-key username"));
757       case aDeleteKey:
758         if( argc != 1 )
759             wrong_args(_("--delete-key username"));
760         /* note: fname is the user id! */
761         if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
762             log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
763         break;
764
765       case aChangePass: /* Change the passphrase */
766         if( argc > 1 ) /* no arg: use default, 1 arg use this one */
767             wrong_args(_("--change-passphrase [username]"));
768         /* note: fname is the user id! */
769         if( (rc = change_passphrase(fname)) )
770             log_error("%s: change passphrase failed: %s\n", print_fname_stdin(fname),
771                                                        g10_errstr(rc) );
772         break;
773       #endif /* IS_G10 */
774
775       case aCheckKeys:
776         opt.check_sigs = 1;
777       case aListSigs:
778         opt.list_sigs = 1;
779       case aListKeys:
780         std_key_list( argc, argv );
781         break;
782
783       case aKMode: /* list keyring */
784         if( argc < 2 )  /* -kv [userid] */
785             std_key_list( (argc && **argv)? 1:0, argv );
786         else if( argc == 2 ) { /* -kv userid keyring */
787             if( access( argv[1], R_OK ) ) {
788                 log_error(_("can't open %s: %s\n"),
789                                print_fname_stdin(argv[1]), strerror(errno));
790             }
791             else {
792                 /* add keyring (default keyrings are not registered in this
793                  * special case */
794                 add_keyring( argv[1] );
795                 std_key_list( **argv?1:0, argv );
796             }
797         }
798         else
799             wrong_args(_("-k[v][v][v][c] [userid] [keyring]") );
800         break;
801
802     #ifdef IS_G10
803       case aKeygen: /* generate a key (interactive) */
804         if( argc )
805             wrong_args(_("--gen-key"));
806         generate_keypair();
807         break;
808     #endif
809
810       case aImport:
811         if( !argc  ) {
812             rc = import_pubkeys( NULL );
813             if( rc )
814                 log_error("import failed: %s\n", g10_errstr(rc) );
815         }
816         for( ; argc; argc--, argv++ ) {
817             rc = import_pubkeys( *argv );
818             if( rc )
819                 log_error("import from '%s' failed: %s\n",
820                                                 *argv, g10_errstr(rc) );
821         }
822         break;
823
824       case aExport:
825         sl = NULL;
826         for( ; argc; argc--, argv++ )
827             add_to_strlist( &sl, *argv );
828         export_pubkeys( sl );
829         free_strlist(sl);
830         break;
831
832     #ifdef IS_G10
833       case aGenRevoke:
834         if( argc != 1 )
835             wrong_args("--gen-revoke user-id");
836         gen_revoke( *argv );
837         break;
838     #endif
839
840     #ifdef IS_G10MAINT
841       case aDeArmor:
842         if( argc > 1 )
843             wrong_args("--dearmor [file]");
844         rc = dearmor_file( argc? *argv: NULL );
845         if( rc )
846             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
847         break;
848
849       case aEnArmor:
850         if( argc > 1 )
851             wrong_args("--enarmor [file]");
852         rc = enarmor_file( argc? *argv: NULL );
853         if( rc )
854             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
855         break;
856
857
858       case aPrimegen:
859         if( argc == 1 ) {
860             mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
861             putchar('\n');
862         }
863         else if( argc == 2 ) {
864             mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
865                                                    atoi(argv[1]), NULL,NULL ), 1);
866             putchar('\n');
867         }
868         else if( argc == 3 ) {
869             MPI g = mpi_alloc(1);
870             mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
871                                                    atoi(argv[1]), g, NULL ), 1);
872             printf("\nGenerator: ");
873             mpi_print( stdout, g, 1 );
874             putchar('\n');
875             mpi_free(g);
876         }
877         else
878             usage(1);
879         break;
880
881       case aGenRandom:
882         if( argc < 1 || argc > 2 )
883             wrong_args("--gen-random level [hex]");
884         {
885             int level = atoi(*argv);
886             for(;;) {
887                 int c = get_random_byte(level);
888                 if( argc == 1 ) {
889                     printf("%02x", c );
890                     fflush(stdout);
891                 }
892                 else
893                     putchar(c&0xff);
894             }
895         }
896         break;
897
898       case aPrintMDs:
899         if( !argc )
900             print_mds(NULL);
901         else {
902             for(; argc; argc--, argv++ )
903                 print_mds(*argv);
904         }
905         break;
906
907       case aTest: do_test( argc? atoi(*argv): 1 ); break;
908
909       case aListTrustDB:
910         if( !argc )
911             list_trustdb(NULL);
912         else {
913             for( ; argc; argc--, argv++ )
914                 list_trustdb( *argv );
915         }
916         break;
917
918       case aListTrustPath:
919         if( argc != 2 )
920             wrong_args("--list-trust-path [-- -]<maxdepth> <username>");
921         list_trust_path( atoi(*argv), argv[1] );
922         break;
923
924      #endif /* IS_G10MAINT */
925
926
927       case aNOP:
928         break;
929
930       case aListPackets:
931         opt.list_packets=1;
932       default:
933         /* fixme: g10maint should to regular maintenace tasks here */
934         if( argc > 1 )
935             wrong_args(_("[filename]"));
936         if( !(a = iobuf_open(fname)) )
937             log_error(_("can't open '%s'\n"), print_fname_stdin(fname));
938         else {
939             if( !opt.no_armor ) {
940                 if( use_armor_filter( a ) ) {
941                     memset( &afx, 0, sizeof afx);
942                     iobuf_push_filter( a, armor_filter, &afx );
943                 }
944             }
945             if( cmd == aListPackets ) {
946                 set_packet_list_mode(1);
947                 opt.list_packets=1;
948             }
949             proc_packets( a );
950             iobuf_close(a);
951         }
952         break;
953     }
954
955     /* cleanup */
956     FREE_STRLIST(remusr);
957     FREE_STRLIST(locusr);
958     g10_exit(0);
959 }
960
961
962 void
963 g10_exit( int rc )
964 {
965     if( opt.debug )
966         secmem_dump_stats();
967     secmem_term();
968     rc = rc? rc : log_get_errorcount(0)? 2:0;
969     /*write_status( STATUS_LEAVE );*/
970     exit(rc );
971 }
972
973 #ifdef IS_G10MAINT
974 static void
975 print_hex( byte *p, size_t n )
976 {
977     int i;
978
979     if( n == 20 ) {
980         for(i=0; i < n ; i++, i++, p += 2 ) {
981             if( i == 10 )
982                 putchar(' ');
983             printf(" %02X%02X", *p, p[1] );
984         }
985     }
986     else {
987         for(i=0; i < n ; i++, p++ ) {
988             if( i && !(i%8) )
989                 putchar(' ');
990             printf(" %02X", *p );
991         }
992     }
993 }
994
995 static void
996 print_mds( const char *fname )
997 {
998     FILE *fp;
999     char buf[1024];
1000     size_t n;
1001     MD_HANDLE md;
1002
1003     if( !fname ) {
1004         fp = stdin;
1005         fname = "[stdin]";
1006     }
1007     else
1008         fp = fopen( fname, "rb" );
1009     if( !fp ) {
1010         log_error("%s: %s\n", fname, strerror(errno) );
1011         return;
1012     }
1013
1014     md = md_open( DIGEST_ALGO_MD5, 0 );
1015     md_enable( md, DIGEST_ALGO_RMD160 );
1016     md_enable( md, DIGEST_ALGO_SHA1 );
1017
1018     while( (n=fread( buf, 1, DIM(buf), fp )) )
1019         md_write( md, buf, n );
1020     if( ferror(fp) )
1021         log_error("%s: %s\n", fname, strerror(errno) );
1022     else {
1023         md_final(md);
1024         printf(  "%s:    MD5 =", fname ); print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
1025         printf("\n%s: RMD160 =", fname ); print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
1026         printf("\n%s:   SHA1 =", fname ); print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
1027         putchar('\n');
1028     }
1029
1030
1031     md_close(md);
1032
1033     if( fp != stdin )
1034         fclose(fp);
1035 }
1036
1037
1038
1039 static void
1040 do_test(int times)
1041 {
1042     MPI base[4];
1043     MPI exp[4];
1044     MPI t1 = mpi_alloc(50);
1045     MPI t2 = mpi_alloc(50);
1046     MPI t3 = mpi_alloc(50);
1047     MPI tmp= mpi_alloc(50);
1048     MPI m =   mpi_alloc(50);
1049     MPI res = mpi_alloc(50);
1050
1051     mpi_fromstr( m, "0x10000000000000000000000000" );
1052     base[0] = mpi_alloc_set_ui( 3 );
1053     mpi_fromstr( base[0], "0x145984358945989898495ffdd13" );
1054     base[1] = mpi_alloc_set_ui( 5 );
1055     mpi_fromstr( base[1], "0x000effff9999000000001100001" );
1056     base[2] = mpi_alloc_set_ui( 2 );
1057     mpi_fromstr( base[2], "0x499eeeaaaaa0444444545466672" );
1058     base[3] = NULL;
1059     exp[0]  = mpi_alloc_set_ui( 30 );
1060     exp[1]  = mpi_alloc_set_ui( 10 );
1061     mpi_fromstr( exp[1], "0x3457878888888888aabbbccccc1" );
1062     exp[2]  = mpi_alloc_set_ui( 24 );
1063     exp[3] = NULL;
1064
1065     mpi_powm( t1, base[0], exp[0], m );
1066     mpi_powm( t2, base[1], exp[1], m );
1067     mpi_powm( t3, base[2], exp[2], m );
1068     mpi_mulm( tmp, t1, t2, m );
1069     mpi_mulm( t1, tmp, t3, m );
1070     log_mpidump("X=", t1 );
1071
1072
1073     mpi_mulpowm( res, base, exp, m );
1074     log_mpidump("X=", res );
1075
1076
1077     m_check(NULL);
1078 }
1079 #endif /* IS_G10MAINT */
1080