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