Forgot to commit this:
[gnupg.git] / g10 / misc.c
1 /* misc.c -  miscellaneous functions
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <errno.h>
27 #ifdef HAVE_STAT
28 #include <sys/stat.h>
29 #endif
30 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
31   #include <asm/sysinfo.h>
32   #include <asm/unistd.h>
33 #endif
34 #ifdef HAVE_SETRLIMIT
35   #include <time.h>
36   #include <sys/time.h>
37   #include <sys/resource.h>
38 #endif
39 #include "util.h"
40 #include "main.h"
41 #include "photoid.h"
42 #include "options.h"
43 #include "i18n.h"
44
45
46 const char *g10m_revision_string(int);
47 const char *g10c_revision_string(int);
48 const char *g10u_revision_string(int);
49
50 #ifdef __GNUC__
51 volatile
52 #endif
53          void
54 pull_in_libs(void)
55 {
56     g10m_revision_string(0);
57     g10c_revision_string(0);
58     g10u_revision_string(0);
59 }
60
61
62 #if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
63 static int
64 setsysinfo(unsigned long op, void *buffer, unsigned long size,
65                      int *start, void *arg, unsigned long flag)
66 {
67     return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
68 }
69
70 void
71 trap_unaligned(void)
72 {
73     unsigned int buf[2];
74
75     buf[0] = SSIN_UACPROC;
76     buf[1] = UAC_SIGBUS | UAC_NOPRINT;
77     setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
78 }
79 #else
80 void
81 trap_unaligned(void)
82 {  /* dummy */
83 }
84 #endif
85
86
87 int
88 disable_core_dumps()
89 {
90  #ifdef HAVE_DOSISH_SYSTEM
91     return 0;
92  #else
93   #ifdef HAVE_SETRLIMIT
94     struct rlimit limit;
95
96     limit.rlim_cur = 0;
97     limit.rlim_max = 0;
98     if( !setrlimit( RLIMIT_CORE, &limit ) )
99         return 0;
100     if( errno != EINVAL && errno != ENOSYS )
101         log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
102   #endif
103     return 1;
104  #endif
105 }
106
107
108
109 u16
110 checksum_u16( unsigned n )
111 {
112     u16 a;
113
114     a  = (n >> 8) & 0xff;
115     if( opt.emulate_bugs & EMUBUG_GPGCHKSUM ) {
116        a |= n & 0xff;
117        log_debug("csum_u16 emulated for n=%u\n", n);
118     }
119     else
120        a += n & 0xff;
121     return a;
122 }
123
124 static u16
125 checksum_u16_nobug( unsigned n )
126 {
127     u16 a;
128
129     a  = (n >> 8) & 0xff;
130     a += n & 0xff;
131     return a;
132 }
133
134 u16
135 checksum( byte *p, unsigned n )
136 {
137     u16 a;
138
139     for(a=0; n; n-- )
140         a += *p++;
141     return a;
142 }
143
144 u16
145 checksum_mpi( MPI a )
146 {
147     u16 csum;
148     byte *buffer;
149     unsigned nbytes;
150     unsigned nbits;
151
152     buffer = mpi_get_buffer( a, &nbytes, NULL );
153     /* some versions of gpg encode wrong values for the length of an mpi
154      * so that mpi_get_nbits() which counts the mpi yields another (shorter)
155      * value than the one store with the mpi.  mpi_get_nbit_info() returns
156      * this stored value if it is still available.
157      */
158
159     if( opt.emulate_bugs & EMUBUG_GPGCHKSUM )
160         nbits = 0;
161     else
162         nbits = mpi_get_nbit_info(a);
163     if( !nbits )
164        nbits = mpi_get_nbits(a);
165     csum = checksum_u16( nbits );
166     csum += checksum( buffer, nbytes );
167     m_free( buffer );
168     return csum;
169 }
170
171 /****************
172  * This is the correct function
173  */
174 u16
175 checksum_mpi_counted_nbits( MPI a )
176 {
177     u16 csum;
178     byte *buffer;
179     unsigned nbytes;
180     unsigned nbits;
181
182     buffer = mpi_get_buffer( a, &nbytes, NULL );
183     nbits = mpi_get_nbits(a);
184     mpi_set_nbit_info(a,nbits);
185     csum = checksum_u16_nobug( nbits );
186     csum += checksum( buffer, nbytes );
187     m_free( buffer );
188     return csum;
189 }
190
191
192 u32
193 buffer_to_u32( const byte *buffer )
194 {
195     unsigned long a;
196     a =  *buffer << 24;
197     a |= buffer[1] << 16;
198     a |= buffer[2] << 8;
199     a |= buffer[3];
200     return a;
201 }
202
203
204 static void
205 no_exp_algo(void)
206 {
207     static int did_note = 0;
208
209     if( !did_note ) {
210         did_note = 1;
211         log_info(_("Experimental algorithms should not be used!\n"));
212     }
213 }
214
215 void
216 print_pubkey_algo_note( int algo )
217 {
218     if( algo >= 100 && algo <= 110 )
219         no_exp_algo();
220 }
221
222 void
223 print_cipher_algo_note( int algo )
224 {
225     if( algo >= 100 && algo <= 110 )
226         no_exp_algo();
227     else if(    algo == CIPHER_ALGO_3DES
228              || algo == CIPHER_ALGO_CAST5
229              || algo == CIPHER_ALGO_BLOWFISH
230              || algo == CIPHER_ALGO_TWOFISH
231              || algo == CIPHER_ALGO_RIJNDAEL
232              || algo == CIPHER_ALGO_RIJNDAEL192
233              || algo == CIPHER_ALGO_RIJNDAEL256
234            )
235         ;
236     else {
237         static int did_note = 0;
238
239         if( !did_note ) {
240             did_note = 1;
241             log_info(_("this cipher algorithm is deprecated; "
242                        "please use a more standard one!\n"));
243         }
244     }
245 }
246
247 void
248 print_digest_algo_note( int algo )
249 {
250     if( algo >= 100 && algo <= 110 )
251         no_exp_algo();
252 }
253
254
255 /* Return a string which is used as a kind of process ID */
256 const byte *
257 get_session_marker( size_t *rlen )
258 {
259     static byte marker[SIZEOF_UNSIGNED_LONG*2];
260     static int initialized;
261
262     if ( !initialized ) {
263         volatile ulong aa, bb; /* we really want the uninitialized value */
264         ulong a, b;
265
266         initialized = 1;
267         /* also this marker is guessable it is not easy to use this 
268          * for a faked control packet because an attacker does not
269          * have enough control about the time the verification does 
270          * take place.  Of course, we can add just more random but 
271          * than we need the random generator even for verification
272          * tasks - which does not make sense. */
273         a = aa ^ (ulong)getpid();
274         b = bb ^ (ulong)time(NULL);
275         memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
276         memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
277     }
278     *rlen = sizeof(marker);
279     return marker;
280 }
281
282 /****************
283  * Wrapper around the libgcrypt function with addional checks on
284  * openPGP contraints for the algo ID.
285  */
286 int
287 openpgp_cipher_test_algo( int algo )
288 {
289     if( algo < 0 || algo > 110 )
290         return G10ERR_CIPHER_ALGO;
291     return check_cipher_algo(algo);
292 }
293
294 int
295 openpgp_pk_test_algo( int algo, unsigned int usage_flags )
296 {
297     if( algo < 0 || algo > 110 )
298         return G10ERR_PUBKEY_ALGO;
299     return check_pubkey_algo2( algo, usage_flags );
300 }
301
302 int 
303 openpgp_pk_algo_usage ( int algo )
304 {
305     int use = 0; 
306     
307     /* they are hardwired in gpg 1.0 */
308     switch ( algo ) {    
309       case PUBKEY_ALGO_RSA:
310           use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC;
311           break;
312       case PUBKEY_ALGO_RSA_E:
313           use = PUBKEY_USAGE_ENC;
314           break;
315       case PUBKEY_ALGO_RSA_S:
316           use = PUBKEY_USAGE_SIG;
317           break;
318       case PUBKEY_ALGO_ELGAMAL_E:
319           use = PUBKEY_USAGE_ENC;
320           break;
321       case PUBKEY_ALGO_DSA:  
322           use = PUBKEY_USAGE_SIG;
323           break;
324       case PUBKEY_ALGO_ELGAMAL:
325           use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC;
326           break;
327       default:
328           break;
329     }
330     return use;
331 }
332
333 int
334 openpgp_md_test_algo( int algo )
335 {
336     if( algo < 0 || algo > 110 )
337         return G10ERR_DIGEST_ALGO;
338     return check_digest_algo(algo);
339 }
340
341 int
342 check_permissions(const char *path,int extension,int checkonly)
343 {
344 #if defined(HAVE_STAT) && !defined(HAVE_DOSISH_SYSTEM)
345   char *tmppath;
346   struct stat statbuf;
347   int ret=1;
348   int isdir=0;
349
350   if(opt.no_perm_warn)
351     return 0;
352
353   if(extension && path[0]!=DIRSEP_C)
354     {
355       if(strchr(path,DIRSEP_C))
356         tmppath=make_filename(path,NULL);
357       else
358         tmppath=make_filename(GNUPG_LIBDIR,path,NULL);
359     }
360   else
361     tmppath=m_strdup(path);
362
363   /* It's okay if the file doesn't exist */
364   if(stat(tmppath,&statbuf)!=0)
365     {
366       ret=0;
367       goto end;
368     }
369
370   isdir=S_ISDIR(statbuf.st_mode);
371
372   /* We may have to revisit this if we start piping keyrings to gpg
373      over a named pipe or keyserver character device :) */
374   if(!isdir && !S_ISREG(statbuf.st_mode))
375     {
376       ret=0;
377       goto end;
378     }
379
380   /* Per-user files must be owned by the user.  Extensions must be
381      owned by the user or root. */
382   if((!extension && statbuf.st_uid != getuid()) ||
383      (extension && statbuf.st_uid!=0 && statbuf.st_uid!=getuid()))
384     {
385       if(!checkonly)
386         log_info(_("Warning: unsafe ownership on %s \"%s\"\n"),
387                  isdir?"directory":extension?"extension":"file",path);
388       goto end;
389     }
390
391   /* This works for both directories and files - basically, we don't
392      care what the owner permissions are, so long as the group and
393      other permissions are 0 for per-user files, and non-writable for
394      extensions. */
395   if((extension && (statbuf.st_mode & (S_IWGRP|S_IWOTH)) !=0) ||
396      (!extension && (statbuf.st_mode & (S_IRWXG|S_IRWXO)) != 0))
397     {
398       char *dir;
399
400       /* However, if the directory the directory/file is in is owned
401          by the user and is 700, then this is not a problem.
402          Theoretically, we could walk this test up to the root
403          directory /, but for the sake of sanity, I'm stopping at one
404          level down. */
405
406       dir=make_dirname(tmppath);
407       if(stat(dir,&statbuf)==0 && statbuf.st_uid==getuid() &&
408          S_ISDIR(statbuf.st_mode) && (statbuf.st_mode & (S_IRWXG|S_IRWXO))==0)
409         {
410           m_free(dir);
411           ret=0;
412           goto end;
413         }
414
415       m_free(dir);
416
417       if(!checkonly)
418         log_info(_("Warning: unsafe permissions on %s \"%s\"\n"),
419                  isdir?"directory":extension?"extension":"file",path);
420       goto end;
421     }
422
423   ret=0;
424
425  end:
426   m_free(tmppath);
427
428   return ret;
429
430 #endif /* HAVE_STAT && !HAVE_DOSISH_SYSTEM */
431
432   return 0;
433 }
434
435 /* Special warning for the IDEA cipher */
436 void
437 idea_cipher_warn(int show)
438 {
439   static int warned=0;
440
441   if(!warned || show)
442     {
443       log_info(_("the IDEA cipher plugin is not present\n"));
444       log_info(_("please see http://www.gnupg.org/why-not-idea.html "
445                  "for more information\n"));
446       warned=1;
447     }
448 }
449
450 /* Expand %-strings.  Returns a string which must be m_freed.  Returns
451    NULL if the string cannot be expanded (too large). */
452 char *
453 pct_expando(const char *string,struct expando_args *args)
454 {
455   const char *ch=string;
456   int idx=0,maxlen=0,done=0;
457   u32 pk_keyid[2]={0,0},sk_keyid[2]={0,0};
458   char *ret=NULL;
459
460   if(args->pk)
461     keyid_from_pk(args->pk,pk_keyid);
462
463   if(args->sk)
464     keyid_from_sk(args->sk,sk_keyid);
465
466   if(!args->pk && args->sk)
467     keyid_from_sk(args->sk,pk_keyid);
468
469   while(*ch!='\0')
470     {
471       char *str=NULL;
472
473       if(!done)
474         {
475           /* 8192 is way bigger than we'll need here */
476           if(maxlen>=8192)
477             goto fail;
478
479           maxlen+=1024;
480           ret=m_realloc(ret,maxlen);
481         }
482
483       done=0;
484
485       if(*ch=='%')
486         {
487           switch(*(ch+1))
488             {
489             case 's': /* short key id */
490               if(idx+8<maxlen)
491                 {
492                   sprintf(&ret[idx],"%08lX",(ulong)sk_keyid[1]);
493                   idx+=8;
494                   done=1;
495                 }
496               break;
497
498             case 'S': /* long key id */
499               if(idx+16<maxlen)
500                 {
501                   sprintf(&ret[idx],"%08lX%08lX",
502                           (ulong)sk_keyid[0],(ulong)sk_keyid[1]);
503                   idx+=16;
504                   done=1;
505                 }
506               break;
507
508             case 'k': /* short key id */
509               if(idx+8<maxlen)
510                 {
511                   sprintf(&ret[idx],"%08lX",(ulong)pk_keyid[1]);
512                   idx+=8;
513                   done=1;
514                 }
515               break;
516
517             case 'K': /* long key id */
518               if(idx+16<maxlen)
519                 {
520                   sprintf(&ret[idx],"%08lX%08lX",
521                           (ulong)pk_keyid[0],(ulong)pk_keyid[1]);
522                   idx+=16;
523                   done=1;
524                 }
525               break;
526
527             case 'f': /* fingerprint */
528               {
529                 byte array[MAX_FINGERPRINT_LEN];
530                 size_t len;
531                 int i;
532
533                 if(args->pk)
534                   fingerprint_from_pk(args->pk,array,&len);
535                 else
536                   memset(array,0,MAX_FINGERPRINT_LEN);
537
538                 if(idx+(len*2)<maxlen)
539                   {
540                     for(i=0;i<len;i++)
541                       {
542                         sprintf(&ret[idx],"%02X",array[i]);
543                         idx+=2;
544                       }
545                     done=1;
546                   }
547               }
548               break;
549
550             case 't': /* e.g. "jpg" */
551               str=image_type_to_string(args->imagetype,0);
552               /* fall through */
553
554             case 'T': /* e.g. "image/jpeg" */
555               if(str==NULL)
556                 str=image_type_to_string(args->imagetype,2);
557
558               if(idx+strlen(str)<maxlen)
559                 {
560                   strcpy(&ret[idx],str);
561                   idx+=strlen(str);
562                   done=1;
563                 }
564               break;
565
566             case '%':
567               if(idx+1<maxlen)
568                 {
569                   ret[idx++]='%';
570                   ret[idx]='\0';
571                   done=1;
572                 }
573               break;
574
575               /* Any unknown %-keys (like %i, %o, %I, and %O) are
576                  passed through for later expansion.  Note this also
577                  handles the case where the last character in the
578                  string is a '%' - the terminating \0 will end up here
579                  and properly terminate the string. */
580             default:
581               if(idx+2<maxlen)
582                 {
583                   ret[idx++]='%';
584                   ret[idx++]=*(ch+1);
585                   ret[idx]='\0';
586                   done=1;
587                 }
588               break;
589               }
590
591           if(done)
592             ch++;
593         }
594       else
595         {
596           if(idx+1<maxlen)
597             {
598               ret[idx++]=*ch;
599               ret[idx]='\0';
600               done=1;
601             }
602         }
603
604       if(done)
605         ch++;
606     }
607
608   return ret;
609
610  fail:
611   m_free(ret);
612   return NULL;
613 }
614
615 int
616 hextobyte( const char *s )
617 {
618     int c;
619
620     if( *s >= '0' && *s <= '9' )
621         c = 16 * (*s - '0');
622     else if( *s >= 'A' && *s <= 'F' )
623         c = 16 * (10 + *s - 'A');
624     else if( *s >= 'a' && *s <= 'f' )
625         c = 16 * (10 + *s - 'a');
626     else
627         return -1;
628     s++;
629     if( *s >= '0' && *s <= '9' )
630         c += *s - '0';
631     else if( *s >= 'A' && *s <= 'F' )
632         c += 10 + *s - 'A';
633     else if( *s >= 'a' && *s <= 'f' )
634         c += 10 + *s - 'a';
635     else
636         return -1;
637     return c;
638 }
639
640 void
641 deprecated_warning(const char *configname,unsigned int configlineno,
642                    const char *option,const char *repl1,const char *repl2)
643 {
644   if(configname)
645     {
646       if(strncmp("--",option,2)==0)
647         option+=2;
648
649       if(strncmp("--",repl1,2)==0)
650         repl1+=2;
651
652       log_info(_("%s:%d: deprecated option \"%s\"\n"),
653                configname,configlineno,option);
654     }
655   else
656     log_info(_("WARNING: \"%s\" is a deprecated option\n"),option);
657
658   log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
659 }
660
661 const char *
662 compress_algo_to_string(int algo)
663 {
664   const char *s="?";
665
666   switch(algo)
667     {
668     case 0:
669       s="Uncompressed";
670       break;
671
672     case 1:
673       s="ZIP";
674       break;
675
676     case 2:
677       s="ZLIB";
678       break;
679     }
680
681   return s;
682 }
683
684 int
685 check_compress_algo(int algo)
686 {
687   if(algo>=0 && algo<=2)
688     return 0;
689
690   return G10ERR_COMPR_ALGO;
691 }