~ubuntu-branches/ubuntu/oneiric/gnupg2/oneiric-updates

« back to all changes in this revision

Viewing changes to g10/misc.c

  • Committer: Bazaar Package Importer
  • Author(s): Thomas Viehmann
  • Date: 2008-10-04 10:25:53 UTC
  • mfrom: (5.1.15 intrepid)
  • Revision ID: james.westby@ubuntu.com-20081004102553-fv62pp8dsitxli47
Tags: 2.0.9-3.1
* Non-maintainer upload.
* agent/gpg-agent.c: Deinit the threading library before exec'ing
  the command to run in --daemon mode. And because that still doesn't
  restore the sigprocmask, do that manually. Closes: #499569

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* misc.c -  miscellaneous functions
2
 
 * Copyright (C) 1998, 1999, 2000, 2001, 2002,
3
 
 *               2003 Free Software Foundation, Inc.
 
1
/* misc.c - miscellaneous functions
 
2
 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004,
 
3
 *               2005, 2006, 2007 Free Software Foundation, Inc.
4
4
 *
5
5
 * This file is part of GnuPG.
6
6
 *
7
7
 * GnuPG is free software; you can redistribute it and/or modify
8
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
 
9
 * the Free Software Foundation; either version 3 of the License, or
10
10
 * (at your option) any later version.
11
11
 *
12
12
 * GnuPG is distributed in the hope that it will be useful,
15
15
 * GNU General Public License for more details.
16
16
 *
17
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
 
18
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
20
19
 */
21
20
 
22
21
#include <config.h>
25
24
#include <string.h>
26
25
#include <unistd.h>
27
26
#include <errno.h>
28
 
#include <assert.h>
29
27
#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
30
28
#include <asm/sysinfo.h>
31
29
#include <asm/unistd.h>
35
33
#include <sys/time.h>
36
34
#include <sys/resource.h>
37
35
#endif
 
36
#ifdef ENABLE_SELINUX_HACKS
 
37
#include <sys/stat.h>
 
38
#endif
 
39
 
 
40
#ifdef HAVE_W32_SYSTEM
 
41
#include <time.h>
 
42
#include <process.h>
 
43
#include <windows.h> 
 
44
#include <shlobj.h>
 
45
#ifndef CSIDL_APPDATA
 
46
#define CSIDL_APPDATA 0x001a
 
47
#endif
 
48
#ifndef CSIDL_LOCAL_APPDATA
 
49
#define CSIDL_LOCAL_APPDATA 0x001c
 
50
#endif
 
51
#ifndef CSIDL_FLAG_CREATE
 
52
#define CSIDL_FLAG_CREATE 0x8000
 
53
#endif
 
54
#endif /*HAVE_W32_SYSTEM*/
38
55
 
39
56
#include "gpg.h"
 
57
#ifdef HAVE_W32_SYSTEM
 
58
# include "status.h"
 
59
#endif /*HAVE_W32_SYSTEM*/
40
60
#include "util.h"
41
61
#include "main.h"
42
62
#include "photoid.h"
43
63
#include "options.h"
 
64
#include "call-agent.h"
44
65
#include "i18n.h"
45
66
 
46
 
#define MAX_EXTERN_MPI_BITS 16384
47
 
 
48
 
 
49
 
#if defined(__linux__) && defined(__alpha__) && __GLIBC__ < 2
 
67
 
50
68
static int
51
 
setsysinfo(unsigned long op, void *buffer, unsigned long size,
52
 
                     int *start, void *arg, unsigned long flag)
53
 
{
54
 
    return syscall(__NR_osf_setsysinfo, op, buffer, size, start, arg, flag);
55
 
}
56
 
 
57
 
void
58
 
trap_unaligned(void)
59
 
{
60
 
    unsigned int buf[2];
61
 
 
62
 
    buf[0] = SSIN_UACPROC;
63
 
    buf[1] = UAC_SIGBUS | UAC_NOPRINT;
64
 
    setsysinfo(SSI_NVPAIRS, buf, 1, 0, 0, 0);
65
 
}
66
 
#else
67
 
void
68
 
trap_unaligned(void)
69
 
{  /* dummy */
70
 
}
71
 
#endif
72
 
 
73
 
 
74
 
int
75
 
disable_core_dumps()
76
 
{
77
 
#ifdef HAVE_DOSISH_SYSTEM
78
 
    return 0;
79
 
#else
80
 
#ifdef HAVE_SETRLIMIT
81
 
    struct rlimit limit;
82
 
 
83
 
    limit.rlim_cur = 0;
84
 
    limit.rlim_max = 0;
85
 
    if( !setrlimit( RLIMIT_CORE, &limit ) )
86
 
        return 0;
87
 
    if( errno != EINVAL && errno != ENOSYS )
88
 
        log_fatal(_("can't disable core dumps: %s\n"), strerror(errno) );
89
 
#endif
90
 
    return 1;
91
 
#endif
 
69
string_count_chr (const char *string, int c)
 
70
{
 
71
  int count;
 
72
 
 
73
  for (count=0; *string; string++ )
 
74
    if ( *string == c )
 
75
      count++;
 
76
  return count;
 
77
}
 
78
 
 
79
 
 
80
 
 
81
#ifdef ENABLE_SELINUX_HACKS
 
82
/* A object and a global variable to keep track of files marked as
 
83
   secured. */
 
84
struct secured_file_item 
 
85
{
 
86
  struct secured_file_item *next;
 
87
  ino_t ino;
 
88
  dev_t dev;
 
89
};
 
90
static struct secured_file_item *secured_files;
 
91
#endif /*ENABLE_SELINUX_HACKS*/
 
92
 
 
93
 
 
94
 
 
95
 
 
96
/* For the sake of SELinux we want to restrict access through gpg to
 
97
   certain files we keep under our own control.  This function
 
98
   registers such a file and is_secured_file may then be used to
 
99
   check whether a file has ben registered as secured. */
 
100
void
 
101
register_secured_file (const char *fname)
 
102
{
 
103
#ifdef ENABLE_SELINUX_HACKS
 
104
  struct stat buf;
 
105
  struct secured_file_item *sf;
 
106
 
 
107
  /* Note that we stop immediatley if something goes wrong here. */
 
108
  if (stat (fname, &buf))
 
109
    log_fatal (_("fstat of `%s' failed in %s: %s\n"), fname, 
 
110
               "register_secured_file", strerror (errno));
 
111
/*   log_debug ("registering `%s' i=%lu.%lu\n", fname, */
 
112
/*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
 
113
  for (sf=secured_files; sf; sf = sf->next)
 
114
    {
 
115
      if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
 
116
        return; /* Already registered.  */
 
117
    }
 
118
 
 
119
  sf = xmalloc (sizeof *sf);
 
120
  sf->ino = buf.st_ino;
 
121
  sf->dev = buf.st_dev;
 
122
  sf->next = secured_files;
 
123
  secured_files = sf;
 
124
#endif /*ENABLE_SELINUX_HACKS*/
 
125
}
 
126
 
 
127
/* Remove a file registered as secure. */
 
128
void
 
129
unregister_secured_file (const char *fname)
 
130
{
 
131
#ifdef ENABLE_SELINUX_HACKS
 
132
  struct stat buf;
 
133
  struct secured_file_item *sf, *sfprev;
 
134
 
 
135
  if (stat (fname, &buf))
 
136
    {
 
137
      log_error (_("fstat of `%s' failed in %s: %s\n"), fname,
 
138
                 "unregister_secured_file", strerror (errno));
 
139
      return;
 
140
    }
 
141
/*   log_debug ("unregistering `%s' i=%lu.%lu\n", fname,  */
 
142
/*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
 
143
  for (sfprev=NULL,sf=secured_files; sf; sfprev=sf, sf = sf->next)
 
144
    {
 
145
      if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
 
146
        {
 
147
          if (sfprev)
 
148
            sfprev->next = sf->next;
 
149
          else
 
150
            secured_files = sf->next;
 
151
          xfree (sf);
 
152
          return;
 
153
        }
 
154
    }
 
155
#endif /*ENABLE_SELINUX_HACKS*/
 
156
}
 
157
 
 
158
/* Return true if FD is corresponds to a secured file.  Using -1 for
 
159
   FS is allowed and will return false. */ 
 
160
int 
 
161
is_secured_file (int fd)
 
162
{
 
163
#ifdef ENABLE_SELINUX_HACKS
 
164
  struct stat buf;
 
165
  struct secured_file_item *sf;
 
166
 
 
167
  if (fd == -1)
 
168
    return 0; /* No file descriptor so it can't be secured either.  */
 
169
 
 
170
  /* Note that we print out a error here and claim that a file is
 
171
     secure if something went wrong. */
 
172
  if (fstat (fd, &buf))
 
173
    {
 
174
      log_error (_("fstat(%d) failed in %s: %s\n"), fd, 
 
175
                 "is_secured_file", strerror (errno));
 
176
      return 1;
 
177
    }
 
178
/*   log_debug ("is_secured_file (%d) i=%lu.%lu\n", fd, */
 
179
/*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
 
180
  for (sf=secured_files; sf; sf = sf->next)
 
181
    {
 
182
      if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
 
183
        return 1; /* Yes.  */
 
184
    }
 
185
#endif /*ENABLE_SELINUX_HACKS*/
 
186
  return 0; /* No. */
 
187
}
 
188
 
 
189
/* Return true if FNAME is corresponds to a secured file.  Using NULL,
 
190
   "" or "-" for FS is allowed and will return false. This function is
 
191
   used before creating a file, thus it won't fail if the file does
 
192
   not exist. */ 
 
193
int 
 
194
is_secured_filename (const char *fname)
 
195
{
 
196
#ifdef ENABLE_SELINUX_HACKS
 
197
  struct stat buf;
 
198
  struct secured_file_item *sf;
 
199
 
 
200
  if (iobuf_is_pipe_filename (fname) || !*fname)
 
201
    return 0; 
 
202
 
 
203
  /* Note that we print out a error here and claim that a file is
 
204
     secure if something went wrong. */
 
205
  if (stat (fname, &buf))
 
206
    {
 
207
      if (errno == ENOENT || errno == EPERM || errno == EACCES)
 
208
        return 0;
 
209
      log_error (_("fstat of `%s' failed in %s: %s\n"), fname,
 
210
                 "is_secured_filename", strerror (errno));
 
211
      return 1;
 
212
    }
 
213
/*   log_debug ("is_secured_filename (%s) i=%lu.%lu\n", fname, */
 
214
/*              (unsigned long)buf.st_dev, (unsigned long)buf.st_ino); */
 
215
  for (sf=secured_files; sf; sf = sf->next)
 
216
    {
 
217
      if (sf->ino == buf.st_ino && sf->dev == buf.st_dev)
 
218
        return 1; /* Yes.  */
 
219
    }
 
220
#endif /*ENABLE_SELINUX_HACKS*/
 
221
  return 0; /* No. */
92
222
}
93
223
 
94
224
 
115
245
}
116
246
 
117
247
u16
118
 
checksum_mpi( gcry_mpi_t a )
 
248
checksum_mpi (gcry_mpi_t a)
119
249
{
120
 
  int rc;
121
250
  u16 csum;
122
251
  byte *buffer;
123
252
  size_t nbytes;
124
253
 
125
 
  rc = gcry_mpi_print( GCRYMPI_FMT_PGP, NULL, 0, &nbytes, a );
126
 
  if (rc)
127
 
    BUG ();
128
 
  /* fixme: for numbers not in secure memory we should use a stack
129
 
   * based buffer and only allocate a larger one if mpi_print return
130
 
   * an error */
131
 
  buffer = gcry_is_secure(a)? gcry_xmalloc_secure(nbytes):gcry_xmalloc(nbytes);
132
 
  rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, NULL, a );
133
 
  if (rc)
134
 
    BUG ();
135
 
  csum = checksum (buffer, nbytes );
136
 
  xfree (buffer );
 
254
  if ( gcry_mpi_print (GCRYMPI_FMT_PGP, NULL, 0, &nbytes, a) )
 
255
    BUG ();
 
256
  /* Fixme: For numbers not in secure memory we should use a stack
 
257
   * based buffer and only allocate a larger one if mpi_print returns
 
258
   * an error. */
 
259
  buffer = (gcry_is_secure(a)?
 
260
            gcry_xmalloc_secure (nbytes) : gcry_xmalloc (nbytes));
 
261
  if ( gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, NULL, a) )
 
262
    BUG ();
 
263
  csum = checksum (buffer, nbytes);
 
264
  xfree (buffer);
137
265
  return csum;
138
266
}
139
267
 
148
276
    return a;
149
277
}
150
278
 
151
 
 
152
 
static void
153
 
no_exp_algo(void)
154
 
{
155
 
    static int did_note = 0;
156
 
 
157
 
    if( !did_note ) {
158
 
        did_note = 1;
159
 
        log_info(_("Experimental algorithms should not be used!\n"));
160
 
    }
161
 
}
162
 
 
163
279
void
164
280
print_pubkey_algo_note( int algo )
165
281
{
166
 
    if( algo >= 100 && algo <= 110 )
167
 
        no_exp_algo();
 
282
  if(algo >= 100 && algo <= 110)
 
283
    {
 
284
      static int warn=0;
 
285
      if(!warn)
 
286
        {
 
287
          warn=1;
 
288
          log_info (_("WARNING: using experimental public key algorithm %s\n"),
 
289
                    gcry_pk_algo_name (algo));
 
290
        }
 
291
    }
 
292
  else if (algo == 20)
 
293
    {
 
294
      log_info (_("WARNING: Elgamal sign+encrypt keys are deprecated\n"));
 
295
    }
168
296
}
169
297
 
170
298
void
171
299
print_cipher_algo_note( int algo )
172
300
{
173
 
    if( algo >= 100 && algo <= 110 )
174
 
        no_exp_algo();
175
 
    else if(    algo == CIPHER_ALGO_3DES
176
 
             || algo == CIPHER_ALGO_CAST5
177
 
             || algo == CIPHER_ALGO_BLOWFISH
178
 
             || algo == CIPHER_ALGO_TWOFISH
179
 
             || algo == CIPHER_ALGO_RIJNDAEL
180
 
             || algo == CIPHER_ALGO_RIJNDAEL192
181
 
             || algo == CIPHER_ALGO_RIJNDAEL256
182
 
           )
183
 
        ;
184
 
    else {
185
 
        static int did_note = 0;
186
 
 
187
 
        if( !did_note ) {
188
 
            did_note = 1;
189
 
            log_info(_("this cipher algorithm is deprecated; "
190
 
                       "please use a more standard one!\n"));
 
301
  if(algo >= 100 && algo <= 110)
 
302
    {
 
303
      static int warn=0;
 
304
      if(!warn)
 
305
        {
 
306
          warn=1;
 
307
          log_info (_("WARNING: using experimental cipher algorithm %s\n"),
 
308
                    openpgp_cipher_algo_name (algo));
191
309
        }
192
310
    }
193
311
}
195
313
void
196
314
print_digest_algo_note( int algo )
197
315
{
198
 
    if( algo >= 100 && algo <= 110 )
199
 
        no_exp_algo();
200
 
}
201
 
 
202
 
 
203
 
/* Return a string which is used as a kind of process ID */
204
 
const byte *
205
 
get_session_marker( size_t *rlen )
206
 
{
207
 
    static byte marker[SIZEOF_UNSIGNED_LONG*2];
208
 
    static int initialized;
209
 
 
210
 
    if ( !initialized ) {
211
 
        volatile ulong aa, bb; /* we really want the uninitialized value */
212
 
        ulong a, b;
213
 
 
214
 
        initialized = 1;
215
 
        /* also this marker is guessable it is not easy to use this 
216
 
         * for a faked control packet because an attacker does not
217
 
         * have enough control about the time the verification does 
218
 
         * take place.  Of course, we can add just more random but 
219
 
         * than we need the random generator even for verification
220
 
         * tasks - which does not make sense. */
221
 
        a = aa ^ (ulong)getpid();
222
 
        b = bb ^ (ulong)time(NULL);
223
 
        memcpy( marker, &a, SIZEOF_UNSIGNED_LONG );
224
 
        memcpy( marker+SIZEOF_UNSIGNED_LONG, &b, SIZEOF_UNSIGNED_LONG );
225
 
    }
226
 
    *rlen = sizeof(marker);
227
 
    return marker;
 
316
  if(algo >= 100 && algo <= 110)
 
317
    {
 
318
      static int warn=0;
 
319
      if(!warn)
 
320
        {
 
321
          warn=1;
 
322
          log_info (_("WARNING: using experimental digest algorithm %s\n"),
 
323
                    gcry_md_algo_name (algo));
 
324
        }
 
325
    }
 
326
  else if(algo==DIGEST_ALGO_MD5)
 
327
    log_info (_("WARNING: digest algorithm %s is deprecated\n"),
 
328
              gcry_md_algo_name (algo));
 
329
}
 
330
 
 
331
 
 
332
/* Map OpenPGP algo numbers to those used by Libgcrypt.  We need to do
 
333
   this for algorithms we implemented in Libgcrypt after they become
 
334
   part of OpenPGP.  */
 
335
static int
 
336
map_cipher_openpgp_to_gcry (int algo)
 
337
{
 
338
  switch (algo)
 
339
    {
 
340
    case CIPHER_ALGO_CAMELLIA128: return 310; 
 
341
    case CIPHER_ALGO_CAMELLIA256: return 312; 
 
342
    default: return algo;
 
343
    }
 
344
}
 
345
 
 
346
/* The inverse fucntion of above.  */
 
347
static int
 
348
map_cipher_gcry_to_openpgp (int algo)
 
349
{
 
350
  switch (algo)
 
351
    {
 
352
    case 310: return CIPHER_ALGO_CAMELLIA128;
 
353
    case 312: return CIPHER_ALGO_CAMELLIA256;
 
354
    default: return algo;
 
355
    }
228
356
}
229
357
 
230
358
/****************
231
 
 * Wrapper around the libgcrypt function with addional checks on
232
 
 * openPGP contraints for the algo ID.
 
359
 * Wrapper around the libgcrypt function with additonal checks on
 
360
 * the OpenPGP contraints for the algo ID.
233
361
 */
234
362
int
235
363
openpgp_cipher_test_algo( int algo )
236
364
{
237
 
    if( algo < 0 || algo > 110 )
238
 
        return GPG_ERR_CIPHER_ALGO;
239
 
    return gcry_cipher_test_algo (algo);
240
 
}
241
 
 
242
 
int
243
 
openpgp_pk_test_algo( int algo, unsigned int usage_flags )
244
 
{
245
 
  size_t value = usage_flags;
246
 
 
247
 
  if (algo == GCRY_PK_ELG_E)
248
 
    algo = GCRY_PK_ELG;
249
 
#ifdef __GNUC__
250
 
#warning need to handle the usage here?
 
365
  /* (5 and 6 are marked reserved by rfc4880.)  */
 
366
  if ( algo < 0 || algo > 110 || algo == 5 || algo == 6 )
 
367
    return gpg_error (GPG_ERR_CIPHER_ALGO);
 
368
 
 
369
  /* Camellia is not yet defined for OpenPGP thus only allow it if
 
370
     requested.  */
 
371
#ifndef USE_CAMELLIA
 
372
  if (algo == CIPHER_ALGO_CAMELLIA128 
 
373
       || algo == CIPHER_ALGO_CAMELLIA256)
 
374
    return gpg_error (GPG_ERR_CIPHER_ALGO);
251
375
#endif
252
 
  if (algo < 0 || algo > 110)
253
 
    return GPG_ERR_PUBKEY_ALGO;
254
 
  return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, &value);
 
376
 
 
377
  return gcry_cipher_test_algo (map_cipher_openpgp_to_gcry (algo));
 
378
}
 
379
 
 
380
/* Map the OpenPGP cipher algorithm whose ID is contained in ALGORITHM to a
 
381
   string representation of the algorithm name.  For unknown algorithm
 
382
   IDs this function returns "?".  */
 
383
const char *
 
384
openpgp_cipher_algo_name (int algo) 
 
385
{
 
386
  return gcry_cipher_algo_name (map_cipher_openpgp_to_gcry (algo));
 
387
}
 
388
 
 
389
 
 
390
 
 
391
int
 
392
openpgp_pk_test_algo( int algo )
 
393
{
 
394
  /* Dont't allow type 20 keys unless in rfc2440 mode.  */
 
395
  if (!RFC2440 && algo == 20)
 
396
    return gpg_error (GPG_ERR_PUBKEY_ALGO);
 
397
    
 
398
  if (algo == GCRY_PK_ELG_E)
 
399
    algo = GCRY_PK_ELG;
 
400
 
 
401
  if (algo < 0 || algo > 110)
 
402
    return gpg_error (GPG_ERR_PUBKEY_ALGO);
 
403
  return gcry_pk_test_algo (algo);
 
404
}
 
405
 
 
406
int
 
407
openpgp_pk_test_algo2( int algo, unsigned int use )
 
408
{
 
409
  size_t use_buf = use;
 
410
 
 
411
  /* Dont't allow type 20 keys unless in rfc2440 mode.  */
 
412
  if (!RFC2440 && algo == 20)
 
413
    return gpg_error (GPG_ERR_PUBKEY_ALGO);
 
414
 
 
415
  if (algo == GCRY_PK_ELG_E)
 
416
    algo = GCRY_PK_ELG;
 
417
 
 
418
  if (algo < 0 || algo > 110)
 
419
    return gpg_error (GPG_ERR_PUBKEY_ALGO);
 
420
 
 
421
  return gcry_pk_algo_info (algo, GCRYCTL_TEST_ALGO, NULL, &use_buf);
255
422
}
256
423
 
257
424
int 
259
426
{
260
427
    int use = 0; 
261
428
    
262
 
    /* they are hardwired in gpg 1.0 */
 
429
    /* They are hardwired in gpg 1.0. */
263
430
    switch ( algo ) {    
264
431
      case PUBKEY_ALGO_RSA:
265
 
          use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
 
432
          use = (PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG
 
433
                 | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH);
266
434
          break;
267
435
      case PUBKEY_ALGO_RSA_E:
268
436
          use = PUBKEY_USAGE_ENC;
269
437
          break;
270
438
      case PUBKEY_ALGO_RSA_S:
271
 
          use = PUBKEY_USAGE_SIG;
 
439
          use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG;
 
440
          break;
 
441
      case PUBKEY_ALGO_ELGAMAL:
 
442
          if (RFC2440)
 
443
             use = PUBKEY_USAGE_ENC;
272
444
          break;
273
445
      case PUBKEY_ALGO_ELGAMAL_E:
274
446
          use = PUBKEY_USAGE_ENC;
275
447
          break;
276
448
      case PUBKEY_ALGO_DSA:  
277
 
          use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
278
 
          break;
279
 
      case PUBKEY_ALGO_ELGAMAL:
280
 
          use = PUBKEY_USAGE_SIG | PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH;
 
449
          use = PUBKEY_USAGE_CERT | PUBKEY_USAGE_SIG | PUBKEY_USAGE_AUTH;
281
450
          break;
282
451
      default:
283
452
          break;
288
457
int
289
458
openpgp_md_test_algo( int algo )
290
459
{
291
 
    if( algo < 0 || algo > 110 )
292
 
        return GPG_ERR_DIGEST_ALGO;
293
 
    return gcry_md_test_algo (algo);
294
 
}
295
 
 
296
 
int
297
 
openpgp_md_map_name (const char *string)
298
 
{
299
 
  int i = gcry_md_map_name (string);
300
 
 
301
 
  if (!i && (string[0]=='H' || string[0]=='h'))
302
 
    { /* Didn't find it, so try the Hx format */
303
 
      long val;
304
 
      char *endptr;
305
 
 
306
 
      string++;
307
 
      
308
 
      val=strtol(string,&endptr,10);
309
 
      if (*string!='\0' && *endptr=='\0' && !openpgp_md_test_algo(val))
310
 
        i = val;
311
 
    }
312
 
  return i < 0 || i > 110? 0 : i;
313
 
}
314
 
 
315
 
int
316
 
openpgp_cipher_map_name (const char *string)
317
 
{
318
 
  int i = gcry_cipher_map_name (string);
319
 
 
320
 
  if (!i && (string[0]=='S' || string[0]=='s'))
321
 
    { /* Didn't find it, so try the Sx format */
322
 
      long val;
323
 
      char *endptr;
324
 
 
325
 
      string++;
326
 
      
327
 
      val=strtol(string,&endptr,10);
328
 
      if (*string!='\0' && *endptr=='\0' && !openpgp_cipher_test_algo(val))
329
 
        i = val;
330
 
    }
331
 
  return i < 0 || i > 110? 0 : i;
332
 
}
333
 
 
334
 
int
335
 
openpgp_pk_map_name (const char *string)
336
 
{
337
 
  int i = gcry_pk_map_name (string);
338
 
  return i < 0 || i > 110? 0 : i;
 
460
  /* Note: If the list of actual supported OpenPGP algorithms changes,
 
461
     make sure that our hard coded values at
 
462
     print_status_begin_signing() gets updated. */
 
463
  /* 4, 5, 6, 7 are defined by rfc2440 but will be removed from the
 
464
     next revision of the standard.  */
 
465
  if (algo < 0 || algo > 110 || (algo >= 4 && algo <= 7))
 
466
    return gpg_error (GPG_ERR_DIGEST_ALGO);
 
467
  return gcry_md_test_algo (algo);
339
468
}
340
469
 
341
470
#ifdef USE_IDEA
348
477
  if(!warned || show)
349
478
    {
350
479
      log_info(_("the IDEA cipher plugin is not present\n"));
351
 
      log_info(_("please see http://www.gnupg.org/why-not-idea.html "
352
 
                 "for more information\n"));
 
480
      log_info(_("please see %s for more information\n"),
 
481
               "http://www.gnupg.org/faq/why-not-idea.html");
353
482
      warned=1;
354
483
    }
355
484
}
356
485
#endif
357
486
 
358
 
/* Expand %-strings.  Returns a string which must be m_freed.  Returns
 
487
 
 
488
static unsigned long 
 
489
get_signature_count (PKT_secret_key *sk)
 
490
{
 
491
#ifdef ENABLE_CARD_SUPPORT
 
492
  if(sk && sk->is_protected && sk->protect.s2k.mode==1002)
 
493
    {
 
494
      struct agent_card_info_s info;
 
495
      if(agent_scd_getattr("SIG-COUNTER",&info)==0)
 
496
        return info.sig_counter;
 
497
    }  
 
498
#endif
 
499
 
 
500
  /* How to do this without a card? */
 
501
 
 
502
  return 0;
 
503
}
 
504
 
 
505
/* Expand %-strings.  Returns a string which must be xfreed.  Returns
359
506
   NULL if the string cannot be expanded (too large). */
360
507
char *
361
508
pct_expando(const char *string,struct expando_args *args)
387
534
            goto fail;
388
535
 
389
536
          maxlen+=1024;
390
 
          ret= xrealloc(ret,maxlen);
 
537
          ret=xrealloc(ret,maxlen);
391
538
        }
392
539
 
393
540
      done=0;
434
581
                }
435
582
              break;
436
583
 
 
584
            case 'c': /* signature count from card, if any. */
 
585
              if(idx+10<maxlen)
 
586
                {
 
587
                  sprintf(&ret[idx],"%lu",get_signature_count(args->sk));
 
588
                  idx+=strlen(&ret[idx]);
 
589
                  done=1;
 
590
                }             
 
591
              break;
 
592
 
437
593
            case 'p': /* primary pk fingerprint of a sk */
438
594
            case 'f': /* pk fingerprint */
439
595
            case 'g': /* sk fingerprint */
442
598
                size_t len;
443
599
                int i;
444
600
 
445
 
                if( ch[1]=='p' && args->sk)
 
601
                if((*(ch+1))=='p' && args->sk)
446
602
                  {
447
603
                    if(args->sk->is_primary)
448
604
                      fingerprint_from_sk(args->sk,array,&len);
449
605
                    else if(args->sk->main_keyid[0] || args->sk->main_keyid[1])
450
606
                      {
451
 
                        PKT_public_key *pk= xcalloc(1, sizeof(PKT_public_key));
 
607
                        PKT_public_key *pk=
 
608
                          xmalloc_clear(sizeof(PKT_public_key));
452
609
 
453
610
                        if(get_pubkey_fast(pk,args->sk->main_keyid)==0)
454
611
                          fingerprint_from_pk(pk,array,&len);
459
616
                    else
460
617
                      memset(array,0,(len=MAX_FINGERPRINT_LEN));
461
618
                  }
462
 
                else if( ch[1]=='f' && args->pk)
 
619
                else if((*(ch+1))=='f' && args->pk)
463
620
                  fingerprint_from_pk(args->pk,array,&len);
464
 
                else if( ch[1]=='g' && args->sk)
 
621
                else if((*(ch+1))=='g' && args->sk)
465
622
                  fingerprint_from_sk(args->sk,array,&len);
466
623
                else
467
 
                  memset(array, 0, (len=MAX_FINGERPRINT_LEN));
 
624
                  memset(array,0,(len=MAX_FINGERPRINT_LEN));
468
625
 
469
626
                if(idx+(len*2)<maxlen)
470
627
                  {
539
696
  return ret;
540
697
 
541
698
 fail:
542
 
  xfree (ret);
 
699
  xfree(ret);
543
700
  return NULL;
544
701
}
545
702
 
546
 
int
547
 
hextobyte( const char *s )
548
 
{
549
 
    int c;
550
 
 
551
 
    if( *s >= '0' && *s <= '9' )
552
 
        c = 16 * (*s - '0');
553
 
    else if( *s >= 'A' && *s <= 'F' )
554
 
        c = 16 * (10 + *s - 'A');
555
 
    else if( *s >= 'a' && *s <= 'f' )
556
 
        c = 16 * (10 + *s - 'a');
557
 
    else
558
 
        return -1;
559
 
    s++;
560
 
    if( *s >= '0' && *s <= '9' )
561
 
        c += *s - '0';
562
 
    else if( *s >= 'A' && *s <= 'F' )
563
 
        c += 10 + *s - 'A';
564
 
    else if( *s >= 'a' && *s <= 'f' )
565
 
        c += 10 + *s - 'a';
566
 
    else
567
 
        return -1;
568
 
    return c;
569
 
}
570
 
 
571
703
void
572
704
deprecated_warning(const char *configname,unsigned int configlineno,
573
705
                   const char *option,const char *repl1,const char *repl2)
589
721
  log_info(_("please use \"%s%s\" instead\n"),repl1,repl2);
590
722
}
591
723
 
 
724
 
 
725
void
 
726
deprecated_command (const char *name)
 
727
{
 
728
  log_info(_("WARNING: \"%s\" is a deprecated command - do not use it\n"),
 
729
           name);
 
730
}
 
731
 
 
732
 
 
733
void
 
734
obsolete_option (const char *configname, unsigned int configlineno, 
 
735
                 const char *name)
 
736
{
 
737
  if(configname)
 
738
    log_info (_("%s:%u: obsolete option \"%s\" - it has no effect\n"),
 
739
              configname, configlineno, name);
 
740
  else
 
741
    log_info (_("WARNING: \"%s\" is an obsolete option - it has no effect\n"),
 
742
              name);
 
743
}
 
744
 
 
745
 
 
746
/*
 
747
 * Wrapper around gcry_cipher_map_name to provide a fallback using the
 
748
 * "Sn" syntax as used by the preference strings.
 
749
 */
 
750
int 
 
751
string_to_cipher_algo (const char *string) 
 
752
 
753
  int val;
 
754
 
 
755
  val = map_cipher_gcry_to_openpgp (gcry_cipher_map_name (string));
 
756
  if (!val && string && (string[0]=='S' || string[0]=='s'))
 
757
    {
 
758
      char *endptr;
 
759
 
 
760
      string++;
 
761
      val = strtol (string, &endptr, 10);
 
762
      if (!*string || *endptr || openpgp_cipher_test_algo (val))
 
763
        val = 0;
 
764
    }
 
765
 
 
766
  return val;
 
767
}
 
768
 
 
769
/*
 
770
 * Wrapper around gcry_md_map_name to provide a fallback using the
 
771
 * "Hn" syntax as used by the preference strings.
 
772
 */
 
773
int 
 
774
string_to_digest_algo (const char *string) 
 
775
 
776
  int val;
 
777
 
 
778
  val = gcry_md_map_name (string);
 
779
  if (!val && string && (string[0]=='H' || string[0]=='h'))
 
780
    {
 
781
      char *endptr;
 
782
 
 
783
      string++;
 
784
      val = strtol (string, &endptr, 10);
 
785
      if (!*string || *endptr || openpgp_md_test_algo (val))
 
786
        val = 0;
 
787
    }
 
788
 
 
789
  return val;
 
790
}
 
791
 
 
792
 
 
793
 
592
794
const char *
593
795
compress_algo_to_string(int algo)
594
796
{
595
 
  const char *s="?";
 
797
  const char *s=NULL;
596
798
 
597
799
  switch(algo)
598
800
    {
599
 
    case 0:
600
 
      s="Uncompressed";
 
801
    case COMPRESS_ALGO_NONE:
 
802
      s=_("Uncompressed");
601
803
      break;
602
804
 
603
 
    case 1:
 
805
    case COMPRESS_ALGO_ZIP:
604
806
      s="ZIP";
605
807
      break;
606
808
 
607
 
    case 2:
 
809
    case COMPRESS_ALGO_ZLIB:
608
810
      s="ZLIB";
609
811
      break;
 
812
 
 
813
#ifdef HAVE_BZIP2
 
814
    case COMPRESS_ALGO_BZIP2:
 
815
      s="BZIP2";
 
816
      break;
 
817
#endif
610
818
    }
611
819
 
612
820
  return s;
615
823
int
616
824
string_to_compress_algo(const char *string)
617
825
{
618
 
  if(ascii_strcasecmp(string,"uncompressed")==0)
 
826
  /* TRANSLATORS: See doc/TRANSLATE about this string. */
 
827
  if(match_multistr(_("uncompressed|none"),string))
 
828
    return 0;
 
829
  else if(ascii_strcasecmp(string,"uncompressed")==0)
 
830
    return 0;
 
831
  else if(ascii_strcasecmp(string,"none")==0)
619
832
    return 0;
620
833
  else if(ascii_strcasecmp(string,"zip")==0)
621
834
    return 1;
622
835
  else if(ascii_strcasecmp(string,"zlib")==0)
623
836
    return 2;
 
837
#ifdef HAVE_BZIP2
 
838
  else if(ascii_strcasecmp(string,"bzip2")==0)
 
839
    return 3;
 
840
#endif
624
841
  else if(ascii_strcasecmp(string,"z0")==0)
625
842
    return 0;
626
843
  else if(ascii_strcasecmp(string,"z1")==0)
627
844
    return 1;
628
845
  else if(ascii_strcasecmp(string,"z2")==0)
629
846
    return 2;
 
847
#ifdef HAVE_BZIP2
 
848
  else if(ascii_strcasecmp(string,"z3")==0)
 
849
    return 3;
 
850
#endif
630
851
  else
631
852
    return -1;
632
853
}
634
855
int
635
856
check_compress_algo(int algo)
636
857
{
 
858
#ifdef HAVE_BZIP2
 
859
  if(algo>=0 && algo<=3)
 
860
    return 0;
 
861
#else
637
862
  if(algo>=0 && algo<=2)
638
863
    return 0;
 
864
#endif
639
865
 
640
 
  return GPG_ERR_COMPR_ALGO;
 
866
  return G10ERR_COMPR_ALGO;
641
867
}
642
868
 
643
869
int
652
878
}
653
879
 
654
880
/* There is no default_digest_algo function, but see
655
 
   sign.c:hash_for */
 
881
   sign.c:hash_for() */
656
882
 
657
883
int
658
884
default_compress_algo(void)
659
885
{
660
 
  if(opt.def_compress_algo!=-1)
661
 
    return opt.def_compress_algo;
 
886
  if(opt.compress_algo!=-1)
 
887
    return opt.compress_algo;
662
888
  else if(opt.personal_compress_prefs)
663
889
    return opt.personal_compress_prefs[0].value;
664
890
  else
668
894
const char *
669
895
compliance_option_string(void)
670
896
{
671
 
  switch(opt.compliance)
672
 
    {
673
 
    case CO_RFC2440:
674
 
      return "--openpgp";
675
 
    case CO_PGP2:
676
 
      return "--pgp2";
677
 
    case CO_PGP6:
678
 
      return "--pgp6";
679
 
    case CO_PGP7:
680
 
      return "--pgp7";
681
 
    case CO_PGP8:
682
 
      return "--pgp8";
683
 
    default:
684
 
      return "???";
685
 
    }
686
 
}
687
 
 
688
 
static const char *
689
 
compliance_string(void)
690
 
{
691
 
  switch(opt.compliance)
692
 
    {
693
 
    case CO_RFC2440:
694
 
      return "OpenPGP";
695
 
    case CO_PGP2:
696
 
      return "PGP 2.x";
697
 
    case CO_PGP6:
698
 
      return "PGP 6.x";
699
 
    case CO_PGP7:
700
 
      return "PGP 7.x";
701
 
    case CO_PGP8:
702
 
      return "PGP 8.x";
703
 
    default:
704
 
      return "???";
705
 
    }
 
897
  char *ver="???";
 
898
 
 
899
  switch(opt.compliance)
 
900
    {
 
901
    case CO_GNUPG:   return "--gnupg";
 
902
    case CO_RFC4880: return "--openpgp";
 
903
    case CO_RFC2440: return "--rfc2440";
 
904
    case CO_RFC1991: return "--rfc1991";
 
905
    case CO_PGP2:    return "--pgp2";
 
906
    case CO_PGP6:    return "--pgp6";
 
907
    case CO_PGP7:    return "--pgp7";
 
908
    case CO_PGP8:    return "--pgp8";
 
909
    }
 
910
 
 
911
  return ver;
706
912
}
707
913
 
708
914
void
709
915
compliance_failure(void)
710
916
{
711
 
  log_info(_("this message may not be usable by %s\n"),compliance_string());
 
917
  char *ver="???";
 
918
 
 
919
  switch(opt.compliance)
 
920
    {
 
921
    case CO_GNUPG:
 
922
      ver="GnuPG";
 
923
      break;
 
924
 
 
925
    case CO_RFC4880:
 
926
      ver="OpenPGP";
 
927
      break;
 
928
 
 
929
    case CO_RFC2440:
 
930
      ver="OpenPGP (older)";
 
931
      break;
 
932
 
 
933
    case CO_RFC1991:
 
934
      ver="old PGP";
 
935
      break;
 
936
 
 
937
    case CO_PGP2:
 
938
      ver="PGP 2.x";
 
939
      break;
 
940
 
 
941
    case CO_PGP6:
 
942
      ver="PGP 6.x";
 
943
      break;
 
944
 
 
945
    case CO_PGP7:
 
946
      ver="PGP 7.x";
 
947
      break;
 
948
 
 
949
    case CO_PGP8:
 
950
      ver="PGP 8.x";
 
951
      break;
 
952
    }
 
953
 
 
954
  log_info(_("this message may not be usable by %s\n"),ver);
712
955
  opt.compliance=CO_GNUPG;
713
956
}
714
957
 
 
958
/* Break a string into successive option pieces.  Accepts single word
 
959
   options and key=value argument options. */
 
960
char *
 
961
optsep(char **stringp)
 
962
{
 
963
  char *tok,*end;
 
964
 
 
965
  tok=*stringp;
 
966
  if(tok)
 
967
    {
 
968
      end=strpbrk(tok," ,=");
 
969
      if(end)
 
970
        {
 
971
          int sawequals=0;
 
972
          char *ptr=end;
 
973
 
 
974
          /* what we need to do now is scan along starting with *end,
 
975
             If the next character we see (ignoring spaces) is an =
 
976
             sign, then there is an argument. */
 
977
 
 
978
          while(*ptr)
 
979
            {
 
980
              if(*ptr=='=')
 
981
                sawequals=1;
 
982
              else if(*ptr!=' ')
 
983
                break;
 
984
              ptr++;
 
985
            }
 
986
 
 
987
          /* There is an argument, so grab that too.  At this point,
 
988
             ptr points to the first character of the argument. */
 
989
          if(sawequals)
 
990
            {
 
991
              /* Is it a quoted argument? */
 
992
              if(*ptr=='"')
 
993
                {
 
994
                  ptr++;
 
995
                  end=strchr(ptr,'"');
 
996
                  if(end)
 
997
                    end++;
 
998
                }
 
999
              else
 
1000
                end=strpbrk(ptr," ,");
 
1001
            }
 
1002
 
 
1003
          if(end && *end)
 
1004
            {
 
1005
              *end='\0';
 
1006
              *stringp=end+1;
 
1007
            }
 
1008
          else
 
1009
            *stringp=NULL;
 
1010
        }
 
1011
      else
 
1012
        *stringp=NULL;
 
1013
    }
 
1014
 
 
1015
  return tok;
 
1016
}
 
1017
 
 
1018
/* Breaks an option value into key and value.  Returns NULL if there
 
1019
   is no value.  Note that "string" is modified to remove the =value
 
1020
   part. */
 
1021
char *
 
1022
argsplit(char *string)
 
1023
{
 
1024
  char *equals,*arg=NULL;
 
1025
 
 
1026
  equals=strchr(string,'=');
 
1027
  if(equals)
 
1028
    {
 
1029
      char *quote,*space;
 
1030
 
 
1031
      *equals='\0';
 
1032
      arg=equals+1;
 
1033
 
 
1034
      /* Quoted arg? */
 
1035
      quote=strchr(arg,'"');
 
1036
      if(quote)
 
1037
        {
 
1038
          arg=quote+1;
 
1039
 
 
1040
          quote=strchr(arg,'"');
 
1041
          if(quote)
 
1042
            *quote='\0';
 
1043
        }
 
1044
      else
 
1045
        {
 
1046
          size_t spaces;
 
1047
 
 
1048
          /* Trim leading spaces off of the arg */
 
1049
          spaces=strspn(arg," ");
 
1050
          arg+=spaces;
 
1051
        }
 
1052
 
 
1053
      /* Trim tailing spaces off of the tag */
 
1054
      space=strchr(string,' ');
 
1055
      if(space)
 
1056
        *space='\0';
 
1057
    }
 
1058
 
 
1059
  return arg;
 
1060
}
 
1061
 
 
1062
/* Return the length of the initial token, leaving off any
 
1063
   argument. */
 
1064
static size_t
 
1065
optlen(const char *s)
 
1066
{
 
1067
  char *end=strpbrk(s," =");
 
1068
 
 
1069
  if(end)
 
1070
    return end-s;
 
1071
  else
 
1072
    return strlen(s);
 
1073
}
 
1074
 
715
1075
int
716
 
parse_options(char *str,unsigned int *options,struct parse_options *opts)
 
1076
parse_options(char *str,unsigned int *options,
 
1077
              struct parse_options *opts,int noisy)
717
1078
{
718
1079
  char *tok;
719
1080
 
720
 
  while((tok=strsep(&str," ,")))
 
1081
  if (str && !strcmp (str, "help"))
 
1082
    {
 
1083
      int i,maxlen=0;
 
1084
 
 
1085
      /* Figure out the longest option name so we can line these up
 
1086
         neatly. */
 
1087
      for(i=0;opts[i].name;i++)
 
1088
        if(opts[i].help && maxlen<strlen(opts[i].name))
 
1089
          maxlen=strlen(opts[i].name);
 
1090
 
 
1091
      for(i=0;opts[i].name;i++)
 
1092
        if(opts[i].help)
 
1093
          printf("%s%*s%s\n",opts[i].name,
 
1094
                 maxlen+2-(int)strlen(opts[i].name),"",_(opts[i].help));
 
1095
 
 
1096
      g10_exit(0);
 
1097
    }
 
1098
 
 
1099
  while((tok=optsep(&str)))
721
1100
    {
722
1101
      int i,rev=0;
 
1102
      char *otok=tok;
723
1103
 
724
1104
      if(tok[0]=='\0')
725
1105
        continue;
732
1112
 
733
1113
      for(i=0;opts[i].name;i++)
734
1114
        {
735
 
          if(ascii_strcasecmp(opts[i].name,tok)==0)
 
1115
          size_t toklen=optlen(tok);
 
1116
 
 
1117
          if(ascii_strncasecmp(opts[i].name,tok,toklen)==0)
736
1118
            {
 
1119
              /* We have a match, but it might be incomplete */
 
1120
              if(toklen!=strlen(opts[i].name))
 
1121
                {
 
1122
                  int j;
 
1123
 
 
1124
                  for(j=i+1;opts[j].name;j++)
 
1125
                    {
 
1126
                      if(ascii_strncasecmp(opts[j].name,tok,toklen)==0)
 
1127
                        {
 
1128
                          if(noisy)
 
1129
                            log_info(_("ambiguous option `%s'\n"),otok);
 
1130
                          return 0;
 
1131
                        }
 
1132
                    }
 
1133
                }
 
1134
 
737
1135
              if(rev)
738
 
                *options&=~opts[i].bit;
 
1136
                {
 
1137
                  *options&=~opts[i].bit;
 
1138
                  if(opts[i].value)
 
1139
                    *opts[i].value=NULL;
 
1140
                }
739
1141
              else
740
 
                *options|=opts[i].bit;
 
1142
                {
 
1143
                  *options|=opts[i].bit;
 
1144
                  if(opts[i].value)
 
1145
                    *opts[i].value=argsplit(tok);
 
1146
                }
741
1147
              break;
742
1148
            }
743
1149
        }
744
1150
 
745
1151
      if(!opts[i].name)
746
 
        return 0;
 
1152
        {
 
1153
          if(noisy)
 
1154
            log_info(_("unknown option `%s'\n"),otok);
 
1155
          return 0;
 
1156
        }
747
1157
    }
748
1158
 
749
1159
  return 1;
750
1160
}
751
1161
 
752
1162
 
753
 
 
 
1163
/* Return a new malloced string by unescaping the string S.  Escaping
 
1164
   is percent escaping and '+'/space mapping.  A binary nul will
 
1165
   silently be replaced by a 0xFF. */
 
1166
char *
 
1167
unescape_percent_string (const unsigned char *s)
 
1168
{
 
1169
  char *buffer, *d;
 
1170
 
 
1171
  buffer = d = xmalloc (strlen (s)+1);
 
1172
  while (*s)
 
1173
    {
 
1174
      if (*s == '%' && s[1] && s[2])
 
1175
        { 
 
1176
          s++;
 
1177
          *d = xtoi_2 (s);
 
1178
          if (!*d)
 
1179
            *d = '\xff';
 
1180
          d++;
 
1181
          s += 2;
 
1182
        }
 
1183
      else if (*s == '+')
 
1184
        {
 
1185
          *d++ = ' ';
 
1186
          s++;
 
1187
        }
 
1188
      else
 
1189
        *d++ = *s++;
 
1190
    }
 
1191
  *d = 0; 
 
1192
  return buffer;
 
1193
}
 
1194
 
 
1195
 
 
1196
int
 
1197
has_invalid_email_chars (const char *s)
 
1198
{
 
1199
  int at_seen=0;
 
1200
  const char *valid_chars=
 
1201
    "01234567890_-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
 
1202
 
 
1203
  for ( ; *s; s++ ) 
 
1204
    {
 
1205
      if ( *s & 0x80 )
 
1206
        return 1;
 
1207
      if ( *s == '@' )
 
1208
        at_seen=1;
 
1209
      else if ( !at_seen && !( !!strchr( valid_chars, *s ) || *s == '+' ) )
 
1210
        return 1;
 
1211
      else if ( at_seen && !strchr( valid_chars, *s ) )
 
1212
        return 1;
 
1213
    }
 
1214
  return 0;
 
1215
}
 
1216
 
 
1217
 
 
1218
/* Check whether NAME represents a valid mailbox according to
 
1219
   RFC822. Returns true if so. */
 
1220
int
 
1221
is_valid_mailbox (const char *name)
 
1222
{
 
1223
  return !( !name
 
1224
            || !*name
 
1225
            || has_invalid_email_chars (name)
 
1226
            || string_count_chr (name,'@') != 1
 
1227
            || *name == '@'
 
1228
            || name[strlen(name)-1] == '@'
 
1229
            || name[strlen(name)-1] == '.'
 
1230
            || strstr (name, "..") );
 
1231
}
 
1232
 
 
1233
 
 
1234
/* Similar to access(2), but uses PATH to find the file. */
 
1235
int
 
1236
path_access(const char *file,int mode)
 
1237
{
 
1238
  char *envpath;
 
1239
  int ret=-1;
 
1240
 
 
1241
  envpath=getenv("PATH");
 
1242
 
 
1243
  if(!envpath
 
1244
#ifdef HAVE_DRIVE_LETTERS
 
1245
     || (((file[0]>='A' && file[0]<='Z')
 
1246
          || (file[0]>='a' && file[0]<='z'))
 
1247
         && file[1]==':')
 
1248
#else
 
1249
     || file[0]=='/'
 
1250
#endif
 
1251
     )
 
1252
    return access(file,mode);
 
1253
  else
 
1254
    {
 
1255
      /* At least as large as, but most often larger than we need. */
 
1256
      char *buffer=xmalloc(strlen(envpath)+1+strlen(file)+1);
 
1257
      char *split,*item,*path=xstrdup(envpath);
 
1258
 
 
1259
      split=path;
 
1260
 
 
1261
      while((item=strsep(&split,PATHSEP_S)))
 
1262
        {
 
1263
          strcpy(buffer,item);
 
1264
          strcat(buffer,"/");
 
1265
          strcat(buffer,file);
 
1266
          ret=access(buffer,mode);
 
1267
          if(ret==0)
 
1268
            break;
 
1269
        }
 
1270
 
 
1271
      xfree(path);
 
1272
      xfree(buffer);
 
1273
    }
 
1274
 
 
1275
  return ret;
 
1276
}
 
1277
 
 
1278
 
 
1279
 
754
1280
/* Temporary helper. */
755
1281
int
756
1282
pubkey_get_npkey( int algo )
837
1363
    return nbits;
838
1364
}
839
1365
 
840
 
 
841
 
/* MPI helper functions. */
842
 
 
843
 
 
844
 
/****************
845
 
 * write an mpi to out.
846
 
 */
847
 
int
848
 
mpi_write( iobuf_t out, gcry_mpi_t a )
849
 
{
850
 
    char buffer[(MAX_EXTERN_MPI_BITS+7)/8];
851
 
    size_t nbytes;
852
 
    int rc;
853
 
 
854
 
    nbytes = (MAX_EXTERN_MPI_BITS+7)/8;
855
 
    rc = gcry_mpi_print (GCRYMPI_FMT_PGP, buffer, nbytes, &nbytes, a );
856
 
    if( !rc )
857
 
        rc = iobuf_write( out, buffer, nbytes );
858
 
 
859
 
    return rc;
860
 
}
861
 
 
862
 
/****************
863
 
 * Writyeg a MPI to out, but in this case it is an opaque one,
864
 
 * s used vor v3 protected keys.
865
 
 */
866
 
int
867
 
mpi_write_opaque( iobuf_t out, gcry_mpi_t a )
868
 
{
869
 
    size_t nbytes, nbits;
870
 
    int rc;
871
 
    char *p;
872
 
 
873
 
    assert( gcry_mpi_get_flag( a, GCRYMPI_FLAG_OPAQUE ) );
874
 
    p = gcry_mpi_get_opaque( a, &nbits );
875
 
    nbytes = (nbits+7) / 8;
876
 
    iobuf_put( out, nbits >> 8 );
877
 
    iobuf_put( out, nbits );
878
 
    rc = iobuf_write( out, p, nbytes );
879
 
    return rc;
880
 
}
881
 
 
882
 
 
883
 
/****************
884
 
 * Read an external representation of an mpi and return the MPI
885
 
 * The external format is a 16 bit unsigned value stored in network byte order,
886
 
 * giving the number of bits for the following integer. The integer is stored
887
 
 * with MSB first (left padded with zeroes to align on a byte boundary).
888
 
 */
889
 
gcry_mpi_t
890
 
mpi_read(iobuf_t inp, unsigned int *ret_nread, int secure)
891
 
{
892
 
    int c, c1, c2, i;
893
 
    unsigned int nbits, nbytes, nread=0;
894
 
    gcry_mpi_t a = NULL;
895
 
    byte *buf = NULL;
896
 
    byte *p;
897
 
 
898
 
    if( (c = c1 = iobuf_get(inp)) == -1 )
899
 
        goto leave;
900
 
    nbits = c << 8;
901
 
    if( (c = c2 = iobuf_get(inp)) == -1 )
902
 
        goto leave;
903
 
    nbits |= c;
904
 
    if( nbits > MAX_EXTERN_MPI_BITS ) {
905
 
        log_error("mpi too large (%u bits)\n", nbits);
906
 
        goto leave;
907
 
    }
908
 
    nread = 2;
909
 
    nbytes = (nbits+7) / 8;
910
 
    buf = secure? gcry_xmalloc_secure( nbytes+2 ) : gcry_xmalloc( nbytes+2 );
911
 
    p = buf;
912
 
    p[0] = c1;
913
 
    p[1] = c2;
914
 
    for( i=0 ; i < nbytes; i++ ) {
915
 
        p[i+2] = iobuf_get(inp) & 0xff;
916
 
        nread++;
917
 
    }
918
 
    nread += nbytes;
919
 
    if( gcry_mpi_scan( &a, GCRYMPI_FMT_PGP, buf, nread, &nread ) )
920
 
        a = NULL;
921
 
 
922
 
  leave:
923
 
    gcry_free(buf);
924
 
    if( nread > *ret_nread )
925
 
        log_bug("mpi larger than packet");
926
 
    else
927
 
        *ret_nread = nread;
928
 
    return a;
929
 
}
930
 
 
931
 
/****************
932
 
 * Same as mpi_read but the value is stored as an opaque MPI.
933
 
 * This function is used to read encrypted MPI of v3 packets.
934
 
 */
935
 
gcry_mpi_t
936
 
mpi_read_opaque(iobuf_t inp, unsigned *ret_nread )
937
 
{
938
 
    int c, c1, c2, i;
939
 
    unsigned nbits, nbytes, nread=0;
940
 
    gcry_mpi_t a = NULL;
941
 
    byte *buf = NULL;
942
 
    byte *p;
943
 
 
944
 
    if( (c = c1 = iobuf_get(inp)) == -1 )
945
 
        goto leave;
946
 
    nbits = c << 8;
947
 
    if( (c = c2 = iobuf_get(inp)) == -1 )
948
 
        goto leave;
949
 
    nbits |= c;
950
 
    if( nbits > MAX_EXTERN_MPI_BITS ) {
951
 
        log_error("mpi too large (%u bits)\n", nbits);
952
 
        goto leave;
953
 
    }
954
 
    nread = 2;
955
 
    nbytes = (nbits+7) / 8;
956
 
    buf = gcry_xmalloc( nbytes );
957
 
    p = buf;
958
 
    for( i=0 ; i < nbytes; i++ ) {
959
 
        p[i] = iobuf_get(inp) & 0xff;
960
 
    }
961
 
    nread += nbytes;
962
 
    a = gcry_mpi_set_opaque(NULL, buf, nbits );
963
 
    buf = NULL;
964
 
 
965
 
  leave:
966
 
    gcry_free(buf);
967
 
    if( nread > *ret_nread )
968
 
        log_bug("mpi larger than packet");
969
 
    else
970
 
        *ret_nread = nread;
971
 
    return a;
972
 
}
973
 
 
974
 
 
 
1366
 
 
1367
 
 
1368
/* FIXME: Use gcry_mpi_print directly. */
975
1369
int
976
1370
mpi_print( FILE *fp, gcry_mpi_t a, int mode )
977
1371
{
985
1379
        n += fprintf(fp, "[%u bits]", n1);
986
1380
    }
987
1381
    else {
988
 
        int rc;
989
 
        char *buffer;
 
1382
        unsigned char *buffer;
990
1383
 
991
 
        rc = gcry_mpi_aprint( GCRYMPI_FMT_HEX, &buffer, NULL, a );
992
 
        assert( !rc );
 
1384
        if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buffer, NULL, a))
 
1385
          BUG ();
993
1386
        fputs( buffer, fp );
994
1387
        n += strlen(buffer);
995
1388
        gcry_free( buffer );
997
1390
    return n;
998
1391
}
999
1392
 
1000