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