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

« back to all changes in this revision

Viewing changes to kbx/keybox-dump.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:
5
5
 *
6
6
 * GnuPG is free software; you can redistribute it and/or modify
7
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
 
8
 * the Free Software Foundation; either version 3 of the License, or
9
9
 * (at your option) any later version.
10
10
 *
11
11
 * GnuPG is distributed in the hope that it will be useful,
14
14
 * GNU General Public License for more details.
15
15
 *
16
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
 
17
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
19
18
 */
20
19
 
21
20
#include <config.h>
25
24
#include <errno.h>
26
25
 
27
26
#include "keybox-defs.h"
 
27
#include <gcrypt.h>
 
28
 
 
29
/* Argg, we can't include ../common/util.h */
 
30
char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf);
 
31
 
28
32
 
29
33
static ulong
30
34
get32 (const byte *buffer)
184
188
 
185
189
  fprintf( fp, "Data-Offset: %lu\n", rawdata_off );
186
190
  fprintf( fp, "Data-Length: %lu\n", rawdata_len );
 
191
  if (rawdata_off > length || rawdata_len > length 
 
192
      || rawdata_off+rawdata_off > length)
 
193
    fprintf (fp, "[Error: raw data larger than blob]\n");
187
194
 
188
195
  nkeys = get16 (buffer + 16);
189
196
  fprintf (fp, "Key-Count: %lu\n", nkeys );
323
330
}
324
331
 
325
332
 
 
333
/* Compute the SHA_1 checksum of teh rawdata in BLOB and aput it into
 
334
   DIGEST. */
 
335
static int
 
336
hash_blob_rawdata (KEYBOXBLOB blob, unsigned char *digest)
 
337
{
 
338
  const unsigned char *buffer;
 
339
  size_t n, length;
 
340
  int type;
 
341
  ulong rawdata_off, rawdata_len;
 
342
 
 
343
  buffer = _keybox_get_blob_image (blob, &length);
 
344
  
 
345
  if (length < 32)
 
346
    return -1;
 
347
  n = get32 (buffer);
 
348
  if (n < length) 
 
349
    length = n;  /* Blob larger than length in header - ignore the rest. */
 
350
 
 
351
  type = buffer[4];
 
352
  switch (type)
 
353
    {
 
354
    case BLOBTYPE_PGP:
 
355
    case BLOBTYPE_X509:
 
356
      break;
 
357
 
 
358
    case BLOBTYPE_EMPTY:
 
359
    case BLOBTYPE_HEADER:
 
360
    default:
 
361
      memset (digest, 0, 20);
 
362
      return 0;
 
363
    }
 
364
 
 
365
  if (length < 40)
 
366
    return -1;
 
367
  
 
368
  rawdata_off = get32 (buffer + 8);
 
369
  rawdata_len = get32 (buffer + 12);
 
370
 
 
371
  if (rawdata_off > length || rawdata_len > length 
 
372
      || rawdata_off+rawdata_off > length)
 
373
    return -1; /* Out of bounds.  */
 
374
 
 
375
  gcry_md_hash_buffer (GCRY_MD_SHA1, digest, buffer+rawdata_off, rawdata_len);
 
376
  return 0;
 
377
}
 
378
 
 
379
 
326
380
struct file_stats_s
327
381
{
328
382
  unsigned long too_short_blobs;
402
456
 
403
457
 
404
458
 
 
459
static FILE *
 
460
open_file (const char **filename, FILE *outfp)
 
461
{
 
462
  FILE *fp;
 
463
 
 
464
  if (!*filename)
 
465
    {
 
466
      *filename = "-";
 
467
      fp = stdin;
 
468
    }
 
469
  else
 
470
    fp = fopen (*filename, "rb");
 
471
  if (!fp)
 
472
    {
 
473
      int save_errno = errno;
 
474
      fprintf (outfp, "can't open `%s': %s\n", *filename, strerror(errno));
 
475
      errno = save_errno;
 
476
    }
 
477
  return fp;
 
478
}
 
479
 
 
480
 
 
481
 
405
482
int
406
483
_keybox_dump_file (const char *filename, int stats_only, FILE *outfp)
407
484
{
413
490
 
414
491
  memset (&stats, 0, sizeof stats);
415
492
 
416
 
  if (!filename)
417
 
    {
418
 
      filename = "-";
419
 
      fp = stdin;
420
 
    }
421
 
  else
422
 
    fp = fopen (filename, "rb");
423
 
  if (!fp)
424
 
    {
425
 
      gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
426
 
      fprintf (outfp, "can't open `%s': %s\n", filename, strerror(errno));
427
 
      return tmperr;
428
 
    }
 
493
  if (!(fp = open_file (&filename, outfp)))
 
494
    return gpg_error_from_syserror ();
429
495
 
430
496
  while ( !(rc = _keybox_read_blob (&blob, fp)) )
431
497
    {
482
548
 
483
549
  return rc;
484
550
}
 
551
 
 
552
 
 
553
 
 
554
struct dupitem_s 
 
555
{
 
556
  unsigned long recno; 
 
557
  unsigned char digest[20];
 
558
};
 
559
 
 
560
 
 
561
static int
 
562
cmp_dupitems (const void *arg_a, const void *arg_b)
 
563
{
 
564
  struct dupitem_s *a = (struct dupitem_s *)arg_a;
 
565
  struct dupitem_s *b = (struct dupitem_s *)arg_b;
 
566
  
 
567
  return memcmp (a->digest, b->digest, 20);
 
568
}
 
569
 
 
570
 
 
571
int
 
572
_keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp)
 
573
{
 
574
  FILE *fp;
 
575
  KEYBOXBLOB blob;
 
576
  int rc;
 
577
  unsigned long recno = 0;
 
578
  unsigned char zerodigest[20];
 
579
  struct dupitem_s *dupitems;
 
580
  size_t dupitems_size, dupitems_count, lastn, n;
 
581
  char fprbuf[3*20+1];
 
582
  
 
583
  memset (zerodigest, 0, sizeof zerodigest);
 
584
 
 
585
  if (!(fp = open_file (&filename, outfp)))
 
586
    return gpg_error_from_syserror ();
 
587
 
 
588
  dupitems_size = 1000;
 
589
  dupitems = malloc (dupitems_size * sizeof *dupitems);
 
590
  if (!dupitems)
 
591
    {
 
592
      gpg_error_t tmperr = gpg_error_from_syserror ();
 
593
      fprintf (outfp, "error allocating array for `%s': %s\n",
 
594
               filename, strerror(errno));
 
595
      return tmperr;
 
596
    }
 
597
  dupitems_count = 0;
 
598
 
 
599
  while ( !(rc = _keybox_read_blob (&blob, fp)) )
 
600
    {
 
601
      unsigned char digest[20];
 
602
      
 
603
      if (hash_blob_rawdata (blob, digest))
 
604
        fprintf (outfp, "error in blob %ld of `%s'\n", recno, filename);
 
605
      else if (memcmp (digest, zerodigest, 20))
 
606
        {
 
607
          if (dupitems_count >= dupitems_size)
 
608
            {
 
609
              struct dupitem_s *tmp;
 
610
 
 
611
              dupitems_size += 1000;
 
612
              tmp = realloc (dupitems, dupitems_size * sizeof *dupitems);
 
613
              if (!tmp)
 
614
                {
 
615
                  gpg_error_t tmperr = gpg_error_from_syserror ();
 
616
                  fprintf (outfp, "error reallocating array for `%s': %s\n",
 
617
                           filename, strerror(errno));
 
618
                  free (dupitems);
 
619
                  return tmperr;
 
620
                }
 
621
              dupitems = tmp;
 
622
            }
 
623
          dupitems[dupitems_count].recno = recno;
 
624
          memcpy (dupitems[dupitems_count].digest, digest, 20);
 
625
          dupitems_count++;
 
626
        }
 
627
      _keybox_release_blob (blob);
 
628
      recno++;
 
629
    }
 
630
  if (rc == -1)
 
631
    rc = 0;
 
632
  if (rc)
 
633
    fprintf (outfp, "error reading `%s': %s\n", filename, gpg_strerror (rc));
 
634
  if (fp != stdin)
 
635
    fclose (fp);
 
636
 
 
637
  qsort (dupitems, dupitems_count, sizeof *dupitems, cmp_dupitems);
 
638
 
 
639
  for (lastn=0, n=1; n < dupitems_count; lastn=n, n++)
 
640
    {
 
641
      if (!memcmp (dupitems[lastn].digest, dupitems[n].digest, 20))
 
642
        {
 
643
          bin2hexcolon (dupitems[lastn].digest, 20, fprbuf);
 
644
          fprintf (outfp, "fpr=%s recno=%lu", fprbuf, dupitems[lastn].recno);
 
645
          do
 
646
            fprintf (outfp, " %lu", dupitems[n].recno);
 
647
          while (++n < dupitems_count
 
648
                 && !memcmp (dupitems[lastn].digest, dupitems[n].digest, 20));
 
649
          putc ('\n', outfp);
 
650
          n--;
 
651
        }
 
652
    }
 
653
 
 
654
  free (dupitems);
 
655
 
 
656
  return rc;
 
657
}
 
658
 
 
659
 
 
660
/* Print records with record numbers FROM to TO to OUTFP.  */
 
661
int
 
662
_keybox_dump_cut_records (const char *filename, unsigned long from,
 
663
                          unsigned long to, FILE *outfp)
 
664
{
 
665
  FILE *fp;
 
666
  KEYBOXBLOB blob;
 
667
  int rc;
 
668
  unsigned long recno = 0;
 
669
  
 
670
  if (!(fp = open_file (&filename, stderr)))
 
671
    return gpg_error_from_syserror ();
 
672
 
 
673
  while ( !(rc = _keybox_read_blob (&blob, fp)) )
 
674
    {
 
675
      if (recno > to)
 
676
        break; /* Ready.  */
 
677
      if (recno >= from)
 
678
        {
 
679
          if ((rc = _keybox_write_blob (blob, outfp)))
 
680
            {
 
681
              fprintf (stderr, "error writing output: %s\n",
 
682
                       gpg_strerror (rc));
 
683
              goto leave;
 
684
            }
 
685
        }
 
686
      _keybox_release_blob (blob);
 
687
      recno++;
 
688
    }
 
689
  if (rc == -1)
 
690
    rc = 0;
 
691
  if (rc)
 
692
    fprintf (stderr, "error reading `%s': %s\n", filename, gpg_strerror (rc));
 
693
 leave:
 
694
  if (fp != stdin)
 
695
    fclose (fp);
 
696
  return rc;
 
697
}