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