int
tdbio_set_dbname( const char *new_dbname, int create )
{
    char *fname;
    static int initialized = 0;

    if( !initialized ) {
	atexit( cleanup );
	initialized = 1;
    }

    if(new_dbname==NULL)
      fname=make_filename(opt.homedir,"trustdb" EXTSEP_S "gpg", NULL);
    else if (*new_dbname != DIRSEP_C )
      {
	if (strchr(new_dbname, DIRSEP_C) )
	  fname = make_filename (new_dbname, NULL);
	else
	  fname = make_filename (opt.homedir, new_dbname, NULL);
      }
    else
      fname = xstrdup (new_dbname);

    if( access( fname, R_OK ) ) {
	if( errno != ENOENT ) {
	    log_error( _("can't access `%s': %s\n"), fname, strerror(errno) );
	    xfree(fname);
	    return G10ERR_TRUSTDB;
	}
	if( create ) {
	    FILE *fp;
	    TRUSTREC rec;
	    int rc;
	    char *p = strrchr( fname, DIRSEP_C );
	    mode_t oldmask;

	    assert(p);
	    *p = 0;
	    if( access( fname, F_OK ) ) {
		try_make_homedir( fname );
		log_fatal( _("%s: directory does not exist!\n"), fname );
	    }
	    *p = DIRSEP_C;

	    xfree(db_name);
	    db_name = fname;
#ifdef __riscos__
	    if( !lockhandle )
		lockhandle = create_dotlock( db_name );
	    if( !lockhandle )
		log_fatal( _("can't create lock for `%s'\n"), db_name );
            if( make_dotlock( lockhandle, -1 ) )
                log_fatal( _("can't lock `%s'\n"), db_name );
#endif /* __riscos__ */
	    oldmask=umask(077);
            if (is_secured_filename (fname)) {
                fp = NULL;
                errno = EPERM;
            }
            else
                fp =fopen( fname, "wb" );
	    umask(oldmask);
	    if( !fp )
		log_fatal( _("can't create `%s': %s\n"), fname, strerror(errno) );
	    fclose(fp);
	    db_fd = open( db_name, O_RDWR | MY_O_BINARY );
	    if( db_fd == -1 )
		log_fatal( _("can't open `%s': %s\n"), db_name, strerror(errno) );

#ifndef __riscos__
	    if( !lockhandle )
		lockhandle = create_dotlock( db_name );
	    if( !lockhandle )
		log_fatal( _("can't create lock for `%s'\n"), db_name );
#endif /* !__riscos__ */

            rc = create_version_record ();
	    if( rc )
		log_fatal( _("%s: failed to create version record: %s"),
						   fname, g10_errstr(rc));
	    /* and read again to check that we are okay */
	    if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
		log_fatal( _("%s: invalid trustdb created\n"), db_name );

	    if( !opt.quiet )
		log_info(_("%s: trustdb created\n"), db_name);

	    return 0;
	}
    }
    xfree(db_name);
    db_name = fname;
    return 0;
}
Пример #2
0
int
tdbio_set_dbname( const char *new_dbname, int create, int *r_nofile)
{
    char *fname;
    struct stat statbuf;
    static int initialized = 0;

    if( !initialized ) {
	atexit( cleanup );
	initialized = 1;
    }

    *r_nofile = 0;

    if(new_dbname==NULL)
      fname=make_filename(opt.homedir,"trustdb" EXTSEP_S "gpg", NULL);
    else if (*new_dbname != DIRSEP_C )
      {
	if (strchr(new_dbname, DIRSEP_C) )
	  fname = make_filename (new_dbname, NULL);
	else
	  fname = make_filename (opt.homedir, new_dbname, NULL);
      }
    else
      fname = xstrdup (new_dbname);

    xfree (db_name);
    db_name = fname;

    /*
     * Quick check for (likely) case where there is trustdb.gpg
     * already.  This check is not required in theory, but it helps in
     * practice, avoiding costly operations of preparing and taking
     * the lock.
     */
    if (stat (fname, &statbuf) == 0 && statbuf.st_size > 0)
      /* OK, we have the valid trustdb.gpg already.  */
      return 0;

    take_write_lock ();

    if( access( fname, R_OK ) ) {
        if( errno != ENOENT )
            log_fatal( _("can't access `%s': %s\n"), fname, strerror(errno) );

	if (!create)
          *r_nofile = 1;
        else {
	    FILE *fp;
	    TRUSTREC rec;
	    int rc;
	    char *p = strrchr( fname, DIRSEP_C );
	    mode_t oldmask;
            int save_slash;

#if HAVE_W32_SYSTEM
            {
              /* Windows may either have a slash or a backslash.  Take
                 care of it.  */
              char *pp = strrchr (fname, '/');
              if (!p || pp > p)
                p = pp;
            }
#endif /*HAVE_W32_SYSTEM*/
	    assert (p);
            save_slash = *p;
	    *p = 0;
	    if( access( fname, F_OK ) ) {
		try_make_homedir( fname );
                if (access (fname, F_OK ))
                  log_fatal (_("%s: directory does not exist!\n"), fname);
	    }
	    *p = save_slash;

	    oldmask=umask(077);
            if (is_secured_filename (fname)) {
                fp = NULL;
                errno = EPERM;
            }
            else
                fp =fopen( fname, "wb" );
	    umask(oldmask);
	    if( !fp )
		log_fatal( _("can't create `%s': %s\n"), fname, strerror(errno) );
	    fclose(fp);
	    db_fd = open( db_name, O_RDWR | MY_O_BINARY );
	    if( db_fd == -1 )
		log_fatal( _("can't open `%s': %s\n"), db_name, strerror(errno) );

            rc = create_version_record ();
	    if( rc )
		log_fatal( _("%s: failed to create version record: %s"),
						   fname, g10_errstr(rc));
	    /* and read again to check that we are okay */
	    if( tdbio_read_record( 0, &rec, RECTYPE_VER ) )
		log_fatal( _("%s: invalid trustdb created\n"), db_name );

	    if( !opt.quiet )
		log_info(_("%s: trustdb created\n"), db_name);
	}
    }

    release_write_lock ();
    return 0;
}
/*
 * Migrate the trustdb as just up to gpg 1.0.6 (trustdb version 2)
 * to the 2.1 version as used with 1.0.6b - This is pretty trivial as needs
 * only to scan the tdb and insert new the new trust records.  The old ones are
 * obsolte from now on
 */
static void
migrate_from_v2 ()
{
  TRUSTREC rec;
  int i, n;
  struct {
    ulong keyrecno;
    byte  ot;
    byte okay;
    byte  fpr[20];
  } *ottable;
  int ottable_size, ottable_used;
  byte oldbuf[40];
  ulong recno;
  int rc, count;

  ottable_size = 5;
  ottable = xmalloc (ottable_size * sizeof *ottable);
  ottable_used = 0;

  /* We have some restrictions here.  We can't use the version record
   * and we can't use any of the old hashtables because we dropped the
   * code.  So we first collect all ownertrusts and then use a second
   * pass fo find the associated keys.  We have to do this all without using 
   * the regular record read functions.
   */

  /* get all the ownertrusts */
  if (lseek (db_fd, 0, SEEK_SET ) == -1 ) 
      log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno));
  for (recno=0;;recno++)
    {
      do
        n = read (db_fd, oldbuf, 40);
      while (n==-1 && errno == EINTR);
      if (!n)
        break; /* eof */
      if (n != 40)
        log_fatal ("migrate_vfrom_v2: read error or short read\n");

      if (*oldbuf != 2)
        continue;
      
      /* v2 dir record */
      if (ottable_used == ottable_size)
        {
          ottable_size += 1000;
          ottable = xrealloc (ottable, ottable_size * sizeof *ottable);
        }
      ottable[ottable_used].keyrecno = buftoulong (oldbuf+6);
      ottable[ottable_used].ot = oldbuf[18];
      ottable[ottable_used].okay = 0;
      memset (ottable[ottable_used].fpr,0, 20);
      if (ottable[ottable_used].keyrecno && ottable[ottable_used].ot)
        ottable_used++;
    }
  log_info ("found %d ownertrust records\n", ottable_used);

  /* Read again and find the fingerprints */
  if (lseek (db_fd, 0, SEEK_SET ) == -1 ) 
      log_fatal ("migrate_from_v2: lseek failed: %s\n", strerror (errno));
  for (recno=0;;recno++)
    {
      do
        n = read (db_fd, oldbuf, 40);
      while (n==-1 && errno == EINTR);
      if (!n)
        break; /* eof */
      if (n != 40)
        log_fatal ("migrate_from_v2: read error or short read\n");

      if (*oldbuf != 3) 
        continue;

      /* v2 key record */
      for (i=0; i < ottable_used; i++)
        {
          if (ottable[i].keyrecno == recno)
            {
              memcpy (ottable[i].fpr, oldbuf+20, 20);
              ottable[i].okay = 1;
              break;
            }
        }
    }

  /* got everything - create the v3 trustdb */
  if (ftruncate (db_fd, 0))
    log_fatal ("can't truncate `%s': %s\n", db_name, strerror (errno) );
  if (create_version_record ())
    log_fatal ("failed to recreate version record of `%s'\n", db_name);

  /* access the hash table, so it is store just after the version record, 
   * this is not needed put a dump is more pretty */
  get_trusthashrec ();

  /* And insert the old ownertrust values */
  count = 0;
  for (i=0; i < ottable_used; i++)
    {
      if (!ottable[i].okay)
        continue;
      
      memset (&rec, 0, sizeof rec);
      rec.recnum = tdbio_new_recnum ();
      rec.rectype = RECTYPE_TRUST;
      memcpy(rec.r.trust.fingerprint, ottable[i].fpr, 20);
      rec.r.trust.ownertrust = ottable[i].ot;
      if (tdbio_write_record (&rec))
        log_fatal ("failed to write trust record of `%s'\n", db_name);
      count++;
    }

  revalidation_mark ();
  rc = tdbio_sync ();
  if (rc)
    log_fatal ("failed to sync `%s'\n", db_name);
  log_info ("migrated %d version 2 ownertrusts\n", count);
  xfree (ottable);
}
Пример #4
0
/*
 * Set the file name for the trustdb to NEW_DBNAME and if CREATE is
 * true create that file.  If NEW_DBNAME is NULL a default name is
 * used, if the it does not contain a path component separator ('/')
 * the global GnuPG home directory is used.
 *
 * Returns: 0 on success or an error code.
 *
 * On the first call this function registers an atexit handler.
 *
 */
int
tdbio_set_dbname (const char *new_dbname, int create, int *r_nofile)
{
  char *fname, *p;
  struct stat statbuf;
  static int initialized = 0;
  int save_slash;

  if (!initialized)
    {
      atexit (cleanup);
      initialized = 1;
    }

  *r_nofile = 0;

  if (!new_dbname)
    {
      fname = make_filename (opt.homedir, "trustdb" EXTSEP_S GPGEXT_GPG, NULL);
    }
  else if (*new_dbname != DIRSEP_C )
    {
      if (strchr (new_dbname, DIRSEP_C))
        fname = make_filename (new_dbname, NULL);
      else
        fname = make_filename (opt.homedir, new_dbname, NULL);
    }
  else
    {
      fname = xstrdup (new_dbname);
    }

  xfree (db_name);
  db_name = fname;

  /* Quick check for (likely) case where there already is a
   * trustdb.gpg.  This check is not required in theory, but it helps
   * in practice avoiding costly operations of preparing and taking
   * the lock.  */
  if (!stat (fname, &statbuf) && statbuf.st_size > 0)
    {
      /* OK, we have the valid trustdb.gpg already.  */
      return 0;
    }
  else if (!create)
    {
      *r_nofile = 1;
      return 0;
    }

  /* Here comes: No valid trustdb.gpg AND CREATE==1 */

  /*
   * Make sure the directory exists.  This should be done before
   * acquiring the lock, which assumes the existence of the directory.
   */
  p = strrchr (fname, DIRSEP_C);
#if HAVE_W32_SYSTEM
  {
    /* Windows may either have a slash or a backslash.  Take
       care of it.  */
    char *pp = strrchr (fname, '/');
    if (!p || pp > p)
      p = pp;
  }
#endif /*HAVE_W32_SYSTEM*/
  assert (p);
  save_slash = *p;
  *p = 0;
  if (access (fname, F_OK))
    {
      try_make_homedir (fname);
      if (access (fname, F_OK))
        log_fatal (_("%s: directory does not exist!\n"), fname);
    }
  *p = save_slash;

  take_write_lock ();

  if (access (fname, R_OK))
    {
      FILE *fp;
      TRUSTREC rec;
      int rc;
      mode_t oldmask;

#ifdef HAVE_W32CE_SYSTEM
      /* We know how the cegcc implementation of access works ;-). */
      if (GetLastError () == ERROR_FILE_NOT_FOUND)
        gpg_err_set_errno (ENOENT);
      else
        gpg_err_set_errno (EIO);
#endif /*HAVE_W32CE_SYSTEM*/
      if (errno != ENOENT)
        log_fatal ( _("can't access '%s': %s\n"), fname, strerror (errno));

      oldmask = umask (077);
      if (is_secured_filename (fname))
        {
          fp = NULL;
          gpg_err_set_errno (EPERM);
        }
      else
        fp = fopen (fname, "wb");
      umask(oldmask);
      if (!fp)
        log_fatal (_("can't create '%s': %s\n"), fname, strerror (errno));
      fclose (fp);

      db_fd = open (db_name, O_RDWR | MY_O_BINARY);
      if (db_fd == -1)
        log_fatal (_("can't open '%s': %s\n"), db_name, strerror (errno));

      rc = create_version_record ();
      if (rc)
        log_fatal (_("%s: failed to create version record: %s"),
                   fname, gpg_strerror (rc));

      /* Read again to check that we are okay. */
      if (tdbio_read_record (0, &rec, RECTYPE_VER))
        log_fatal (_("%s: invalid trustdb created\n"), db_name);

      if (!opt.quiet)
        log_info (_("%s: trustdb created\n"), db_name);
    }

  release_write_lock ();
  return 0;
}