release 0.2.14
[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              * We should do it here, but for now it is not needed.
640              * Anyway, this password scheme is not quite good
641              */
642         }
643     }
644
645     switch( cmd ) {
646       case aPrimegen:
647       case aPrintMDs:
648       case aGenRandom:
649       case aDeArmor:
650       case aEnArmor:
651         break;
652       case aKMode:
653       case aListKeys:
654       case aCheckKeys:
655         break;
656       case aListTrustDB: rc = init_trustdb( argc? 1:0, trustdb_name ); break;
657       default: rc = init_trustdb(1, trustdb_name ); break;
658     }
659     if( rc )
660         log_error(_("failed to initialize the TrustDB: %s\n"), g10_errstr(rc));
661
662
663     switch( cmd ) {
664       case aStore: /* only store the file */
665         if( argc > 1 )
666             wrong_args(_("--store [filename]"));
667         if( (rc = encode_store(fname)) )
668             log_error("%s: store failed: %s\n",
669                                  print_fname_stdin(fname), g10_errstr(rc) );
670         break;
671     #ifdef IS_G10
672       case aSym: /* encrypt the given file only with the symmetric cipher */
673         if( argc > 1 )
674             wrong_args(_("--symmetric [filename]"));
675         if( (rc = encode_symmetric(fname)) )
676             log_error("%s: symmetric encryption failed: %s\n",
677                             print_fname_stdin(fname), g10_errstr(rc) );
678         break;
679
680       case aEncr: /* encrypt the given file */
681         if( argc > 1 )
682             wrong_args(_("--encrypt [filename]"));
683         if( (rc = encode_crypt(fname,remusr)) )
684             log_error("%s: encryption failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
685         break;
686
687       case aSign: /* sign the given file */
688         sl = NULL;
689         if( detached_sig ) { /* sign all files */
690             for( ; argc; argc--, argv++ )
691                 add_to_strlist( &sl, *argv );
692         }
693         else {
694             if( argc > 1 )
695                 wrong_args(_("--sign [filename]"));
696             if( argc ) {
697                 sl = m_alloc_clear( sizeof *sl + strlen(fname));
698                 strcpy(sl->d, fname);
699             }
700         }
701         if( (rc = sign_file( sl, detached_sig, locusr, 0, NULL, NULL)) )
702             log_error("signing failed: %s\n", g10_errstr(rc) );
703         free_strlist(sl);
704         break;
705
706       case aSignEncr: /* sign and encrypt the given file */
707         if( argc > 1 )
708             wrong_args(_("--sign --encrypt [filename]"));
709         if( argc ) {
710             sl = m_alloc_clear( sizeof *sl + strlen(fname));
711             strcpy(sl->d, fname);
712         }
713         else
714             sl = NULL;
715         if( (rc = sign_file(sl, detached_sig, locusr, 1, remusr, NULL)) )
716             log_error("%s: sign+encrypt failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
717         free_strlist(sl);
718         break;
719
720       case aClearsign: /* make a clearsig */
721         if( argc > 1 )
722             wrong_args(_("--clearsign [filename]"));
723         if( (rc = clearsign_file(fname, locusr, NULL)) )
724             log_error("%s: clearsign failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
725         break;
726
727       case aVerify:
728         if( (rc = verify_signatures( argc, argv ) ))
729             log_error("verify signatures failed: %s\n", g10_errstr(rc) );
730         break;
731
732       case aDecrypt:
733         if( argc > 1 )
734             wrong_args(_("--decrypt [filename]"));
735         if( (rc = decrypt_message( fname ) ))
736             log_error("decrypt_message failed: %s\n", g10_errstr(rc) );
737         break;
738
739
740       case aSignKey: /* sign the key given as argument */
741         if( argc != 1 )
742             wrong_args(_("--sign-key username"));
743         /* note: fname is the user id! */
744         if( (rc = sign_key(fname, locusr)) )
745             log_error("%s: sign key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
746         break;
747
748       case aEditSig: /* Edit a key signature */
749         if( argc != 1 )
750             wrong_args(_("--edit-sig username"));
751         /* note: fname is the user id! */
752         if( (rc = edit_keysigs(fname)) )
753             log_error("%s: edit signature failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
754         break;
755
756       case aDeleteSecretKey:
757         if( argc != 1 )
758             wrong_args(_("--delete-secret-key username"));
759       case aDeleteKey:
760         if( argc != 1 )
761             wrong_args(_("--delete-key username"));
762         /* note: fname is the user id! */
763         if( (rc = delete_key(fname, cmd==aDeleteSecretKey)) )
764             log_error("%s: delete key failed: %s\n", print_fname_stdin(fname), g10_errstr(rc) );
765         break;
766
767       case aChangePass: /* Change the passphrase */
768         if( argc > 1 ) /* no arg: use default, 1 arg use this one */
769             wrong_args(_("--change-passphrase [username]"));
770         /* note: fname is the user id! */
771         if( (rc = change_passphrase(fname)) )
772             log_error("%s: change passphrase failed: %s\n", print_fname_stdin(fname),
773                                                        g10_errstr(rc) );
774         break;
775       #endif /* IS_G10 */
776
777       case aCheckKeys:
778         opt.check_sigs = 1;
779       case aListSigs:
780         opt.list_sigs = 1;
781       case aListKeys:
782         std_key_list( argc, argv );
783         break;
784
785       case aKMode: /* list keyring */
786         if( argc < 2 )  /* -kv [userid] */
787             std_key_list( (argc && **argv)? 1:0, argv );
788         else if( argc == 2 ) { /* -kv userid keyring */
789             if( access( argv[1], R_OK ) ) {
790                 log_error(_("can't open %s: %s\n"),
791                                print_fname_stdin(argv[1]), strerror(errno));
792             }
793             else {
794                 /* add keyring (default keyrings are not registered in this
795                  * special case */
796                 add_keyring( argv[1] );
797                 std_key_list( **argv?1:0, argv );
798             }
799         }
800         else
801             wrong_args(_("-k[v][v][v][c] [userid] [keyring]") );
802         break;
803
804     #ifdef IS_G10
805       case aKeygen: /* generate a key (interactive) */
806         if( argc )
807             wrong_args(_("--gen-key"));
808         generate_keypair();
809         break;
810     #endif
811
812       case aImport:
813         if( !argc  ) {
814             rc = import_pubkeys( NULL );
815             if( rc )
816                 log_error("import failed: %s\n", g10_errstr(rc) );
817         }
818         for( ; argc; argc--, argv++ ) {
819             rc = import_pubkeys( *argv );
820             if( rc )
821                 log_error("import from '%s' failed: %s\n",
822                                                 *argv, g10_errstr(rc) );
823         }
824         break;
825
826       case aExport:
827         sl = NULL;
828         for( ; argc; argc--, argv++ )
829             add_to_strlist( &sl, *argv );
830         export_pubkeys( sl );
831         free_strlist(sl);
832         break;
833
834     #ifdef IS_G10
835       case aGenRevoke:
836         if( argc != 1 )
837             wrong_args("--gen-revoke user-id");
838         gen_revoke( *argv );
839         break;
840     #endif
841
842     #ifdef IS_G10MAINT
843       case aDeArmor:
844         if( argc > 1 )
845             wrong_args("--dearmor [file]");
846         rc = dearmor_file( argc? *argv: NULL );
847         if( rc )
848             log_error(_("dearmoring failed: %s\n"), g10_errstr(rc));
849         break;
850
851       case aEnArmor:
852         if( argc > 1 )
853             wrong_args("--enarmor [file]");
854         rc = enarmor_file( argc? *argv: NULL );
855         if( rc )
856             log_error(_("enarmoring failed: %s\n"), g10_errstr(rc));
857         break;
858
859
860       case aPrimegen:
861         if( argc == 1 ) {
862             mpi_print( stdout, generate_public_prime( atoi(argv[0]) ), 1);
863             putchar('\n');
864         }
865         else if( argc == 2 ) {
866             mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
867                                                    atoi(argv[1]), NULL,NULL ), 1);
868             putchar('\n');
869         }
870         else if( argc == 3 ) {
871             MPI g = mpi_alloc(1);
872             mpi_print( stdout, generate_elg_prime( atoi(argv[0]),
873                                                    atoi(argv[1]), g, NULL ), 1);
874             printf("\nGenerator: ");
875             mpi_print( stdout, g, 1 );
876             putchar('\n');
877             mpi_free(g);
878         }
879         else
880             usage(1);
881         break;
882
883       case aGenRandom:
884         if( argc < 1 || argc > 2 )
885             wrong_args("--gen-random level [hex]");
886         {
887             int level = atoi(*argv);
888             for(;;) {
889                 int c = get_random_byte(level);
890                 if( argc == 1 ) {
891                     printf("%02x", c );
892                     fflush(stdout);
893                 }
894                 else
895                     putchar(c&0xff);
896             }
897         }
898         break;
899
900       case aPrintMDs:
901         if( !argc )
902             print_mds(NULL);
903         else {
904             for(; argc; argc--, argv++ )
905                 print_mds(*argv);
906         }
907         break;
908
909       case aTest: do_test( argc? atoi(*argv): 1 ); break;
910
911       case aListTrustDB:
912         if( !argc )
913             list_trustdb(NULL);
914         else {
915             for( ; argc; argc--, argv++ )
916                 list_trustdb( *argv );
917         }
918         break;
919
920       case aListTrustPath:
921         if( argc != 2 )
922             wrong_args("--list-trust-path [-- -]<maxdepth> <username>");
923         list_trust_path( atoi(*argv), argv[1] );
924         break;
925
926      #endif /* IS_G10MAINT */
927
928
929       case aNOP:
930         break;
931
932       case aListPackets:
933         opt.list_packets=1;
934       default:
935         /* fixme: g10maint should to regular maintenace tasks here */
936         if( argc > 1 )
937             wrong_args(_("[filename]"));
938         if( !(a = iobuf_open(fname)) )
939             log_error(_("can't open '%s'\n"), print_fname_stdin(fname));
940         else {
941             if( !opt.no_armor ) {
942                 if( use_armor_filter( a ) ) {
943                     memset( &afx, 0, sizeof afx);
944                     iobuf_push_filter( a, armor_filter, &afx );
945                 }
946             }
947             if( cmd == aListPackets ) {
948                 set_packet_list_mode(1);
949                 opt.list_packets=1;
950             }
951             proc_packets( a );
952             iobuf_close(a);
953         }
954         break;
955     }
956
957     /* cleanup */
958     FREE_STRLIST(remusr);
959     FREE_STRLIST(locusr);
960     g10_exit(0);
961 }
962
963
964 void
965 g10_exit( int rc )
966 {
967     if( opt.debug )
968         secmem_dump_stats();
969     secmem_term();
970     rc = rc? rc : log_get_errorcount(0)? 2:0;
971     /*write_status( STATUS_LEAVE );*/
972     exit(rc );
973 }
974
975 #ifdef IS_G10MAINT
976 static void
977 print_hex( byte *p, size_t n )
978 {
979     int i;
980
981     if( n == 20 ) {
982         for(i=0; i < n ; i++, i++, p += 2 ) {
983             if( i == 10 )
984                 putchar(' ');
985             printf(" %02X%02X", *p, p[1] );
986         }
987     }
988     else {
989         for(i=0; i < n ; i++, p++ ) {
990             if( i && !(i%8) )
991                 putchar(' ');
992             printf(" %02X", *p );
993         }
994     }
995 }
996
997 static void
998 print_mds( const char *fname )
999 {
1000     FILE *fp;
1001     char buf[1024];
1002     size_t n;
1003     MD_HANDLE md;
1004
1005     if( !fname ) {
1006         fp = stdin;
1007         fname = "[stdin]";
1008     }
1009     else
1010         fp = fopen( fname, "rb" );
1011     if( !fp ) {
1012         log_error("%s: %s\n", fname, strerror(errno) );
1013         return;
1014     }
1015
1016     md = md_open( DIGEST_ALGO_MD5, 0 );
1017     md_enable( md, DIGEST_ALGO_RMD160 );
1018     md_enable( md, DIGEST_ALGO_SHA1 );
1019
1020     while( (n=fread( buf, 1, DIM(buf), fp )) )
1021         md_write( md, buf, n );
1022     if( ferror(fp) )
1023         log_error("%s: %s\n", fname, strerror(errno) );
1024     else {
1025         md_final(md);
1026         printf(  "%s:    MD5 =", fname ); print_hex(md_read(md, DIGEST_ALGO_MD5), 16 );
1027         printf("\n%s: RMD160 =", fname ); print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
1028         printf("\n%s:   SHA1 =", fname ); print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
1029         putchar('\n');
1030     }
1031
1032
1033     md_close(md);
1034
1035     if( fp != stdin )
1036         fclose(fp);
1037 }
1038
1039
1040
1041 static void
1042 do_test(int times)
1043 {
1044     MPI base[4];
1045     MPI exp[4];
1046     MPI t1 = mpi_alloc(50);
1047     MPI t2 = mpi_alloc(50);
1048     MPI t3 = mpi_alloc(50);
1049     MPI tmp= mpi_alloc(50);
1050     MPI m =   mpi_alloc(50);
1051     MPI res = mpi_alloc(50);
1052
1053     mpi_fromstr( m, "0x10000000000000000000000000" );
1054     base[0] = mpi_alloc_set_ui( 3 );
1055     mpi_fromstr( base[0], "0x145984358945989898495ffdd13" );
1056     base[1] = mpi_alloc_set_ui( 5 );
1057     mpi_fromstr( base[1], "0x000effff9999000000001100001" );
1058     base[2] = mpi_alloc_set_ui( 2 );
1059     mpi_fromstr( base[2], "0x499eeeaaaaa0444444545466672" );
1060     base[3] = NULL;
1061     exp[0]  = mpi_alloc_set_ui( 30 );
1062     exp[1]  = mpi_alloc_set_ui( 10 );
1063     mpi_fromstr( exp[1], "0x3457878888888888aabbbccccc1" );
1064     exp[2]  = mpi_alloc_set_ui( 24 );
1065     exp[3] = NULL;
1066
1067     mpi_powm( t1, base[0], exp[0], m );
1068     mpi_powm( t2, base[1], exp[1], m );
1069     mpi_powm( t3, base[2], exp[2], m );
1070     mpi_mulm( tmp, t1, t2, m );
1071     mpi_mulm( t1, tmp, t3, m );
1072     log_mpidump("X=", t1 );
1073
1074
1075     mpi_mulpowm( res, base, exp, m );
1076     log_mpidump("X=", res );
1077
1078
1079     m_check(NULL);
1080 }
1081 #endif /* IS_G10MAINT */
1082