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