* misc.c (optsep): Add the ability to understand keyword="quoted arg with
[gnupg.git] / g10 / misc.c
1 /* misc.c -  miscellaneous functions
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003,
3  *               2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
29 #include <asm/sysinfo.h>
30 #include <asm/unistd.h>
31 #endif
32 #ifdef HAVE_SETRLIMIT
33 #include <time.h>
34 #include <sys/time.h>
35 #include <sys/resource.h>
36 #endif
37 #include "util.h"
38 #include "main.h"
39 #include "photoid.h"
40 #include "options.h"
41 #include "i18n.h"
42
43 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
44 static int
45 setsysinfo(unsigned long op, void *buffer, unsigned long size,
46                      int *start, void *arg, unsigned long flag)
47 {
48     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
49 }
50
51 void
52 trap_unaligned(void)
53 {
54     unsigned int buf[2];
55
56     buf[0] = SSIN_UACPROC;
57     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
58     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
59 }
60 #else
61 void
62 trap_unaligned(void)
63 {  /* dummy */
64 }
65 #endif
66
67
68 int
69 disable_core_dumps()
70 {
71 #ifdef HAVE_DOSISH_SYSTEM
72     return 0;
73 #else
74 #ifdef HAVE_SETRLIMIT
75     struct rlimit limit;
76
77     limit.rlim_cur = 0;
78     limit.rlim_max = 0;
79     if( !setrlimit( RLIMIT_CORE, &limit ) )
80         return 0;
81     if( errno != EINVAL && errno != ENOSYS )
82         log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
83 #endif
84     return 1;
85 #endif
86 }
87
88
89
90 u16
91 checksum_u16( unsigned n )
92 {
93     u16 a;
94
95     a  = (n >> 8) & 0xff;
96     a += n & 0xff;
97     return a;
98 }
99
100
101 u16
102 checksum( byte *p, unsigned n )
103 {
104     u16 a;
105
106     for(a=0; n; n-- )
107         a += *p++;
108     return a;
109 }
110
111 u16
112 checksum_mpi( MPI a )
113 {
114     u16 csum;
115     byte *buffer;
116     unsigned nbytes;
117     unsigned nbits;
118
119     buffer = mpi_get_buffer( a, &nbytes, NULL );
120     nbits = mpi_get_nbits(a);
121     csum = checksum_u16( nbits );
122     csum += checksum( buffer, nbytes );
123     m_free( buffer );
124     return csum;
125 }
126
127 u32
128 buffer_to_u32( const byte *buffer )
129 {
130     unsigned long a;
131     a =  *buffer << 24;
132     a |= buffer[1] << 16;
133     a |= buffer[2] << 8;
134     a |= buffer[3];
135     return a;
136 }
137
138
139 static void
140 no_exp_algo(void)
141 {
142     static int did_note = 0;
143
144     if( !did_note ) {
145         did_note = 1;
146         log_info(_("Experimental algorithms should not be used!\n"));
147     }
148 }
149
150 void
151 print_pubkey_algo_note( int algo )
152 {
153     if( algo >= 100 && algo <= 110 )
154         no_exp_algo();
155 }
156
157 void
158 print_cipher_algo_note( int algo )
159 {
160     if( algo >= 100 && algo <= 110 )
161         no_exp_algo();
162     else if(    algo == CIPHER_ALGO_3DES
163              || algo == CIPHER_ALGO_CAST5
164              || algo == CIPHER_ALGO_BLOWFISH
165              || algo == CIPHER_ALGO_TWOFISH
166              || algo == CIPHER_ALGO_AES
167              || algo == CIPHER_ALGO_AES192
168              || algo == CIPHER_ALGO_AES256
169            )
170         ;
171     else {
172         static int did_note = 0;
173
174         if( !did_note ) {
175             did_note = 1;
176             log_info(_("this cipher algorithm is deprecated; "
177                        "please use a more standard one!\n"));
178         }
179     }
180 }
181
182 void
183 print_digest_algo_note( int algo )
184 {
185     if( algo >= 100 && algo <= 110 )
186         no_exp_algo();
187 }
188
189
190 /* Return a string which is used as a kind of process ID */
191 const byte *
192 get_session_marker( size_t *rlen )
193 {
194     static byte marker[SIZEOF_UNSIGNED_LONG*2];
195     static int initialized;
196
197     if ( !initialized ) {
198         volatile ulong aa, bb; /* we really want the uninitialized value */
199         ulong a, b;
200
201         initialized = 1;
202         /* also this marker is guessable it is not easy to use this 
203          * for a faked control packet because an attacker does not
204          * have enough control about the time the verification does 
205          * take place.  Of course, we can add just more random but 
206          * than we need the random generator even for verification
207          * tasks - which does not make sense. */
208         a = aa ^ (ulong)getpid();
209         b = bb ^ (ulong)time(NULL);
210         memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
211         memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
212     }
213     *rlen = sizeof(marker);
214     return marker;
215 }
216
217 /****************
218  * Wrapper around the libgcrypt function with addional checks on
219  * openPGP contraints for the algo ID.
220  */
221 int
222 openpgp_cipher_test_algo( int algo )
223 {
224     if( algo < 0 || algo > 110 )
225         return G10ERR_CIPHER_ALGO;
226     return check_cipher_algo(algo);
227 }
228
229 int
230 openpgp_pk_test_algo( int algo, unsigned int usage_flags )
231 {
232     if( algo < 0 || algo > 110 )
233         return G10ERR_PUBKEY_ALGO;
234     return check_pubkey_algo2( algo, usage_flags );
235 }
236
237 int 
238 openpgp_pk_algo_usage ( int algo )
239 {
240     int use = 0; 
241     
242     /* they are hardwired in gpg 1.0 */
243     switch ( algo ) {    
244       case PUBKEY_ALGO_RSA:
245           use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
246           break;
247       case PUBKEY_ALGO_RSA_E:
248           use = PUBKEY_USAGE_ENC;
249           break;
250       case PUBKEY_ALGO_RSA_S:
251           use = PUBKEY_USAGE_SIG;
252           break;
253       case PUBKEY_ALGO_ELGAMAL_E:
254           use = PUBKEY_USAGE_ENC;
255           break;
256       case PUBKEY_ALGO_DSA:  
257           use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
258           break;
259       default:
260           break;
261     }
262     return use;
263 }
264
265 int
266 openpgp_md_test_algo( int algo )
267 {
268     if( algo < 0 || algo > 110 )
269         return G10ERR_DIGEST_ALGO;
270     return check_digest_algo(algo);
271 }
272
273 #ifdef USE_IDEA
274 /* Special warning for the IDEA cipher */
275 void
276 idea_cipher_warn(int show)
277 {
278   static int warned=0;
279
280   if(!warned || show)
281     {
282       log_info(_("the IDEA cipher plugin is not present\n"));
283       log_info(_("please see http://www.gnupg.org/why-not-idea.html "
284                  "for more information\n"));
285       warned=1;
286     }
287 }
288 #endif
289
290 /* Expand %-strings.  Returns a string which must be m_freed.  Returns
291    NULL if the string cannot be expanded (too large). */
292 char *
293 pct_expando(const char *string,struct expando_args *args)
294 {
295   const char *ch=string;
296   int idx=0,maxlen=0,done=0;
297   u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
298   char *ret=NULL;
299
300   if(args->pk)
301     keyid_from_pk(args->pk,pk_keyid);
302
303   if(args->sk)
304     keyid_from_sk(args->sk,sk_keyid);
305
306   /* This is used so that %k works in photoid command strings in
307      --list-secret-keys (which of course has a sk, but no pk). */
308   if(!args->pk && args->sk)
309     keyid_from_sk(args->sk,pk_keyid);
310
311   while(*ch!='\0')
312     {
313       char *str=NULL;
314
315       if(!done)
316         {
317           /* 8192 is way bigger than we'll need here */
318           if(maxlen>=8192)
319             goto fail;
320
321           maxlen+=1024;
322           ret=m_realloc(ret,maxlen);
323         }
324
325       done=0;
326
327       if(*ch=='%')
328         {
329           switch(*(ch+1))
330             {
331             case 's': /* short key id */
332               if(idx+8<maxlen)
333                 {
334                   sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
335                   idx+=8;
336                   done=1;
337                 }
338               break;
339
340             case 'S': /* long key id */
341               if(idx+16<maxlen)
342                 {
343                   sprintf(&ret[idx],"%08lX%08lX",
344                           (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
345                   idx+=16;
346                   done=1;
347                 }
348               break;
349
350             case 'k': /* short key id */
351               if(idx+8<maxlen)
352                 {
353                   sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
354                   idx+=8;
355                   done=1;
356                 }
357               break;
358
359             case 'K': /* long key id */
360               if(idx+16<maxlen)
361                 {
362                   sprintf(&ret[idx],"%08lX%08lX",
363                           (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
364                   idx+=16;
365                   done=1;
366                 }
367               break;
368
369             case 'p': /* primary pk fingerprint of a sk */
370             case 'f': /* pk fingerprint */
371             case 'g': /* sk fingerprint */
372               {
373                 byte array[MAX_FINGERPRINT_LEN];
374                 size_t len;
375                 int i;
376
377                 if((*(ch+1))=='p' && args->sk)
378                   {
379                     if(args->sk->is_primary)
380                       fingerprint_from_sk(args->sk,array,&len);
381                     else if(args->sk->main_keyid[0] || args->sk->main_keyid[1])
382                       {
383                         PKT_public_key *pk=
384                           m_alloc_clear(sizeof(PKT_public_key));
385
386                         if(get_pubkey_fast(pk,args->sk->main_keyid)==0)
387                           fingerprint_from_pk(pk,array,&len);
388                         else
389                           memset(array,0,(len=MAX_FINGERPRINT_LEN));
390                         free_public_key(pk);
391                       }
392                     else
393                       memset(array,0,(len=MAX_FINGERPRINT_LEN));
394                   }
395                 else if((*(ch+1))=='f' && args->pk)
396                   fingerprint_from_pk(args->pk,array,&len);
397                 else if((*(ch+1))=='g' && args->sk)
398                   fingerprint_from_sk(args->sk,array,&len);
399                 else
400                   memset(array,0,(len=MAX_FINGERPRINT_LEN));
401
402                 if(idx+(len*2)<maxlen)
403                   {
404                     for(i=0;i<len;i++)
405                       {
406                         sprintf(&ret[idx],"%02X",array[i]);
407                         idx+=2;
408                       }
409                     done=1;
410                   }
411               }
412               break;
413
414             case 't': /* e.g. "jpg" */
415               str=image_type_to_string(args->imagetype,0);
416               /* fall through */
417
418             case 'T': /* e.g. "image/jpeg" */
419               if(str==NULL)
420                 str=image_type_to_string(args->imagetype,2);
421
422               if(idx+strlen(str)<maxlen)
423                 {
424                   strcpy(&ret[idx],str);
425                   idx+=strlen(str);
426                   done=1;
427                 }
428               break;
429
430             case '%':
431               if(idx+1<maxlen)
432                 {
433                   ret[idx++]='%';
434                   ret[idx]='\0';
435                   done=1;
436                 }
437               break;
438
439               /* Any unknown %-keys (like %i, %o, %I, and %O) are
440                  passed through for later expansion.  Note this also
441                  handles the case where the last character in the
442                  string is a '%' - the terminating \0 will end up here
443                  and properly terminate the string. */
444             default:
445               if(idx+2<maxlen)
446                 {
447                   ret[idx++]='%';
448                   ret[idx++]=*(ch+1);
449                   ret[idx]='\0';
450                   done=1;
451                 }
452               break;
453               }
454
455           if(done)
456             ch++;
457         }
458       else
459         {
460           if(idx+1<maxlen)
461             {
462               ret[idx++]=*ch;
463               ret[idx]='\0';
464               done=1;
465             }
466         }
467
468       if(done)
469         ch++;
470     }
471
472   return ret;
473
474  fail:
475   m_free(ret);
476   return NULL;
477 }
478
479 void
480 deprecated_warning(const char *configname,unsigned int configlineno,
481                    const char *option,const char *repl1,const char *repl2)
482 {
483   if(configname)
484     {
485       if(strncmp("--",option,2)==0)
486         option+=2;
487
488       if(strncmp("--",repl1,2)==0)
489         repl1+=2;
490
491       log_info(_("%s:%d: deprecated option \"%s\"\n"),
492                configname,configlineno,option);
493     }
494   else
495     log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
496
497   log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
498 }
499
500 const char *
501 compress_algo_to_string(int algo)
502 {
503   const char *s=NULL;
504
505   switch(algo)
506     {
507     case COMPRESS_ALGO_NONE:
508       s=_("Uncompressed");
509       break;
510
511     case COMPRESS_ALGO_ZIP:
512       s="ZIP";
513       break;
514
515     case COMPRESS_ALGO_ZLIB:
516       s="ZLIB";
517       break;
518
519 #ifdef HAVE_BZIP2
520     case COMPRESS_ALGO_BZIP2:
521       s="BZIP2";
522       break;
523 #endif
524     }
525
526   return s;
527 }
528
529 int
530 string_to_compress_algo(const char *string)
531 {
532   /* NOTE TO TRANSLATOR: See doc/TRANSLATE about this string. */
533   if(match_multistr(_("uncompressed|none"),string))
534     return 0;
535   else if(ascii_strcasecmp(string,"uncompressed")==0)
536     return 0;
537   else if(ascii_strcasecmp(string,"none")==0)
538     return 0;
539   else if(ascii_strcasecmp(string,"zip")==0)
540     return 1;
541   else if(ascii_strcasecmp(string,"zlib")==0)
542     return 2;
543 #ifdef HAVE_BZIP2
544   else if(ascii_strcasecmp(string,"bzip2")==0)
545     return 3;
546 #endif
547   else if(ascii_strcasecmp(string,"z0")==0)
548     return 0;
549   else if(ascii_strcasecmp(string,"z1")==0)
550     return 1;
551   else if(ascii_strcasecmp(string,"z2")==0)
552     return 2;
553 #ifdef HAVE_BZIP2
554   else if(ascii_strcasecmp(string,"z3")==0)
555     return 3;
556 #endif
557   else
558     return -1;
559 }
560
561 int
562 check_compress_algo(int algo)
563 {
564 #ifdef HAVE_BZIP2
565   if(algo>=0 && algo<=3)
566     return 0;
567 #else
568   if(algo>=0 && algo<=2)
569     return 0;
570 #endif
571
572   return G10ERR_COMPR_ALGO;
573 }
574
575 int
576 default_cipher_algo(void)
577 {
578   if(opt.def_cipher_algo)
579     return opt.def_cipher_algo;
580   else if(opt.personal_cipher_prefs)
581     return opt.personal_cipher_prefs[0].value;
582   else
583     return opt.s2k_cipher_algo;
584 }
585
586 /* There is no default_digest_algo function, but see
587    sign.c:hash_for() */
588
589 int
590 default_compress_algo(void)
591 {
592   if(opt.compress_algo!=-1)
593     return opt.compress_algo;
594   else if(opt.personal_compress_prefs)
595     return opt.personal_compress_prefs[0].value;
596   else
597     return DEFAULT_COMPRESS_ALGO;
598 }
599
600 const char *
601 compliance_option_string(void)
602 {
603   switch(opt.compliance)
604     {
605     case CO_RFC2440:
606       return "--openpgp";
607     case CO_PGP2:
608       return "--pgp2";
609     case CO_PGP6:
610       return "--pgp6";
611     case CO_PGP7:
612       return "--pgp7";
613     case CO_PGP8:
614       return "--pgp8";
615     default:
616       return "???";
617     }
618 }
619
620 static const char *
621 compliance_string(void)
622 {
623   switch(opt.compliance)
624     {
625     case CO_RFC2440:
626       return "OpenPGP";
627     case CO_PGP2:
628       return "PGP 2.x";
629     case CO_PGP6:
630       return "PGP 6.x";
631     case CO_PGP7:
632       return "PGP 7.x";
633     case CO_PGP8:
634       return "PGP 8.x";
635     default:
636       return "???";
637     }
638 }
639
640 void
641 compliance_failure(void)
642 {
643   log_info(_("this message may not be usable by %s\n"),compliance_string());
644   opt.compliance=CO_GNUPG;
645 }
646
647 /* Break a string into successive option pieces.  Accepts single word
648    options and key=value argument options. */
649 char *
650 optsep(char **stringp)
651 {
652   char *tok,*end;
653
654   tok=*stringp;
655   if(tok)
656     {
657       end=strpbrk(tok," ,=");
658       if(end)
659         {
660           int sawequals=0;
661           char *ptr=end;
662
663           /* what we need to do now is scan along starting with *end,
664              If the next character we see (ignoring spaces) is an =
665              sign, then there is an argument. */
666
667           while(*ptr)
668             {
669               if(*ptr=='=')
670                 sawequals=1;
671               else if(*ptr!=' ')
672                 break;
673               ptr++;
674             }
675
676           /* There is an argument, so grab that too.  At this point,
677              ptr points to the first character of the argument. */
678           if(sawequals)
679             {
680               /* Is it a quoted argument? */
681               if(*ptr=='"')
682                 {
683                   ptr++;
684                   end=strchr(ptr,'"');
685                   if(end)
686                     end++;
687                 }
688               else
689                 end=strpbrk(ptr," ,");
690             }
691
692           if(end && *end)
693             {
694               *end='\0';
695               *stringp=end+1;
696             }
697           else
698             *stringp=NULL;
699         }
700       else
701         *stringp=NULL;
702     }
703
704   return tok;
705 }
706
707 /* Breaks an option value into key and value.  Returns NULL if there
708    is no value.  Note that "string" is modified to remove the =value
709    part. */
710 char *
711 argsplit(char *string)
712 {
713   char *equals,*arg=NULL;
714
715   equals=strchr(string,'=');
716   if(equals)
717     {
718       char *space;
719
720       space=strchr(string,' ');
721       if(space)
722         {
723           *space='\0';
724           arg=space+1;
725         }
726       else
727         {
728           *equals='\0';
729           arg=equals+1;
730         }
731
732       space=strrchr(arg,' ');
733       if(space)
734         arg=space+1;
735     }
736
737   return arg;
738 }
739
740 /* Return the length of the initial token, leaving off any
741    argument. */
742 static size_t
743 optlen(const char *s)
744 {
745   char *end=strpbrk(s," =");
746
747   if(end)
748     return end-s;
749   else
750     return strlen(s);
751 }
752
753 int
754 parse_options(char *str,unsigned int *options,
755               struct parse_options *opts,int noisy)
756 {
757   char *tok;
758
759   while((tok=optsep(&str)))
760     {
761       int i,rev=0;
762       char *otok=tok;
763
764       if(tok[0]=='\0')
765         continue;
766
767       if(ascii_strncasecmp("no-",tok,3)==0)
768         {
769           rev=1;
770           tok+=3;
771         }
772
773       for(i=0;opts[i].name;i++)
774         {
775           size_t toklen=optlen(tok);
776
777           if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
778             {
779               /* We have a match, but it might be incomplete */
780               if(toklen!=strlen(opts[i].name))
781                 {
782                   int j;
783
784                   for(j=i+1;opts[j].name;j++)
785                     {
786                       if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
787                         {
788                           if(noisy)
789                             log_info(_("ambiguous option `%s'\n"),otok);
790                           return 0;
791                         }
792                     }
793                 }
794
795               if(rev)
796                 {
797                   *options&=~opts[i].bit;
798                   if(opts[i].value)
799                     *opts[i].value=NULL;
800                 }
801               else
802                 {
803                   *options|=opts[i].bit;
804                   if(opts[i].value)
805                     *opts[i].value=argsplit(tok);
806                 }
807               break;
808             }
809         }
810
811       if(!opts[i].name)
812         {
813           if(noisy)
814             log_info(_("unknown option `%s'\n"),otok);
815           return 0;
816         }
817     }
818
819   return 1;
820 }