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