A couple of fixes. gpg2's key generation does now work.
[gnupg.git] / g10 / misc.c
1 /* misc.c - miscellaneous functions
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3  *               2005, 2006 Free Software Foundation, Inc.
4  *
5  * This file is part of GnuPG.
6  *
7  * GnuPG is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * GnuPG is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
20  * USA.
21  */
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <errno.h>
29 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
30 #include <asm/sysinfo.h>
31 #include <asm/unistd.h>
32 #endif
33 #ifdef HAVE_SETRLIMIT
34 #include <time.h>
35 #include <sys/time.h>
36 #include <sys/resource.h>
37 #endif
38 #ifdef ENABLE_SELINUX_HACKS
39 #include <sys/stat.h>
40 #endif
41
42 #ifdef HAVE_W32_SYSTEM
43 #include <time.h>
44 #include <process.h>
45 #include <windows.h> 
46 #include <shlobj.h>
47 #ifndef CSIDL_APPDATA
48 #define CSIDL_APPDATA 0x001a
49 #endif
50 #ifndef CSIDL_LOCAL_APPDATA
51 #define CSIDL_LOCAL_APPDATA 0x001c
52 #endif
53 #ifndef CSIDL_FLAG_CREATE
54 #define CSIDL_FLAG_CREATE 0x8000
55 #endif
56 #endif /*HAVE_W32_SYSTEM*/
57
58 #include "gpg.h"
59 #ifdef HAVE_W32_SYSTEM
60 # include "errors.h"
61 # include "dynload.h"
62 #endif /*HAVE_W32_SYSTEM*/
63 #include "util.h"
64 #include "main.h"
65 #include "photoid.h"
66 #include "options.h"
67 #include "i18n.h"
68
69
70 static int
71 string_count_chr (const char *string, int c)
72 {
73   int count;
74
75   for (count=0; *string; string++ )
76     if ( *string == c )
77       count++;
78   return count;
79 }
80
81
82
83 #ifdef ENABLE_SELINUX_HACKS
84 /* A object and a global variable to keep track of files marked as
85    secured. */
86 struct secured_file_item 
87 {
88   struct secured_file_item *next;
89   ino_t ino;
90   dev_t dev;
91 };
92 static struct secured_file_item *secured_files;
93 #endif /*ENABLE_SELINUX_HACKS*/
94
95
96
97 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
98 static int
99 setsysinfo(unsigned long op, void *buffer, unsigned long size,
100                      int *start, void *arg, unsigned long flag)
101 {
102     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
103 }
104
105 void
106 trap_unaligned(void)
107 {
108     unsigned int buf[2];
109
110     buf[0] = SSIN_UACPROC;
111     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
112     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
113 }
114 #else
115 void
116 trap_unaligned(void)
117 {  /* dummy */
118 }
119 #endif
120
121
122 int
123 disable_core_dumps()
124 {
125 #ifdef HAVE_DOSISH_SYSTEM
126     return 0;
127 #else
128 #ifdef HAVE_SETRLIMIT
129     struct rlimit limit;
130
131     limit.rlim_cur = 0;
132     limit.rlim_max = 0;
133     if( !setrlimit( RLIMIT_CORE, &limit ) )
134         return 0;
135     if( errno != EINVAL && errno != ENOSYS )
136         log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
137 #endif
138     return 1;
139 #endif
140 }
141
142
143 /* For the sake of SELinux we want to restrict access through gpg to
144    certain files we keep under our own control.  This function
145    registers such a file and is_secured_file may then be used to
146    check whether a file has ben registered as secured. */
147 void
148 register_secured_file (const char *fname)
149 {
150 #ifdef ENABLE_SELINUX_HACKS
151   struct stat buf;
152   struct secured_file_item *sf;
153
154   /* Note that we stop immediatley if something goes wrong here. */
155   if (stat (fname, &buf))
156     log_fatal (_("fstat of `%s' failed in %s: %s\n"), fname, 
157                "register_secured_file", strerror (errno));
158 /*   log_debug ("registering `%s' i=%lu.%lu\n", fname, */
159 /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
160   for (sf=secured_files; sf; sf = sf->next)
161     {
162       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
163         return; /* Already registered.  */
164     }
165
166   sf = xmalloc (sizeof *sf);
167   sf->ino = buf.st_ino;
168   sf->dev = buf.st_dev;
169   sf->next = secured_files;
170   secured_files = sf;
171 #endif /*ENABLE_SELINUX_HACKS*/
172 }
173
174 /* Remove a file registered as secure. */
175 void
176 unregister_secured_file (const char *fname)
177 {
178 #ifdef ENABLE_SELINUX_HACKS
179   struct stat buf;
180   struct secured_file_item *sf, *sfprev;
181
182   if (stat (fname, &buf))
183     {
184       log_error (_("fstat of `%s' failed in %s: %s\n"), fname,
185                  "unregister_secured_file", strerror (errno));
186       return;
187     }
188 /*   log_debug ("unregistering `%s' i=%lu.%lu\n", fname,  */
189 /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
190   for (sfprev=NULL,sf=secured_files; sf; sfprev=sf, sf = sf->next)
191     {
192       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
193         {
194           if (sfprev)
195             sfprev->next = sf->next;
196           else
197             secured_files = sf->next;
198           xfree (sf);
199           return;
200         }
201     }
202 #endif /*ENABLE_SELINUX_HACKS*/
203 }
204
205 /* Return true if FD is corresponds to a secured file.  Using -1 for
206    FS is allowed and will return false. */ 
207 int 
208 is_secured_file (int fd)
209 {
210 #ifdef ENABLE_SELINUX_HACKS
211   struct stat buf;
212   struct secured_file_item *sf;
213
214   if (fd == -1)
215     return 0; /* No file descriptor so it can't be secured either.  */
216
217   /* Note that we print out a error here and claim that a file is
218      secure if something went wrong. */
219   if (fstat (fd, &buf))
220     {
221       log_error (_("fstat(%d) failed in %s: %s\n"), fd, 
222                  "is_secured_file", strerror (errno));
223       return 1;
224     }
225 /*   log_debug ("is_secured_file (%d) i=%lu.%lu\n", fd, */
226 /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
227   for (sf=secured_files; sf; sf = sf->next)
228     {
229       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
230         return 1; /* Yes.  */
231     }
232 #endif /*ENABLE_SELINUX_HACKS*/
233   return 0; /* No. */
234 }
235
236 /* Return true if FNAME is corresponds to a secured file.  Using NULL,
237    "" or "-" for FS is allowed and will return false. This function is
238    used before creating a file, thus it won't fail if the file does
239    not exist. */ 
240 int 
241 is_secured_filename (const char *fname)
242 {
243 #ifdef ENABLE_SELINUX_HACKS
244   struct stat buf;
245   struct secured_file_item *sf;
246
247   if (iobuf_is_pipe_filename (fname) || !*fname)
248     return 0; 
249
250   /* Note that we print out a error here and claim that a file is
251      secure if something went wrong. */
252   if (stat (fname, &buf))
253     {
254       if (errno == ENOENT || errno == EPERM || errno == EACCES)
255         return 0;
256       log_error (_("fstat of `%s' failed in %s: %s\n"), fname,
257                  "is_secured_filename", strerror (errno));
258       return 1;
259     }
260 /*   log_debug ("is_secured_filename (%s) i=%lu.%lu\n", fname, */
261 /*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
262   for (sf=secured_files; sf; sf = sf->next)
263     {
264       if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
265         return 1; /* Yes.  */
266     }
267 #endif /*ENABLE_SELINUX_HACKS*/
268   return 0; /* No. */
269 }
270
271
272
273 u16
274 checksum_u16( unsigned n )
275 {
276     u16 a;
277
278     a  = (n >> 8) & 0xff;
279     a += n & 0xff;
280     return a;
281 }
282
283
284 u16
285 checksum( byte *p, unsigned n )
286 {
287     u16 a;
288
289     for(a=0; n; n-- )
290         a += *p++;
291     return a;
292 }
293
294 u16
295 checksum_mpi (gcry_mpi_t a)
296 {
297   u16 csum;
298   byte *buffer;
299   unsigned int nbytes;
300
301   if ( gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, a) )
302     BUG ();
303   /* Fixme: For numbers not in secure memory we should use a stack
304    * based buffer and only allocate a larger one if mpi_print returns
305    * an error. */
306   buffer = (gcry_is_secure(a)?
307             gcry_xmalloc_secure (nbytes) : gcry_xmalloc (nbytes));
308   if ( gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, NULL, a) )
309     BUG ();
310   csum = checksum (buffer, nbytes);
311   xfree (buffer);
312   return csum;
313 }
314
315 u32
316 buffer_to_u32( const byte *buffer )
317 {
318     unsigned long a;
319     a =  *buffer << 24;
320     a |= buffer[1] << 16;
321     a |= buffer[2] << 8;
322     a |= buffer[3];
323     return a;
324 }
325
326 void
327 print_pubkey_algo_note( int algo )
328 {
329   if(algo >= 100 && algo <= 110)
330     {
331       static int warn=0;
332       if(!warn)
333         {
334           warn=1;
335           log_info (_("WARNING: using experimental public key algorithm %s\n"),
336                     gcry_pk_algo_name (algo));
337         }
338     }
339 }
340
341 void
342 print_cipher_algo_note( int algo )
343 {
344   if(algo >= 100 && algo <= 110)
345     {
346       static int warn=0;
347       if(!warn)
348         {
349           warn=1;
350           log_info (_("WARNING: using experimental cipher algorithm %s\n"),
351                     gcry_cipher_algo_name (algo));
352         }
353     }
354 }
355
356 void
357 print_digest_algo_note( int algo )
358 {
359   if(algo >= 100 && algo <= 110)
360     {
361       static int warn=0;
362       if(!warn)
363         {
364           warn=1;
365           log_info (_("WARNING: using experimental digest algorithm %s\n"),
366                     gcry_md_algo_name (algo));
367         }
368     }
369   else if(algo==DIGEST_ALGO_MD5)
370     log_info (_("WARNING: digest algorithm %s is deprecated\n"),
371               gcry_md_algo_name (algo));
372 }
373
374 /* Return a string which is used as a kind of process ID */
375 const byte *
376 get_session_marker( size_t *rlen )
377 {
378   static byte marker[SIZEOF_UNSIGNED_LONG*2];
379   static int initialized;
380   
381   if ( !initialized )
382     {
383       volatile ulong aa, bb; /* We really want the uninitialized value. */
384       ulong a, b;
385       
386       initialized = 1;
387       /* Although this marker is guessable it is not easy to use this
388        * for a faked control packet because an attacker does not have
389        * enough control about the time the verification takes place.
390        * Of course, we could add just more random but than we need the
391        * random generator even for verification tasks - which does not
392        * make sense. */
393       a = aa ^ (ulong)getpid();
394       b = bb ^ (ulong)time(NULL);
395       memcpy ( marker, &a, SIZEOF_UNSIGNED_LONG );
396       memcpy ( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
397     }
398   *rlen = sizeof(marker);
399   return marker;
400 }
401
402 /****************
403  * Wrapper around the libgcrypt function with additonal checks on
404  * the OpenPGP contraints for the algo ID.
405  */
406 int
407 openpgp_cipher_test_algo( int algo )
408 {
409   if ( algo < 0 || algo > 110 )
410     return gpg_error (GPG_ERR_CIPHER_ALGO);
411   return gcry_cipher_test_algo (algo);
412 }
413
414 int
415 openpgp_pk_test_algo( int algo )
416 {
417   if (algo == GCRY_PK_ELG_E)
418     algo = GCRY_PK_ELG;
419
420   if (algo < 0 || algo > 110)
421     return gpg_error (GPG_ERR_PUBKEY_ALGO);
422   return gcry_pk_test_algo (algo);
423 }
424
425 int
426 openpgp_pk_test_algo2( int algo, unsigned int use )
427 {
428   int use_buf = use;
429
430   if (algo == GCRY_PK_ELG_E)
431     algo = GCRY_PK_ELG;
432
433   if (algo < 0 || algo > 110)
434     return gpg_error (GPG_ERR_PUBKEY_ALGO);
435
436   return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, &use_buf);
437 }
438
439 int 
440 openpgp_pk_algo_usage ( int algo )
441 {
442     int use = 0; 
443     
444     /* They are hardwired in gpg 1.0. */
445     switch ( algo ) {    
446       case PUBKEY_ALGO_RSA:
447           use = (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG
448                  | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH);
449           break;
450       case PUBKEY_ALGO_RSA_E:
451           use = PUBKEY_USAGE_ENC;
452           break;
453       case PUBKEY_ALGO_RSA_S:
454           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG;
455           break;
456       case PUBKEY_ALGO_ELGAMAL_E:
457           use = PUBKEY_USAGE_ENC;
458           break;
459       case PUBKEY_ALGO_DSA:  
460           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
461           break;
462       default:
463           break;
464     }
465     return use;
466 }
467
468 int
469 openpgp_md_test_algo( int algo )
470 {
471   if (algo < 0 || algo > 110)
472     return gpg_error (GPG_ERR_DIGEST_ALGO);
473   return gcry_md_test_algo (algo);
474 }
475
476 #ifdef USE_IDEA
477 /* Special warning for the IDEA cipher */
478 void
479 idea_cipher_warn(int show)
480 {
481   static int warned=0;
482
483   if(!warned || show)
484     {
485       log_info(_("the IDEA cipher plugin is not present\n"));
486       log_info(_("please see %s for more information\n"),
487                "http://www.gnupg.org/faq/why-not-idea.html");
488       warned=1;
489     }
490 }
491 #endif
492
493 static unsigned long get_signature_count(PKT_secret_key *sk)
494 {
495 #ifdef ENABLE_CARD_SUPPORT
496   if(sk && sk->is_protected && sk->protect.s2k.mode==1002)
497     {
498       struct agent_card_info_s info;
499       if(agent_scd_getattr("SIG-COUNTER",&info)==0)
500         return info.sig_counter;
501     }  
502 #endif
503
504   /* How to do this without a card? */
505
506   return 0;
507 }
508
509 /* Expand %-strings.  Returns a string which must be xfreed.  Returns
510    NULL if the string cannot be expanded (too large). */
511 char *
512 pct_expando(const char *string,struct expando_args *args)
513 {
514   const char *ch=string;
515   int idx=0,maxlen=0,done=0;
516   u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
517   char *ret=NULL;
518
519   if(args->pk)
520     keyid_from_pk(args->pk,pk_keyid);
521
522   if(args->sk)
523     keyid_from_sk(args->sk,sk_keyid);
524
525   /* This is used so that %k works in photoid command strings in
526      --list-secret-keys (which of course has a sk, but no pk). */
527   if(!args->pk && args->sk)
528     keyid_from_sk(args->sk,pk_keyid);
529
530   while(*ch!='\0')
531     {
532       char *str=NULL;
533
534       if(!done)
535         {
536           /* 8192 is way bigger than we'll need here */
537           if(maxlen>=8192)
538             goto fail;
539
540           maxlen+=1024;
541           ret=xrealloc(ret,maxlen);
542         }
543
544       done=0;
545
546       if(*ch=='%')
547         {
548           switch(*(ch+1))
549             {
550             case 's': /* short key id */
551               if(idx+8<maxlen)
552                 {
553                   sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
554                   idx+=8;
555                   done=1;
556                 }
557               break;
558
559             case 'S': /* long key id */
560               if(idx+16<maxlen)
561                 {
562                   sprintf(&ret[idx],"%08lX%08lX",
563                           (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
564                   idx+=16;
565                   done=1;
566                 }
567               break;
568
569             case 'k': /* short key id */
570               if(idx+8<maxlen)
571                 {
572                   sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
573                   idx+=8;
574                   done=1;
575                 }
576               break;
577
578             case 'K': /* long key id */
579               if(idx+16<maxlen)
580                 {
581                   sprintf(&ret[idx],"%08lX%08lX",
582                           (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
583                   idx+=16;
584                   done=1;
585                 }
586               break;
587
588             case 'c': /* signature count from card, if any. */
589               if(idx+10<maxlen)
590                 {
591                   sprintf(&ret[idx],"%lu",get_signature_count(args->sk));
592                   idx+=strlen(&ret[idx]);
593                   done=1;
594                 }             
595               break;
596
597             case 'p': /* primary pk fingerprint of a sk */
598             case 'f': /* pk fingerprint */
599             case 'g': /* sk fingerprint */
600               {
601                 byte array[MAX_FINGERPRINT_LEN];
602                 size_t len;
603                 int i;
604
605                 if((*(ch+1))=='p' && args->sk)
606                   {
607                     if(args->sk->is_primary)
608                       fingerprint_from_sk(args->sk,array,&len);
609                     else if(args->sk->main_keyid[0] || args->sk->main_keyid[1])
610                       {
611                         PKT_public_key *pk=
612                           xmalloc_clear(sizeof(PKT_public_key));
613
614                         if(get_pubkey_fast(pk,args->sk->main_keyid)==0)
615                           fingerprint_from_pk(pk,array,&len);
616                         else
617                           memset(array,0,(len=MAX_FINGERPRINT_LEN));
618                         free_public_key(pk);
619                       }
620                     else
621                       memset(array,0,(len=MAX_FINGERPRINT_LEN));
622                   }
623                 else if((*(ch+1))=='f' && args->pk)
624                   fingerprint_from_pk(args->pk,array,&len);
625                 else if((*(ch+1))=='g' && args->sk)
626                   fingerprint_from_sk(args->sk,array,&len);
627                 else
628                   memset(array,0,(len=MAX_FINGERPRINT_LEN));
629
630                 if(idx+(len*2)<maxlen)
631                   {
632                     for(i=0;i<len;i++)
633                       {
634                         sprintf(&ret[idx],"%02X",array[i]);
635                         idx+=2;
636                       }
637                     done=1;
638                   }
639               }
640               break;
641
642             case 't': /* e.g. "jpg" */
643               str=image_type_to_string(args->imagetype,0);
644               /* fall through */
645
646             case 'T': /* e.g. "image/jpeg" */
647               if(str==NULL)
648                 str=image_type_to_string(args->imagetype,2);
649
650               if(idx+strlen(str)<maxlen)
651                 {
652                   strcpy(&ret[idx],str);
653                   idx+=strlen(str);
654                   done=1;
655                 }
656               break;
657
658             case '%':
659               if(idx+1<maxlen)
660                 {
661                   ret[idx++]='%';
662                   ret[idx]='\0';
663                   done=1;
664                 }
665               break;
666
667               /* Any unknown %-keys (like %i, %o, %I, and %O) are
668                  passed through for later expansion.  Note this also
669                  handles the case where the last character in the
670                  string is a '%' - the terminating \0 will end up here
671                  and properly terminate the string. */
672             default:
673               if(idx+2<maxlen)
674                 {
675                   ret[idx++]='%';
676                   ret[idx++]=*(ch+1);
677                   ret[idx]='\0';
678                   done=1;
679                 }
680               break;
681               }
682
683           if(done)
684             ch++;
685         }
686       else
687         {
688           if(idx+1<maxlen)
689             {
690               ret[idx++]=*ch;
691               ret[idx]='\0';
692               done=1;
693             }
694         }
695
696       if(done)
697         ch++;
698     }
699
700   return ret;
701
702  fail:
703   xfree(ret);
704   return NULL;
705 }
706
707 void
708 deprecated_warning(const char *configname,unsigned int configlineno,
709                    const char *option,const char *repl1,const char *repl2)
710 {
711   if(configname)
712     {
713       if(strncmp("--",option,2)==0)
714         option+=2;
715
716       if(strncmp("--",repl1,2)==0)
717         repl1+=2;
718
719       log_info(_("%s:%d: deprecated option \"%s\"\n"),
720                configname,configlineno,option);
721     }
722   else
723     log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
724
725   log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
726 }
727
728
729 void
730 deprecated_command (const char *name)
731 {
732   log_info(_("WARNING: \"%s\" is a deprecated command - do not use it\n"),
733            name);
734 }
735
736
737 /*
738  * Wrapper around gcry_cipher_map_name to provide a fallback using the
739  * "Sn" syntax as used by the preference strings.
740  */
741 int 
742 string_to_cipher_algo (const char *string) 
743
744   int val;
745
746   val = gcry_cipher_map_name (string);
747   if (!val && string && (string[0]=='S' || string[0]=='s'))
748     {
749       char *endptr;
750
751       string++;
752       val = strtol (string, &endptr, 10);
753       if (!*string || *endptr || openpgp_cipher_test_algo (val))
754         val = 0;
755     }
756
757   return val;
758 }
759
760 /*
761  * Wrapper around gcry_md_map_name to provide a fallback using the
762  * "Hn" syntax as used by the preference strings.
763  */
764 int 
765 string_to_digest_algo (const char *string) 
766
767   int val;
768
769   val = gcry_md_map_name (string);
770   if (!val && string && (string[0]=='H' || string[0]=='h'))
771     {
772       char *endptr;
773
774       string++;
775       val = strtol (string, &endptr, 10);
776       if (!*string || *endptr || openpgp_md_test_algo (val))
777         val = 0;
778     }
779
780   return val;
781 }
782
783
784
785 const char *
786 compress_algo_to_string(int algo)
787 {
788   const char *s=NULL;
789
790   switch(algo)
791     {
792     case COMPRESS_ALGO_NONE:
793       s=_("Uncompressed");
794       break;
795
796     case COMPRESS_ALGO_ZIP:
797       s="ZIP";
798       break;
799
800     case COMPRESS_ALGO_ZLIB:
801       s="ZLIB";
802       break;
803
804 #ifdef HAVE_BZIP2
805     case COMPRESS_ALGO_BZIP2:
806       s="BZIP2";
807       break;
808 #endif
809     }
810
811   return s;
812 }
813
814 int
815 string_to_compress_algo(const char *string)
816 {
817   /* TRANSLATORS: See doc/TRANSLATE about this string. */
818   if(match_multistr(_("uncompressed|none"),string))
819     return 0;
820   else if(ascii_strcasecmp(string,"uncompressed")==0)
821     return 0;
822   else if(ascii_strcasecmp(string,"none")==0)
823     return 0;
824   else if(ascii_strcasecmp(string,"zip")==0)
825     return 1;
826   else if(ascii_strcasecmp(string,"zlib")==0)
827     return 2;
828 #ifdef HAVE_BZIP2
829   else if(ascii_strcasecmp(string,"bzip2")==0)
830     return 3;
831 #endif
832   else if(ascii_strcasecmp(string,"z0")==0)
833     return 0;
834   else if(ascii_strcasecmp(string,"z1")==0)
835     return 1;
836   else if(ascii_strcasecmp(string,"z2")==0)
837     return 2;
838 #ifdef HAVE_BZIP2
839   else if(ascii_strcasecmp(string,"z3")==0)
840     return 3;
841 #endif
842   else
843     return -1;
844 }
845
846 int
847 check_compress_algo(int algo)
848 {
849 #ifdef HAVE_BZIP2
850   if(algo>=0 && algo<=3)
851     return 0;
852 #else
853   if(algo>=0 && algo<=2)
854     return 0;
855 #endif
856
857   return G10ERR_COMPR_ALGO;
858 }
859
860 int
861 default_cipher_algo(void)
862 {
863   if(opt.def_cipher_algo)
864     return opt.def_cipher_algo;
865   else if(opt.personal_cipher_prefs)
866     return opt.personal_cipher_prefs[0].value;
867   else
868     return opt.s2k_cipher_algo;
869 }
870
871 /* There is no default_digest_algo function, but see
872    sign.c:hash_for() */
873
874 int
875 default_compress_algo(void)
876 {
877   if(opt.compress_algo!=-1)
878     return opt.compress_algo;
879   else if(opt.personal_compress_prefs)
880     return opt.personal_compress_prefs[0].value;
881   else
882     return DEFAULT_COMPRESS_ALGO;
883 }
884
885 const char *
886 compliance_option_string(void)
887 {
888   switch(opt.compliance)
889     {
890     case CO_RFC2440:
891       return "--openpgp";
892     case CO_PGP2:
893       return "--pgp2";
894     case CO_PGP6:
895       return "--pgp6";
896     case CO_PGP7:
897       return "--pgp7";
898     case CO_PGP8:
899       return "--pgp8";
900     default:
901       return "???";
902     }
903 }
904
905 static const char *
906 compliance_string(void)
907 {
908   switch(opt.compliance)
909     {
910     case CO_RFC2440:
911       return "OpenPGP";
912     case CO_PGP2:
913       return "PGP 2.x";
914     case CO_PGP6:
915       return "PGP 6.x";
916     case CO_PGP7:
917       return "PGP 7.x";
918     case CO_PGP8:
919       return "PGP 8.x";
920     default:
921       return "???";
922     }
923 }
924
925 void
926 compliance_failure(void)
927 {
928   log_info(_("this message may not be usable by %s\n"),compliance_string());
929   opt.compliance=CO_GNUPG;
930 }
931
932 /* Break a string into successive option pieces.  Accepts single word
933    options and key=value argument options. */
934 char *
935 optsep(char **stringp)
936 {
937   char *tok,*end;
938
939   tok=*stringp;
940   if(tok)
941     {
942       end=strpbrk(tok," ,=");
943       if(end)
944         {
945           int sawequals=0;
946           char *ptr=end;
947
948           /* what we need to do now is scan along starting with *end,
949              If the next character we see (ignoring spaces) is an =
950              sign, then there is an argument. */
951
952           while(*ptr)
953             {
954               if(*ptr=='=')
955                 sawequals=1;
956               else if(*ptr!=' ')
957                 break;
958               ptr++;
959             }
960
961           /* There is an argument, so grab that too.  At this point,
962              ptr points to the first character of the argument. */
963           if(sawequals)
964             {
965               /* Is it a quoted argument? */
966               if(*ptr=='"')
967                 {
968                   ptr++;
969                   end=strchr(ptr,'"');
970                   if(end)
971                     end++;
972                 }
973               else
974                 end=strpbrk(ptr," ,");
975             }
976
977           if(end && *end)
978             {
979               *end='\0';
980               *stringp=end+1;
981             }
982           else
983             *stringp=NULL;
984         }
985       else
986         *stringp=NULL;
987     }
988
989   return tok;
990 }
991
992 /* Breaks an option value into key and value.  Returns NULL if there
993    is no value.  Note that "string" is modified to remove the =value
994    part. */
995 char *
996 argsplit(char *string)
997 {
998   char *equals,*arg=NULL;
999
1000   equals=strchr(string,'=');
1001   if(equals)
1002     {
1003       char *quote,*space;
1004
1005       *equals='\0';
1006       arg=equals+1;
1007
1008       /* Quoted arg? */
1009       quote=strchr(arg,'"');
1010       if(quote)
1011         {
1012           arg=quote+1;
1013
1014           quote=strchr(arg,'"');
1015           if(quote)
1016             *quote='\0';
1017         }
1018       else
1019         {
1020           size_t spaces;
1021
1022           /* Trim leading spaces off of the arg */
1023           spaces=strspn(arg," ");
1024           arg+=spaces;
1025         }
1026
1027       /* Trim tailing spaces off of the tag */
1028       space=strchr(string,' ');
1029       if(space)
1030         *space='\0';
1031     }
1032
1033   return arg;
1034 }
1035
1036 /* Return the length of the initial token, leaving off any
1037    argument. */
1038 static size_t
1039 optlen(const char *s)
1040 {
1041   char *end=strpbrk(s," =");
1042
1043   if(end)
1044     return end-s;
1045   else
1046     return strlen(s);
1047 }
1048
1049 int
1050 parse_options(char *str,unsigned int *options,
1051               struct parse_options *opts,int noisy)
1052 {
1053   char *tok;
1054
1055   if (str && !strcmp (str, "help"))
1056     {
1057       int i,maxlen=0;
1058
1059       /* Figure out the longest option name so we can line these up
1060          neatly. */
1061       for(i=0;opts[i].name;i++)
1062         if(opts[i].help && maxlen<strlen(opts[i].name))
1063           maxlen=strlen(opts[i].name);
1064
1065       for(i=0;opts[i].name;i++)
1066         if(opts[i].help)
1067           printf("%s%*s%s\n",opts[i].name,
1068                  maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help));
1069
1070       g10_exit(0);
1071     }
1072
1073   while((tok=optsep(&str)))
1074     {
1075       int i,rev=0;
1076       char *otok=tok;
1077
1078       if(tok[0]=='\0')
1079         continue;
1080
1081       if(ascii_strncasecmp("no-",tok,3)==0)
1082         {
1083           rev=1;
1084           tok+=3;
1085         }
1086
1087       for(i=0;opts[i].name;i++)
1088         {
1089           size_t toklen=optlen(tok);
1090
1091           if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
1092             {
1093               /* We have a match, but it might be incomplete */
1094               if(toklen!=strlen(opts[i].name))
1095                 {
1096                   int j;
1097
1098                   for(j=i+1;opts[j].name;j++)
1099                     {
1100                       if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
1101                         {
1102                           if(noisy)
1103                             log_info(_("ambiguous option `%s'\n"),otok);
1104                           return 0;
1105                         }
1106                     }
1107                 }
1108
1109               if(rev)
1110                 {
1111                   *options&=~opts[i].bit;
1112                   if(opts[i].value)
1113                     *opts[i].value=NULL;
1114                 }
1115               else
1116                 {
1117                   *options|=opts[i].bit;
1118                   if(opts[i].value)
1119                     *opts[i].value=argsplit(tok);
1120                 }
1121               break;
1122             }
1123         }
1124
1125       if(!opts[i].name)
1126         {
1127           if(noisy)
1128             log_info(_("unknown option `%s'\n"),otok);
1129           return 0;
1130         }
1131     }
1132
1133   return 1;
1134 }
1135
1136
1137 /* Return a new malloced string by unescaping the string S.  Escaping
1138    is percent escaping and '+'/space mapping.  A binary nul will
1139    silently be replaced by a 0xFF. */
1140 char *
1141 unescape_percent_string (const unsigned char *s)
1142 {
1143   char *buffer, *d;
1144
1145   buffer = d = xmalloc (strlen (s)+1);
1146   while (*s)
1147     {
1148       if (*s == '%' && s[1] && s[2])
1149         { 
1150           s++;
1151           *d = xtoi_2 (s);
1152           if (!*d)
1153             *d = '\xff';
1154           d++;
1155           s += 2;
1156         }
1157       else if (*s == '+')
1158         {
1159           *d++ = ' ';
1160           s++;
1161         }
1162       else
1163         *d++ = *s++;
1164     }
1165   *d = 0; 
1166   return buffer;
1167 }
1168
1169
1170 int
1171 has_invalid_email_chars (const char *s)
1172 {
1173   int at_seen=0;
1174   const char *valid_chars=
1175     "01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1176
1177   for ( ; *s; s++ ) 
1178     {
1179       if ( *s & 0x80 )
1180         return 1;
1181       if ( *s == '@' )
1182         at_seen=1;
1183       else if ( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) )
1184         return 1;
1185       else if ( at_seen && !strchr( valid_chars, *s ) )
1186         return 1;
1187     }
1188   return 0;
1189 }
1190
1191
1192 /* Check whether NAME represents a valid mailbox according to
1193    RFC822. Returns true if so. */
1194 int
1195 is_valid_mailbox (const char *name)
1196 {
1197   return !( !name
1198             || !*name
1199             || has_invalid_email_chars (name)
1200             || string_count_chr (name,'@') != 1
1201             || *name == '@'
1202             || name[strlen(name)-1] == '@'
1203             || name[strlen(name)-1] == '.'
1204             || strstr (name, "..") );
1205 }
1206
1207
1208 /* This is a helper function to load a Windows function from either of
1209    one DLLs. */
1210 #ifdef HAVE_W32_SYSTEM
1211 static HRESULT
1212 w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
1213 {
1214   static int initialized;
1215   static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
1216
1217   if (!initialized)
1218     {
1219       static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
1220       void *handle;
1221       int i;
1222
1223       initialized = 1;
1224
1225       for (i=0, handle = NULL; !handle && dllnames[i]; i++)
1226         {
1227           handle = dlopen (dllnames[i], RTLD_LAZY);
1228           if (handle)
1229             {
1230               func = dlsym (handle, "SHGetFolderPathA");
1231               if (!func)
1232                 {
1233                   dlclose (handle);
1234                   handle = NULL;
1235                 }
1236             }
1237         }
1238     }
1239
1240   if (func)
1241     return func (a,b,c,d,e);
1242   else
1243     return -1;
1244 }
1245 #endif /*HAVE_W32_SYSTEM*/
1246
1247
1248 /* Return the name of the libexec directory.  The name is allocated in
1249    a static area on the first use.  This function won't fail. */
1250 const char *
1251 get_libexecdir (void)
1252 {
1253 #ifdef HAVE_W32_SYSTEM
1254   static int got_dir;
1255   static char dir[MAX_PATH+5];
1256
1257   if (!got_dir)
1258     {
1259       char *p;
1260
1261       if ( !GetModuleFileName ( NULL, dir, MAX_PATH) )
1262         {
1263           log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
1264           *dir = 0;
1265         }
1266       got_dir = 1;
1267       p = strrchr (dir, DIRSEP_C);
1268       if (p)
1269         *p = 0;
1270       else
1271         {
1272           log_debug ("bad filename `%s' returned for this process\n", dir);
1273           *dir = 0; 
1274         }
1275     }
1276
1277   if (*dir)
1278     return dir;
1279   /* Fallback to the hardwired value. */
1280 #endif /*HAVE_W32_SYSTEM*/
1281
1282   return GNUPG_LIBEXECDIR;
1283 }
1284
1285 /* Similar to access(2), but uses PATH to find the file. */
1286 int
1287 path_access(const char *file,int mode)
1288 {
1289   char *envpath;
1290   int ret=-1;
1291
1292   envpath=getenv("PATH");
1293
1294   if(!envpath
1295 #ifdef HAVE_DRIVE_LETTERS
1296      || (((file[0]>='A' && file[0]<='Z')
1297           || (file[0]>='a' && file[0]<='z'))
1298          && file[1]==':')
1299 #else
1300      || file[0]=='/'
1301 #endif
1302      )
1303     return access(file,mode);
1304   else
1305     {
1306       /* At least as large as, but most often larger than we need. */
1307       char *buffer=xmalloc(strlen(envpath)+1+strlen(file)+1);
1308       char *split,*item,*path=xstrdup(envpath);
1309
1310       split=path;
1311
1312       while((item=strsep(&split,PATHSEP_S)))
1313         {
1314           strcpy(buffer,item);
1315           strcat(buffer,"/");
1316           strcat(buffer,file);
1317           ret=access(buffer,mode);
1318           if(ret==0)
1319             break;
1320         }
1321
1322       xfree(path);
1323       xfree(buffer);
1324     }
1325
1326   return ret;
1327 }
1328
1329
1330 \f
1331 /* Temporary helper. */
1332 int
1333 pubkey_get_npkey( int algo )
1334 {
1335   size_t n;
1336
1337   if (algo == GCRY_PK_ELG_E)
1338     algo = GCRY_PK_ELG;
1339   if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &n))
1340     n = 0;
1341   return n;
1342 }
1343
1344 /* Temporary helper. */
1345 int
1346 pubkey_get_nskey( int algo )
1347 {
1348   size_t n;
1349
1350   if (algo == GCRY_PK_ELG_E)
1351     algo = GCRY_PK_ELG;
1352   if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &n ))
1353     n = 0;
1354   return n;
1355 }
1356
1357 /* Temporary helper. */
1358 int
1359 pubkey_get_nsig( int algo )
1360 {
1361   size_t n;
1362
1363   if (algo == GCRY_PK_ELG_E)
1364     algo = GCRY_PK_ELG;
1365   if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSIGN, NULL, &n))
1366     n = 0;
1367   return n;
1368 }
1369
1370 /* Temporary helper. */
1371 int
1372 pubkey_get_nenc( int algo )
1373 {
1374   size_t n;
1375   
1376   if (algo == GCRY_PK_ELG_E)
1377     algo = GCRY_PK_ELG;
1378   if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, &n ))
1379     n = 0;
1380   return n;
1381 }
1382
1383
1384 /* Temporary helper. */
1385 unsigned int
1386 pubkey_nbits( int algo, gcry_mpi_t *key )
1387 {
1388     int rc, nbits;
1389     gcry_sexp_t sexp;
1390
1391     if( algo == GCRY_PK_DSA ) {
1392         rc = gcry_sexp_build ( &sexp, NULL,
1393                               "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
1394                                   key[0], key[1], key[2], key[3] );
1395     }
1396     else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) {
1397         rc = gcry_sexp_build ( &sexp, NULL,
1398                               "(public-key(elg(p%m)(g%m)(y%m)))",
1399                                   key[0], key[1], key[2] );
1400     }
1401     else if( algo == GCRY_PK_RSA ) {
1402         rc = gcry_sexp_build ( &sexp, NULL,
1403                               "(public-key(rsa(n%m)(e%m)))",
1404                                   key[0], key[1] );
1405     }
1406     else
1407         return 0;
1408
1409     if ( rc )
1410         BUG ();
1411
1412     nbits = gcry_pk_get_nbits( sexp );
1413     gcry_sexp_release( sexp );
1414     return nbits;
1415 }
1416
1417
1418
1419 /* FIXME: Use gcry_mpi_print directly. */
1420 int
1421 mpi_print( FILE *fp, gcry_mpi_t a, int mode )
1422 {
1423     int n=0;
1424
1425     if( !a )
1426         return fprintf(fp, "[MPI_NULL]");
1427     if( !mode ) {
1428         unsigned int n1;
1429         n1 = gcry_mpi_get_nbits(a);
1430         n += fprintf(fp, "[%u bits]", n1);
1431     }
1432     else {
1433         unsigned char *buffer;
1434
1435         if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a))
1436           BUG ();
1437         fputs( buffer, fp );
1438         n += strlen(buffer);
1439         gcry_free( buffer );
1440     }
1441     return n;
1442 }
1443