Fixed yesterday's W32 fix.
[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   else if (algo == 20)
293     {
294       log_info (_("WARNING: Elgamal sign+encrypt keys are deprecated\n"));
295     }
296 }
297
298 void
299 print_cipher_algo_note( int algo )
300 {
301   if(algo >= 100 && algo <= 110)
302     {
303       static int warn=0;
304       if(!warn)
305         {
306           warn=1;
307           log_info (_("WARNING: using experimental cipher algorithm %s\n"),
308                     openpgp_cipher_algo_name (algo));
309         }
310     }
311 }
312
313 void
314 print_digest_algo_note( int algo )
315 {
316   if(algo >= 100 && algo <= 110)
317     {
318       static int warn=0;
319       if(!warn)
320         {
321           warn=1;
322           log_info (_("WARNING: using experimental digest algorithm %s\n"),
323                     gcry_md_algo_name (algo));
324         }
325     }
326   else if(algo==DIGEST_ALGO_MD5)
327     log_info (_("WARNING: digest algorithm %s is deprecated\n"),
328               gcry_md_algo_name (algo));
329 }
330
331
332 /* Map OpenPGP algo numbers to those used by Libgcrypt.  We need to do
333    this for algorithms we implemented in Libgcrypt after they become
334    part of OpenPGP.  */
335 static int
336 map_cipher_openpgp_to_gcry (int algo)
337 {
338   switch (algo)
339     {
340     case CIPHER_ALGO_CAMELLIA128: return 310; 
341     case CIPHER_ALGO_CAMELLIA256: return 312; 
342     default: return algo;
343     }
344 }
345
346 /* The inverse fucntion of above.  */
347 static int
348 map_cipher_gcry_to_openpgp (int algo)
349 {
350   switch (algo)
351     {
352     case 310: return CIPHER_ALGO_CAMELLIA128;
353     case 312: return CIPHER_ALGO_CAMELLIA256;
354     default: return algo;
355     }
356 }
357
358 /****************
359  * Wrapper around the libgcrypt function with additonal checks on
360  * the OpenPGP contraints for the algo ID.
361  */
362 int
363 openpgp_cipher_test_algo( int algo )
364 {
365   /* (5 and 6 are marked reserved by rfc4880.)  */
366   if ( algo < 0 || algo > 110 || algo == 5 || algo == 6 )
367     return gpg_error (GPG_ERR_CIPHER_ALGO);
368
369   /* Camellia is not yet defined for OpenPGP thus only allow it if
370      requested.  */
371 #ifndef USE_CAMELLIA
372   if (algo == CIPHER_ALGO_CAMELLIA128 
373        || algo == CIPHER_ALGO_CAMELLIA256)
374     return gpg_error (GPG_ERR_CIPHER_ALGO);
375 #endif
376
377   return gcry_cipher_test_algo (map_cipher_openpgp_to_gcry (algo));
378 }
379
380 /* Map the OpenPGP cipher algorithm whose ID is contained in ALGORITHM to a
381    string representation of the algorithm name.  For unknown algorithm
382    IDs this function returns "?".  */
383 const char *
384 openpgp_cipher_algo_name (int algo) 
385 {
386   return gcry_cipher_algo_name (map_cipher_openpgp_to_gcry (algo));
387 }
388
389
390
391 int
392 openpgp_pk_test_algo( int algo )
393 {
394   /* Dont't allow type 20 keys unless in rfc2440 mode.  */
395   if (!RFC2440 && algo == 20)
396     return gpg_error (GPG_ERR_PUBKEY_ALGO);
397     
398   if (algo == GCRY_PK_ELG_E)
399     algo = GCRY_PK_ELG;
400
401   if (algo < 0 || algo > 110)
402     return gpg_error (GPG_ERR_PUBKEY_ALGO);
403   return gcry_pk_test_algo (algo);
404 }
405
406 int
407 openpgp_pk_test_algo2( int algo, unsigned int use )
408 {
409   size_t use_buf = use;
410
411   /* Dont't allow type 20 keys unless in rfc2440 mode.  */
412   if (!RFC2440 && algo == 20)
413     return gpg_error (GPG_ERR_PUBKEY_ALGO);
414
415   if (algo == GCRY_PK_ELG_E)
416     algo = GCRY_PK_ELG;
417
418   if (algo < 0 || algo > 110)
419     return gpg_error (GPG_ERR_PUBKEY_ALGO);
420
421   return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, &use_buf);
422 }
423
424 int 
425 openpgp_pk_algo_usage ( int algo )
426 {
427     int use = 0; 
428     
429     /* They are hardwired in gpg 1.0. */
430     switch ( algo ) {    
431       case PUBKEY_ALGO_RSA:
432           use = (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG
433                  | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH);
434           break;
435       case PUBKEY_ALGO_RSA_E:
436           use = PUBKEY_USAGE_ENC;
437           break;
438       case PUBKEY_ALGO_RSA_S:
439           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG;
440           break;
441       case PUBKEY_ALGO_ELGAMAL:
442           if (RFC2440)
443              use = PUBKEY_USAGE_ENC;
444           break;
445       case PUBKEY_ALGO_ELGAMAL_E:
446           use = PUBKEY_USAGE_ENC;
447           break;
448       case PUBKEY_ALGO_DSA:  
449           use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
450           break;
451       default:
452           break;
453     }
454     return use;
455 }
456
457 int
458 openpgp_md_test_algo( int algo )
459 {
460   /* Note: If the list of actual supported OpenPGP algorithms changes,
461      make sure that our hard coded values at
462      print_status_begin_signing() gets updated. */
463   /* 4, 5, 6, 7 are defined by rfc2440 but will be removed from the
464      next revision of the standard.  */
465   if (algo < 0 || algo > 110 || (algo >= 4 && algo <= 7))
466     return gpg_error (GPG_ERR_DIGEST_ALGO);
467   return gcry_md_test_algo (algo);
468 }
469
470 #ifdef USE_IDEA
471 /* Special warning for the IDEA cipher */
472 void
473 idea_cipher_warn(int show)
474 {
475   static int warned=0;
476
477   if(!warned || show)
478     {
479       log_info(_("the IDEA cipher plugin is not present\n"));
480       log_info(_("please see %s for more information\n"),
481                "http://www.gnupg.org/faq/why-not-idea.html");
482       warned=1;
483     }
484 }
485 #endif
486
487
488 static unsigned long 
489 get_signature_count (PKT_secret_key *sk)
490 {
491 #ifdef ENABLE_CARD_SUPPORT
492   if(sk && sk->is_protected && sk->protect.s2k.mode==1002)
493     {
494       struct agent_card_info_s info;
495       if(agent_scd_getattr("SIG-COUNTER",&info)==0)
496         return info.sig_counter;
497     }  
498 #endif
499
500   /* How to do this without a card? */
501
502   return 0;
503 }
504
505 /* Expand %-strings.  Returns a string which must be xfreed.  Returns
506    NULL if the string cannot be expanded (too large). */
507 char *
508 pct_expando(const char *string,struct expando_args *args)
509 {
510   const char *ch=string;
511   int idx=0,maxlen=0,done=0;
512   u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
513   char *ret=NULL;
514
515   if(args->pk)
516     keyid_from_pk(args->pk,pk_keyid);
517
518   if(args->sk)
519     keyid_from_sk(args->sk,sk_keyid);
520
521   /* This is used so that %k works in photoid command strings in
522      --list-secret-keys (which of course has a sk, but no pk). */
523   if(!args->pk && args->sk)
524     keyid_from_sk(args->sk,pk_keyid);
525
526   while(*ch!='\0')
527     {
528       char *str=NULL;
529
530       if(!done)
531         {
532           /* 8192 is way bigger than we'll need here */
533           if(maxlen>=8192)
534             goto fail;
535
536           maxlen+=1024;
537           ret=xrealloc(ret,maxlen);
538         }
539
540       done=0;
541
542       if(*ch=='%')
543         {
544           switch(*(ch+1))
545             {
546             case 's': /* short key id */
547               if(idx+8<maxlen)
548                 {
549                   sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
550                   idx+=8;
551                   done=1;
552                 }
553               break;
554
555             case 'S': /* long key id */
556               if(idx+16<maxlen)
557                 {
558                   sprintf(&ret[idx],"%08lX%08lX",
559                           (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
560                   idx+=16;
561                   done=1;
562                 }
563               break;
564
565             case 'k': /* short key id */
566               if(idx+8<maxlen)
567                 {
568                   sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
569                   idx+=8;
570                   done=1;
571                 }
572               break;
573
574             case 'K': /* long key id */
575               if(idx+16<maxlen)
576                 {
577                   sprintf(&ret[idx],"%08lX%08lX",
578                           (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
579                   idx+=16;
580                   done=1;
581                 }
582               break;
583
584             case 'c': /* signature count from card, if any. */
585               if(idx+10<maxlen)
586                 {
587                   sprintf(&ret[idx],"%lu",get_signature_count(args->sk));
588                   idx+=strlen(&ret[idx]);
589                   done=1;
590                 }             
591               break;
592
593             case 'p': /* primary pk fingerprint of a sk */
594             case 'f': /* pk fingerprint */
595             case 'g': /* sk fingerprint */
596               {
597                 byte array[MAX_FINGERPRINT_LEN];
598                 size_t len;
599                 int i;
600
601                 if((*(ch+1))=='p' && args->sk)
602                   {
603                     if(args->sk->is_primary)
604                       fingerprint_from_sk(args->sk,array,&len);
605                     else if(args->sk->main_keyid[0] || args->sk->main_keyid[1])
606                       {
607                         PKT_public_key *pk=
608                           xmalloc_clear(sizeof(PKT_public_key));
609
610                         if(get_pubkey_fast(pk,args->sk->main_keyid)==0)
611                           fingerprint_from_pk(pk,array,&len);
612                         else
613                           memset(array,0,(len=MAX_FINGERPRINT_LEN));
614                         free_public_key(pk);
615                       }
616                     else
617                       memset(array,0,(len=MAX_FINGERPRINT_LEN));
618                   }
619                 else if((*(ch+1))=='f' && args->pk)
620                   fingerprint_from_pk(args->pk,array,&len);
621                 else if((*(ch+1))=='g' && args->sk)
622                   fingerprint_from_sk(args->sk,array,&len);
623                 else
624                   memset(array,0,(len=MAX_FINGERPRINT_LEN));
625
626                 if(idx+(len*2)<maxlen)
627                   {
628                     for(i=0;i<len;i++)
629                       {
630                         sprintf(&ret[idx],"%02X",array[i]);
631                         idx+=2;
632                       }
633                     done=1;
634                   }
635               }
636               break;
637
638             case 't': /* e.g. "jpg" */
639               str=image_type_to_string(args->imagetype,0);
640               /* fall through */
641
642             case 'T': /* e.g. "image/jpeg" */
643               if(str==NULL)
644                 str=image_type_to_string(args->imagetype,2);
645
646               if(idx+strlen(str)<maxlen)
647                 {
648                   strcpy(&ret[idx],str);
649                   idx+=strlen(str);
650                   done=1;
651                 }
652               break;
653
654             case '%':
655               if(idx+1<maxlen)
656                 {
657                   ret[idx++]='%';
658                   ret[idx]='\0';
659                   done=1;
660                 }
661               break;
662
663               /* Any unknown %-keys (like %i, %o, %I, and %O) are
664                  passed through for later expansion.  Note this also
665                  handles the case where the last character in the
666                  string is a '%' - the terminating \0 will end up here
667                  and properly terminate the string. */
668             default:
669               if(idx+2<maxlen)
670                 {
671                   ret[idx++]='%';
672                   ret[idx++]=*(ch+1);
673                   ret[idx]='\0';
674                   done=1;
675                 }
676               break;
677               }
678
679           if(done)
680             ch++;
681         }
682       else
683         {
684           if(idx+1<maxlen)
685             {
686               ret[idx++]=*ch;
687               ret[idx]='\0';
688               done=1;
689             }
690         }
691
692       if(done)
693         ch++;
694     }
695
696   return ret;
697
698  fail:
699   xfree(ret);
700   return NULL;
701 }
702
703 void
704 deprecated_warning(const char *configname,unsigned int configlineno,
705                    const char *option,const char *repl1,const char *repl2)
706 {
707   if(configname)
708     {
709       if(strncmp("--",option,2)==0)
710         option+=2;
711
712       if(strncmp("--",repl1,2)==0)
713         repl1+=2;
714
715       log_info(_("%s:%d: deprecated option \"%s\"\n"),
716                configname,configlineno,option);
717     }
718   else
719     log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
720
721   log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
722 }
723
724
725 void
726 deprecated_command (const char *name)
727 {
728   log_info(_("WARNING: \"%s\" is a deprecated command - do not use it\n"),
729            name);
730 }
731
732
733 void
734 obsolete_option (const char *configname, unsigned int configlineno, 
735                  const char *name)
736 {
737   if(configname)
738     log_info (_("%s:%u: obsolete option \"%s\" - it has no effect\n"),
739               configname, configlineno, name);
740   else
741     log_info (_("WARNING: \"%s\" is an obsolete option - it has no effect\n"),
742               name);
743 }
744
745
746 /*
747  * Wrapper around gcry_cipher_map_name to provide a fallback using the
748  * "Sn" syntax as used by the preference strings.
749  */
750 int 
751 string_to_cipher_algo (const char *string) 
752
753   int val;
754
755   val = map_cipher_gcry_to_openpgp (gcry_cipher_map_name (string));
756   if (!val && string && (string[0]=='S' || string[0]=='s'))
757     {
758       char *endptr;
759
760       string++;
761       val = strtol (string, &endptr, 10);
762       if (!*string || *endptr || openpgp_cipher_test_algo (val))
763         val = 0;
764     }
765
766   return val;
767 }
768
769 /*
770  * Wrapper around gcry_md_map_name to provide a fallback using the
771  * "Hn" syntax as used by the preference strings.
772  */
773 int 
774 string_to_digest_algo (const char *string) 
775
776   int val;
777
778   val = gcry_md_map_name (string);
779   if (!val && string && (string[0]=='H' || string[0]=='h'))
780     {
781       char *endptr;
782
783       string++;
784       val = strtol (string, &endptr, 10);
785       if (!*string || *endptr || openpgp_md_test_algo (val))
786         val = 0;
787     }
788
789   return val;
790 }
791
792
793
794 const char *
795 compress_algo_to_string(int algo)
796 {
797   const char *s=NULL;
798
799   switch(algo)
800     {
801     case COMPRESS_ALGO_NONE:
802       s=_("Uncompressed");
803       break;
804
805     case COMPRESS_ALGO_ZIP:
806       s="ZIP";
807       break;
808
809     case COMPRESS_ALGO_ZLIB:
810       s="ZLIB";
811       break;
812
813 #ifdef HAVE_BZIP2
814     case COMPRESS_ALGO_BZIP2:
815       s="BZIP2";
816       break;
817 #endif
818     }
819
820   return s;
821 }
822
823 int
824 string_to_compress_algo(const char *string)
825 {
826   /* TRANSLATORS: See doc/TRANSLATE about this string. */
827   if(match_multistr(_("uncompressed|none"),string))
828     return 0;
829   else if(ascii_strcasecmp(string,"uncompressed")==0)
830     return 0;
831   else if(ascii_strcasecmp(string,"none")==0)
832     return 0;
833   else if(ascii_strcasecmp(string,"zip")==0)
834     return 1;
835   else if(ascii_strcasecmp(string,"zlib")==0)
836     return 2;
837 #ifdef HAVE_BZIP2
838   else if(ascii_strcasecmp(string,"bzip2")==0)
839     return 3;
840 #endif
841   else if(ascii_strcasecmp(string,"z0")==0)
842     return 0;
843   else if(ascii_strcasecmp(string,"z1")==0)
844     return 1;
845   else if(ascii_strcasecmp(string,"z2")==0)
846     return 2;
847 #ifdef HAVE_BZIP2
848   else if(ascii_strcasecmp(string,"z3")==0)
849     return 3;
850 #endif
851   else
852     return -1;
853 }
854
855 int
856 check_compress_algo(int algo)
857 {
858 #ifdef HAVE_BZIP2
859   if(algo>=0 && algo<=3)
860     return 0;
861 #else
862   if(algo>=0 && algo<=2)
863     return 0;
864 #endif
865
866   return G10ERR_COMPR_ALGO;
867 }
868
869 int
870 default_cipher_algo(void)
871 {
872   if(opt.def_cipher_algo)
873     return opt.def_cipher_algo;
874   else if(opt.personal_cipher_prefs)
875     return opt.personal_cipher_prefs[0].value;
876   else
877     return opt.s2k_cipher_algo;
878 }
879
880 /* There is no default_digest_algo function, but see
881    sign.c:hash_for() */
882
883 int
884 default_compress_algo(void)
885 {
886   if(opt.compress_algo!=-1)
887     return opt.compress_algo;
888   else if(opt.personal_compress_prefs)
889     return opt.personal_compress_prefs[0].value;
890   else
891     return DEFAULT_COMPRESS_ALGO;
892 }
893
894 const char *
895 compliance_option_string(void)
896 {
897   char *ver="???";
898
899   switch(opt.compliance)
900     {
901     case CO_GNUPG:   return "--gnupg";
902     case CO_RFC4880: return "--openpgp";
903     case CO_RFC2440: return "--rfc2440";
904     case CO_RFC1991: return "--rfc1991";
905     case CO_PGP2:    return "--pgp2";
906     case CO_PGP6:    return "--pgp6";
907     case CO_PGP7:    return "--pgp7";
908     case CO_PGP8:    return "--pgp8";
909     }
910
911   return ver;
912 }
913
914 void
915 compliance_failure(void)
916 {
917   char *ver="???";
918
919   switch(opt.compliance)
920     {
921     case CO_GNUPG:
922       ver="GnuPG";
923       break;
924
925     case CO_RFC4880:
926       ver="OpenPGP";
927       break;
928
929     case CO_RFC2440:
930       ver="OpenPGP (older)";
931       break;
932
933     case CO_RFC1991:
934       ver="old PGP";
935       break;
936
937     case CO_PGP2:
938       ver="PGP 2.x";
939       break;
940
941     case CO_PGP6:
942       ver="PGP 6.x";
943       break;
944
945     case CO_PGP7:
946       ver="PGP 7.x";
947       break;
948
949     case CO_PGP8:
950       ver="PGP 8.x";
951       break;
952     }
953
954   log_info(_("this message may not be usable by %s\n"),ver);
955   opt.compliance=CO_GNUPG;
956 }
957
958 /* Break a string into successive option pieces.  Accepts single word
959    options and key=value argument options. */
960 char *
961 optsep(char **stringp)
962 {
963   char *tok,*end;
964
965   tok=*stringp;
966   if(tok)
967     {
968       end=strpbrk(tok," ,=");
969       if(end)
970         {
971           int sawequals=0;
972           char *ptr=end;
973
974           /* what we need to do now is scan along starting with *end,
975              If the next character we see (ignoring spaces) is an =
976              sign, then there is an argument. */
977
978           while(*ptr)
979             {
980               if(*ptr=='=')
981                 sawequals=1;
982               else if(*ptr!=' ')
983                 break;
984               ptr++;
985             }
986
987           /* There is an argument, so grab that too.  At this point,
988              ptr points to the first character of the argument. */
989           if(sawequals)
990             {
991               /* Is it a quoted argument? */
992               if(*ptr=='"')
993                 {
994                   ptr++;
995                   end=strchr(ptr,'"');
996                   if(end)
997                     end++;
998                 }
999               else
1000                 end=strpbrk(ptr," ,");
1001             }
1002
1003           if(end && *end)
1004             {
1005               *end='\0';
1006               *stringp=end+1;
1007             }
1008           else
1009             *stringp=NULL;
1010         }
1011       else
1012         *stringp=NULL;
1013     }
1014
1015   return tok;
1016 }
1017
1018 /* Breaks an option value into key and value.  Returns NULL if there
1019    is no value.  Note that "string" is modified to remove the =value
1020    part. */
1021 char *
1022 argsplit(char *string)
1023 {
1024   char *equals,*arg=NULL;
1025
1026   equals=strchr(string,'=');
1027   if(equals)
1028     {
1029       char *quote,*space;
1030
1031       *equals='\0';
1032       arg=equals+1;
1033
1034       /* Quoted arg? */
1035       quote=strchr(arg,'"');
1036       if(quote)
1037         {
1038           arg=quote+1;
1039
1040           quote=strchr(arg,'"');
1041           if(quote)
1042             *quote='\0';
1043         }
1044       else
1045         {
1046           size_t spaces;
1047
1048           /* Trim leading spaces off of the arg */
1049           spaces=strspn(arg," ");
1050           arg+=spaces;
1051         }
1052
1053       /* Trim tailing spaces off of the tag */
1054       space=strchr(string,' ');
1055       if(space)
1056         *space='\0';
1057     }
1058
1059   return arg;
1060 }
1061
1062 /* Return the length of the initial token, leaving off any
1063    argument. */
1064 static size_t
1065 optlen(const char *s)
1066 {
1067   char *end=strpbrk(s," =");
1068
1069   if(end)
1070     return end-s;
1071   else
1072     return strlen(s);
1073 }
1074
1075 int
1076 parse_options(char *str,unsigned int *options,
1077               struct parse_options *opts,int noisy)
1078 {
1079   char *tok;
1080
1081   if (str && !strcmp (str, "help"))
1082     {
1083       int i,maxlen=0;
1084
1085       /* Figure out the longest option name so we can line these up
1086          neatly. */
1087       for(i=0;opts[i].name;i++)
1088         if(opts[i].help && maxlen<strlen(opts[i].name))
1089           maxlen=strlen(opts[i].name);
1090
1091       for(i=0;opts[i].name;i++)
1092         if(opts[i].help)
1093           printf("%s%*s%s\n",opts[i].name,
1094                  maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help));
1095
1096       g10_exit(0);
1097     }
1098
1099   while((tok=optsep(&str)))
1100     {
1101       int i,rev=0;
1102       char *otok=tok;
1103
1104       if(tok[0]=='\0')
1105         continue;
1106
1107       if(ascii_strncasecmp("no-",tok,3)==0)
1108         {
1109           rev=1;
1110           tok+=3;
1111         }
1112
1113       for(i=0;opts[i].name;i++)
1114         {
1115           size_t toklen=optlen(tok);
1116
1117           if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
1118             {
1119               /* We have a match, but it might be incomplete */
1120               if(toklen!=strlen(opts[i].name))
1121                 {
1122                   int j;
1123
1124                   for(j=i+1;opts[j].name;j++)
1125                     {
1126                       if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
1127                         {
1128                           if(noisy)
1129                             log_info(_("ambiguous option `%s'\n"),otok);
1130                           return 0;
1131                         }
1132                     }
1133                 }
1134
1135               if(rev)
1136                 {
1137                   *options&=~opts[i].bit;
1138                   if(opts[i].value)
1139                     *opts[i].value=NULL;
1140                 }
1141               else
1142                 {
1143                   *options|=opts[i].bit;
1144                   if(opts[i].value)
1145                     *opts[i].value=argsplit(tok);
1146                 }
1147               break;
1148             }
1149         }
1150
1151       if(!opts[i].name)
1152         {
1153           if(noisy)
1154             log_info(_("unknown option `%s'\n"),otok);
1155           return 0;
1156         }
1157     }
1158
1159   return 1;
1160 }
1161
1162
1163 /* Return a new malloced string by unescaping the string S.  Escaping
1164    is percent escaping and '+'/space mapping.  A binary nul will
1165    silently be replaced by a 0xFF. */
1166 char *
1167 unescape_percent_string (const unsigned char *s)
1168 {
1169   char *buffer, *d;
1170
1171   buffer = d = xmalloc (strlen (s)+1);
1172   while (*s)
1173     {
1174       if (*s == '%' && s[1] && s[2])
1175         { 
1176           s++;
1177           *d = xtoi_2 (s);
1178           if (!*d)
1179             *d = '\xff';
1180           d++;
1181           s += 2;
1182         }
1183       else if (*s == '+')
1184         {
1185           *d++ = ' ';
1186           s++;
1187         }
1188       else
1189         *d++ = *s++;
1190     }
1191   *d = 0; 
1192   return buffer;
1193 }
1194
1195
1196 int
1197 has_invalid_email_chars (const char *s)
1198 {
1199   int at_seen=0;
1200   const char *valid_chars=
1201     "01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
1202
1203   for ( ; *s; s++ ) 
1204     {
1205       if ( *s & 0x80 )
1206         return 1;
1207       if ( *s == '@' )
1208         at_seen=1;
1209       else if ( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) )
1210         return 1;
1211       else if ( at_seen && !strchr( valid_chars, *s ) )
1212         return 1;
1213     }
1214   return 0;
1215 }
1216
1217
1218 /* Check whether NAME represents a valid mailbox according to
1219    RFC822. Returns true if so. */
1220 int
1221 is_valid_mailbox (const char *name)
1222 {
1223   return !( !name
1224             || !*name
1225             || has_invalid_email_chars (name)
1226             || string_count_chr (name,'@') != 1
1227             || *name == '@'
1228             || name[strlen(name)-1] == '@'
1229             || name[strlen(name)-1] == '.'
1230             || strstr (name, "..") );
1231 }
1232
1233
1234 /* Similar to access(2), but uses PATH to find the file. */
1235 int
1236 path_access(const char *file,int mode)
1237 {
1238   char *envpath;
1239   int ret=-1;
1240
1241   envpath=getenv("PATH");
1242
1243   if(!envpath
1244 #ifdef HAVE_DRIVE_LETTERS
1245      || (((file[0]>='A' && file[0]<='Z')
1246           || (file[0]>='a' && file[0]<='z'))
1247          && file[1]==':')
1248 #else
1249      || file[0]=='/'
1250 #endif
1251      )
1252     return access(file,mode);
1253   else
1254     {
1255       /* At least as large as, but most often larger than we need. */
1256       char *buffer=xmalloc(strlen(envpath)+1+strlen(file)+1);
1257       char *split,*item,*path=xstrdup(envpath);
1258
1259       split=path;
1260
1261       while((item=strsep(&split,PATHSEP_S)))
1262         {
1263           strcpy(buffer,item);
1264           strcat(buffer,"/");
1265           strcat(buffer,file);
1266           ret=access(buffer,mode);
1267           if(ret==0)
1268             break;
1269         }
1270
1271       xfree(path);
1272       xfree(buffer);
1273     }
1274
1275   return ret;
1276 }
1277
1278
1279 \f
1280 /* Temporary helper. */
1281 int
1282 pubkey_get_npkey( int algo )
1283 {
1284   size_t n;
1285
1286   if (algo == GCRY_PK_ELG_E)
1287     algo = GCRY_PK_ELG;
1288   if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NPKEY, NULL, &n))
1289     n = 0;
1290   return n;
1291 }
1292
1293 /* Temporary helper. */
1294 int
1295 pubkey_get_nskey( int algo )
1296 {
1297   size_t n;
1298
1299   if (algo == GCRY_PK_ELG_E)
1300     algo = GCRY_PK_ELG;
1301   if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSKEY, NULL, &n ))
1302     n = 0;
1303   return n;
1304 }
1305
1306 /* Temporary helper. */
1307 int
1308 pubkey_get_nsig( int algo )
1309 {
1310   size_t n;
1311
1312   if (algo == GCRY_PK_ELG_E)
1313     algo = GCRY_PK_ELG;
1314   if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSIGN, NULL, &n))
1315     n = 0;
1316   return n;
1317 }
1318
1319 /* Temporary helper. */
1320 int
1321 pubkey_get_nenc( int algo )
1322 {
1323   size_t n;
1324   
1325   if (algo == GCRY_PK_ELG_E)
1326     algo = GCRY_PK_ELG;
1327   if (gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, &n ))
1328     n = 0;
1329   return n;
1330 }
1331
1332
1333 /* Temporary helper. */
1334 unsigned int
1335 pubkey_nbits( int algo, gcry_mpi_t *key )
1336 {
1337     int rc, nbits;
1338     gcry_sexp_t sexp;
1339
1340     if( algo == GCRY_PK_DSA ) {
1341         rc = gcry_sexp_build ( &sexp, NULL,
1342                               "(public-key(dsa(p%m)(q%m)(g%m)(y%m)))",
1343                                   key[0], key[1], key[2], key[3] );
1344     }
1345     else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) {
1346         rc = gcry_sexp_build ( &sexp, NULL,
1347                               "(public-key(elg(p%m)(g%m)(y%m)))",
1348                                   key[0], key[1], key[2] );
1349     }
1350     else if( algo == GCRY_PK_RSA ) {
1351         rc = gcry_sexp_build ( &sexp, NULL,
1352                               "(public-key(rsa(n%m)(e%m)))",
1353                                   key[0], key[1] );
1354     }
1355     else
1356         return 0;
1357
1358     if ( rc )
1359         BUG ();
1360
1361     nbits = gcry_pk_get_nbits( sexp );
1362     gcry_sexp_release( sexp );
1363     return nbits;
1364 }
1365
1366
1367
1368 /* FIXME: Use gcry_mpi_print directly. */
1369 int
1370 mpi_print( FILE *fp, gcry_mpi_t a, int mode )
1371 {
1372     int n=0;
1373
1374     if( !a )
1375         return fprintf(fp, "[MPI_NULL]");
1376     if( !mode ) {
1377         unsigned int n1;
1378         n1 = gcry_mpi_get_nbits(a);
1379         n += fprintf(fp, "[%u bits]", n1);
1380     }
1381     else {
1382         unsigned char *buffer;
1383
1384         if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a))
1385           BUG ();
1386         fputs( buffer, fp );
1387         n += strlen(buffer);
1388         gcry_free( buffer );
1389     }
1390     return n;
1391 }
1392