Пример #1
0
/* Print records with record numbers FROM to TO to OUTFP.  */
int
_keybox_dump_cut_records (const char *filename, unsigned long from,
                          unsigned long to, FILE *outfp)
{
  FILE *fp;
  KEYBOXBLOB blob;
  int rc;
  unsigned long recno = 0;

  if (!(fp = open_file (&filename, stderr)))
    return gpg_error_from_syserror ();

  while ( !(rc = _keybox_read_blob (&blob, fp)) )
    {
      if (recno > to)
        break; /* Ready.  */
      if (recno >= from)
        {
          if ((rc = _keybox_write_blob (blob, outfp)))
            {
              fprintf (stderr, "error writing output: %s\n",
                       gpg_strerror (rc));
              goto leave;
            }
        }
      _keybox_release_blob (blob);
      recno++;
    }
  if (rc == -1)
    rc = 0;
  if (rc)
    fprintf (stderr, "error reading '%s': %s\n", filename, gpg_strerror (rc));
 leave:
  if (fp != stdin)
    fclose (fp);
  return rc;
}
Пример #2
0
int
_keybox_dump_file (const char *filename, int stats_only, FILE *outfp)
{
  FILE *fp;
  KEYBOXBLOB blob;
  int rc;
  unsigned long count = 0;
  struct file_stats_s stats;

  memset (&stats, 0, sizeof stats);

  if (!(fp = open_file (&filename, outfp)))
    return gpg_error_from_syserror ();

  for (;;)
    {
      rc = _keybox_read_blob (&blob, fp);
      if (gpg_err_code (rc) == GPG_ERR_TOO_LARGE
          && gpg_err_source (rc) == GPG_ERR_SOURCE_KEYBOX)
        {
          if (stats_only)
            stats.skipped_long_blobs++;
          else
            {
              fprintf (outfp, "BEGIN-RECORD: %lu\n", count );
              fprintf (outfp, "# Record too large\nEND-RECORD\n");
            }
          count++;
          continue;
        }
      if (rc)
        break;

      if (stats_only)
        {
          update_stats (blob, &stats);
        }
      else
        {
          fprintf (outfp, "BEGIN-RECORD: %lu\n", count );
          _keybox_dump_blob (blob, outfp);
          fprintf (outfp, "END-RECORD\n");
        }
      _keybox_release_blob (blob);
      count++;
    }
  if (rc == -1)
    rc = 0;
  if (rc)
    fprintf (outfp, "# error reading '%s': %s\n", filename, gpg_strerror (rc));

  if (fp != stdin)
    fclose (fp);

  if (stats_only)
    {
      fprintf (outfp,
               "Total number of blobs: %8lu\n"
               "               header: %8lu\n"
               "                empty: %8lu\n"
               "              openpgp: %8lu\n"
               "                 x509: %8lu\n"
               "          non flagged: %8lu\n"
               "       secret flagged: %8lu\n"
               "    ephemeral flagged: %8lu\n",
               stats.total_blob_count,
               stats.header_blob_count,
               stats.empty_blob_count,
               stats.pgp_blob_count,
               stats.x509_blob_count,
               stats.non_flagged,
               stats.secret_flagged,
               stats.ephemeral_flagged);
        if (stats.skipped_long_blobs)
          fprintf (outfp, "   skipped long blobs: %8lu\n",
                   stats.skipped_long_blobs);
        if (stats.unknown_blob_count)
          fprintf (outfp, "   unknown blob types: %8lu\n",
                   stats.unknown_blob_count);
        if (stats.too_short_blobs)
          fprintf (outfp, "      too short blobs: %8lu (error)\n",
                   stats.too_short_blobs);
        if (stats.too_large_blobs)
          fprintf (outfp, "      too large blobs: %8lu (error)\n",
                   stats.too_large_blobs);
    }

  return rc;
}
Пример #3
0
int
_keybox_dump_find_dups (const char *filename, int print_them, FILE *outfp)
{
  FILE *fp;
  KEYBOXBLOB blob;
  int rc;
  unsigned long recno = 0;
  unsigned char zerodigest[20];
  struct dupitem_s *dupitems;
  size_t dupitems_size, dupitems_count, lastn, n;
  char fprbuf[3*20+1];

  (void)print_them;

  memset (zerodigest, 0, sizeof zerodigest);

  if (!(fp = open_file (&filename, outfp)))
    return gpg_error_from_syserror ();

  dupitems_size = 1000;
  dupitems = malloc (dupitems_size * sizeof *dupitems);
  if (!dupitems)
    {
      gpg_error_t tmperr = gpg_error_from_syserror ();
      fprintf (outfp, "error allocating array for '%s': %s\n",
               filename, strerror(errno));
      return tmperr;
    }
  dupitems_count = 0;

  while ( !(rc = _keybox_read_blob (&blob, fp)) )
    {
      unsigned char digest[20];

      if (hash_blob_rawdata (blob, digest))
        fprintf (outfp, "error in blob %ld of '%s'\n", recno, filename);
      else if (memcmp (digest, zerodigest, 20))
        {
          if (dupitems_count >= dupitems_size)
            {
              struct dupitem_s *tmp;

              dupitems_size += 1000;
              tmp = realloc (dupitems, dupitems_size * sizeof *dupitems);
              if (!tmp)
                {
                  gpg_error_t tmperr = gpg_error_from_syserror ();
                  fprintf (outfp, "error reallocating array for '%s': %s\n",
                           filename, strerror(errno));
                  free (dupitems);
                  return tmperr;
                }
              dupitems = tmp;
            }
          dupitems[dupitems_count].recno = recno;
          memcpy (dupitems[dupitems_count].digest, digest, 20);
          dupitems_count++;
        }
      _keybox_release_blob (blob);
      recno++;
    }
  if (rc == -1)
    rc = 0;
  if (rc)
    fprintf (outfp, "error reading '%s': %s\n", filename, gpg_strerror (rc));
  if (fp != stdin)
    fclose (fp);

  qsort (dupitems, dupitems_count, sizeof *dupitems, cmp_dupitems);

  for (lastn=0, n=1; n < dupitems_count; lastn=n, n++)
    {
      if (!memcmp (dupitems[lastn].digest, dupitems[n].digest, 20))
        {
          bin2hexcolon (dupitems[lastn].digest, 20, fprbuf);
          fprintf (outfp, "fpr=%s recno=%lu", fprbuf, dupitems[lastn].recno);
          do
            fprintf (outfp, " %lu", dupitems[n].recno);
          while (++n < dupitems_count
                 && !memcmp (dupitems[lastn].digest, dupitems[n].digest, 20));
          putc ('\n', outfp);
          n--;
        }
    }

  free (dupitems);

  return rc;
}
Пример #4
0
/* Note: When in ephemeral mode the search function does visit all
   blobs but in standard mode, blobs flagged as ephemeral are ignored.  */
int
keybox_search (KEYBOX_HANDLE hd, KEYBOX_SEARCH_DESC *desc, size_t ndesc)
{
  int rc;
  size_t n;
  int need_words, any_skip;
  KEYBOXBLOB blob = NULL;
  struct sn_array_s *sn_array = NULL;

  if (!hd)
    return gpg_error (GPG_ERR_INV_VALUE);

  /* clear last found result */
  if (hd->found.blob)
    {
      _keybox_release_blob (hd->found.blob);
      hd->found.blob = NULL;
    }

  if (hd->error)
    return hd->error; /* still in error state */
  if (hd->eof)
    return -1; /* still EOF */

  /* figure out what information we need */
  need_words = any_skip = 0;
  for (n=0; n < ndesc; n++)
    {
      switch (desc[n].mode)
        {
        case KEYDB_SEARCH_MODE_WORDS:
          need_words = 1;
          break;
        case KEYDB_SEARCH_MODE_FIRST:
          /* always restart the search in this mode */
          keybox_search_reset (hd);
          break;
        default:
          break;
	}
      if (desc[n].skipfnc)
        any_skip = 1;
      if (desc[n].snlen == -1 && !sn_array)
        {
          sn_array = xtrycalloc (ndesc, sizeof *sn_array);
          if (!sn_array)
            return (hd->error = gpg_error_from_syserror ());
        }
    }

  (void)need_words;  /* Not yet implemented.  */

  if (!hd->fp)
    {
      hd->fp = fopen (hd->kb->fname, "rb");
      if (!hd->fp)
        {
          hd->error = gpg_error_from_syserror ();
          xfree (sn_array);
          return hd->error;
        }
    }

  /* Kludge: We need to convert an SN given as hexstring to its binary
     representation - in some cases we are not able to store it in the
     search descriptor, because due to the way we use it, it is not
     possible to free allocated memory. */
  if (sn_array)
    {
      const unsigned char *s;
      int i, odd;
      size_t snlen;

      for (n=0; n < ndesc; n++)
        {
          if (!desc[n].sn)
            ;
          else if (desc[n].snlen == -1)
            {
              unsigned char *sn;

              s = desc[n].sn;
              for (i=0; *s && *s != '/'; s++, i++)
                ;
              odd = (i & 1);
              snlen = (i+1)/2;
              sn_array[n].sn = xtrymalloc (snlen);
              if (!sn_array[n].sn)
                {
                  hd->error = gpg_error_from_syserror ();
                  release_sn_array (sn_array, n);
                  return hd->error;
                }
              sn_array[n].snlen = snlen;
              sn = sn_array[n].sn;
              s = desc[n].sn;
              if (odd)
                {
                  *sn++ = xtoi_1 (s);
                  s++;
                }
              for (; *s && *s != '/';  s += 2)
                *sn++ = xtoi_2 (s);
            }
          else
            {
              const unsigned char *sn;

              sn = desc[n].sn;
              snlen = desc[n].snlen;
              sn_array[n].sn = xtrymalloc (snlen);
              if (!sn_array[n].sn)
                {
                  hd->error = gpg_error_from_syserror ();
                  release_sn_array (sn_array, n);
                  return hd->error;
                }
              sn_array[n].snlen = snlen;
              memcpy (sn_array[n].sn, sn, snlen);
            }
        }
    }


  for (;;)
    {
      unsigned int blobflags;

      _keybox_release_blob (blob); blob = NULL;
      rc = _keybox_read_blob (&blob, hd->fp);
      if (rc)
        break;

      if (blob_get_type (blob) == BLOBTYPE_HEADER)
        continue;


      blobflags = blob_get_blob_flags (blob);
      if (!hd->ephemeral && (blobflags & 2))
        continue; /* Not in ephemeral mode but blob is flagged ephemeral.  */

      for (n=0; n < ndesc; n++)
        {
          switch (desc[n].mode)
            {
            case KEYDB_SEARCH_MODE_NONE:
              never_reached ();
              break;
            case KEYDB_SEARCH_MODE_EXACT:
              if (has_subject_or_alt (blob, desc[n].u.name, 0))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_MAIL:
              if (has_mail (blob, desc[n].u.name, 0))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_MAILSUB:
              if (has_mail (blob, desc[n].u.name, 1))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_SUBSTR:
              if (has_subject_or_alt (blob, desc[n].u.name, 1))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_MAILEND:
            case KEYDB_SEARCH_MODE_WORDS:
              never_reached (); /* not yet implemented */
              break;
            case KEYDB_SEARCH_MODE_ISSUER:
              if (has_issuer (blob, desc[n].u.name))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_ISSUER_SN:
              if (has_issuer_sn (blob, desc[n].u.name,
                                 sn_array? sn_array[n].sn : desc[n].sn,
                                 sn_array? sn_array[n].snlen : desc[n].snlen))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_SN:
              if (has_sn (blob, sn_array? sn_array[n].sn : desc[n].sn,
                                sn_array? sn_array[n].snlen : desc[n].snlen))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_SUBJECT:
              if (has_subject (blob, desc[n].u.name))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_SHORT_KID:
              if (has_short_kid (blob, desc[n].u.kid[1]))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_LONG_KID:
              if (has_long_kid (blob, desc[n].u.kid[0], desc[n].u.kid[1]))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_FPR:
            case KEYDB_SEARCH_MODE_FPR20:
              if (has_fingerprint (blob, desc[n].u.fpr))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_KEYGRIP:
              if (has_keygrip (blob, desc[n].u.grip))
                goto found;
              break;
            case KEYDB_SEARCH_MODE_FIRST:
              goto found;
              break;
            case KEYDB_SEARCH_MODE_NEXT:
              goto found;
              break;
            default:
              rc = gpg_error (GPG_ERR_INV_VALUE);
              goto found;
            }
	}
      continue;
    found:
      for (n=any_skip?0:ndesc; n < ndesc; n++)
        {
/*            if (desc[n].skipfnc */
/*                && desc[n].skipfnc (desc[n].skipfncvalue, aki, NULL)) */
/*              break; */
        }
      if (n == ndesc)
        break; /* got it */
    }

  if (!rc)
    {
      hd->found.blob = blob;
    }
  else if (rc == -1)
    {
      _keybox_release_blob (blob);
      hd->eof = 1;
    }
  else
    {
      _keybox_release_blob (blob);
      hd->error = rc;
    }

  if (sn_array)
    release_sn_array (sn_array, ndesc);

  return rc;
}