示例#1
0
文件: certcache.c 项目: 0ndorio/gnupg
/* Initialize the certificate cache if not yet done.  */
void
cert_cache_init (void)
{
  char *dname;

  if (initialization_done)
    return;
  init_cache_lock ();
  acquire_cache_write_lock ();

  dname = make_filename (gnupg_sysconfdir (), "trusted-certs", NULL);
  load_certs_from_dir (dname, 1);
  xfree (dname);

  dname = make_filename (gnupg_sysconfdir (), "extra-certs", NULL);
  load_certs_from_dir (dname, 0);
  xfree (dname);

  initialization_done = 1;
  release_cache_lock ();

  cert_cache_print_stats ();
}
示例#2
0
void
g13_syshelp_i_know_what_i_am_doing (void)
{
  const char * const yesfile = "Yes-g13-I-know-what-I-am-doing";
  char *fname;

  fname = make_filename (gnupg_sysconfdir (), yesfile, NULL);
  if (access (fname, F_OK))
    {
      log_info ("*******************************************************\n");
      log_info ("* The G13 support for DM-Crypt is new and not matured.\n");
      log_info ("* Bugs or improper use may delete all your disks!\n");
      log_info ("* To confirm that you are ware of this risk, create\n");
      log_info ("* the file '%s'.\n", fname);
      log_info ("*******************************************************\n");
      exit (1);
    }
  xfree (fname);
}
示例#3
0
char *
gnupg_get_help_string (const char *key, int only_current_locale)
{
  static const char *locname;
  char *result;

  if (!locname)
    {
      char *buffer, *p;
      int count = 0;
      const char *s = gnupg_messages_locale_name ();
      buffer = xtrystrdup (s);
      if (!buffer)
        locname = "";
      else
        {
          for (p = buffer; *p; p++)
            if (*p == '.' || *p == '@' || *p == '/' /*(safeguard)*/)
              *p = 0;
            else if (*p == '_')
              {
                if (count++)
                  *p = 0;  /* Also cut at a underscore in the territory.  */
              }
          locname = buffer;
        }
    }

  if (!key || !*key)
    return NULL;

  result = findkey_locale (key, locname, only_current_locale, 
                           gnupg_sysconfdir ());
  if (!result)
    result = findkey_locale (key, locname, only_current_locale,
                             gnupg_datadir ());

  if (result)
    trim_trailing_spaces (result);

  return result;
}
示例#4
0
/* Parse the /etc/gnupg/g13tab for user USERNAME.  Return a table for
   the user on success.  Return NULL on error and print
   diagnostics. */
static tab_item_t
parse_g13tab (const char *username)
{
  gpg_error_t err;
  int c, n;
  char line[512];
  char *p;
  char *fname;
  estream_t fp;
  int lnr;
  char **words = NULL;
  tab_item_t table = NULL;
  tab_item_t *tabletail, ti;

  fname = make_filename (gnupg_sysconfdir (), G13_NAME"tab", NULL);
  fp = es_fopen (fname, "r");
  if (!fp)
    {
      err = gpg_error_from_syserror ();
      log_error (_("error opening '%s': %s\n"), fname, gpg_strerror (err));
      goto leave;
    }

  tabletail = &table;
  err = 0;
  lnr = 0;
  while (es_fgets (line, DIM(line)-1, fp))
    {
      lnr++;
      n = strlen (line);
      if (!n || line[n-1] != '\n')
        {
          /* Eat until end of line. */
          while ((c=es_getc (fp)) != EOF && c != '\n')
            ;
          err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
                           : GPG_ERR_INCOMPLETE_LINE);
          log_error (_("file '%s', line %d: %s\n"),
                     fname, lnr, gpg_strerror (err));
          continue;
        }
      line[--n] = 0; /* Chop the LF. */
      if (n && line[n-1] == '\r')
        line[--n] = 0; /* Chop an optional CR. */

      /* Allow for empty lines and spaces */
      for (p=line; spacep (p); p++)
        ;
      if (!*p || *p == '#')
        continue;

      /* Parse the line.  The format is
       * <username> <blockdev> [<label>|"-" [<mountpoint>]]
       */
      xfree (words);
      words = strtokenize (p, " \t");
      if (!words)
        {
          err = gpg_error_from_syserror ();
          break;
        }
      if (!words[0] || !words[1])
        {
          log_error (_("file '%s', line %d: %s\n"),
                     fname, lnr, gpg_strerror (GPG_ERR_SYNTAX));
          continue;
        }
      if (!(*words[1] == '/'
            || !strncmp (words[1], "PARTUUID=", 9)
            || !strncmp (words[1], "partuuid=", 9)))
        {
          log_error (_("file '%s', line %d: %s\n"),
                     fname, lnr, "Invalid block device syntax");
          continue;
        }
      if (words[2])
        {
          if (strlen (words[2]) > 16 || strchr (words[2], '/'))
            {
              log_error (_("file '%s', line %d: %s\n"),
                         fname, lnr, "Label too long or invalid syntax");
              continue;
            }

          if (words[3] && *words[3] != '/')
            {
              log_error (_("file '%s', line %d: %s\n"),
                         fname, lnr, "Invalid mountpoint syntax");
              continue;
            }
        }
      if (strcmp (words[0], username))
        continue; /* Skip entries for other usernames!  */

      ti = xtrymalloc (sizeof *ti + strlen (words[1]));
      if (!ti)
        {
          err = gpg_error_from_syserror ();
          break;
        }
      ti->next = NULL;
      ti->label = NULL;
      ti->mountpoint = NULL;
      strcpy (ti->blockdev, *words[1]=='/'? words[1] : words[1]+9);
      if (words[2])
        {
          if (strcmp (words[2], "-")
              && !(ti->label = xtrystrdup (words[2])))
            {
              err = gpg_error_from_syserror ();
              xfree (ti);
              break;
            }
          if (words[3] && !(ti->mountpoint = xtrystrdup (words[3])))
            {
              err = gpg_error_from_syserror ();
              xfree (ti->label);
              xfree (ti);
              break;
            }
        }
      *tabletail = ti;
      tabletail = &ti->next;
    }

  if (!err && !es_feof (fp))
    err = gpg_error_from_syserror ();
  if (err)
    log_error (_("error reading '%s', line %d: %s\n"),
               fname, lnr, gpg_strerror (err));

 leave:
  xfree (words);
  es_fclose (fp);
  xfree (fname);
  if (err)
    {
      release_tab_items (table);
      return NULL;
    }
  return table;
}
示例#5
0
int
main ( int argc, char **argv)
{
  ARGPARSE_ARGS pargs;
  int orig_argc;
  char **orig_argv;
  gpg_error_t err = 0;
  /* const char *fname; */
  int may_coredump;
  FILE *configfp = NULL;
  char *configname = NULL;
  unsigned configlineno;
  int parse_debug = 0;
  int no_more_options = 0;
  int default_config =1;
  char *logfile = NULL;
  /* int debug_wait = 0; */
  int use_random_seed = 1;
  /* int nodetach = 0; */
  /* int nokeysetup = 0; */
  struct server_control_s ctrl;

  /*mtrace();*/

  early_system_init ();
  gnupg_reopen_std (G13_NAME "-syshelp");
  set_strusage (my_strusage);
  gcry_control (GCRYCTL_SUSPEND_SECMEM_WARN);

  log_set_prefix (G13_NAME "-syshelp", 1);

  /* Make sure that our subsystems are ready.  */
  i18n_init ();
  init_common_subsystems (&argc, &argv);

  /* Check that the Libgcrypt is suitable.  */
  if (!gcry_check_version (NEED_LIBGCRYPT_VERSION) )
    log_fatal (_("%s is too old (need %s, have %s)\n"), "libgcrypt",
               NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );

  /* Take extra care of the random pool.  */
  gcry_control (GCRYCTL_USE_SECURE_RNDPOOL);

  may_coredump = disable_core_dumps ();

  g13_init_signals ();

  dotlock_create (NULL, 0); /* Register locking cleanup.  */

  opt.session_env = session_env_new ();
  if (!opt.session_env)
    log_fatal ("error allocating session environment block: %s\n",
               strerror (errno));

  opt.homedir = default_homedir ();
  /* Fixme: We enable verbose mode here because there is currently no
     way to do this when starting g13-syshelp.  To fix that we should
     add a g13-syshelp.conf file in /etc/gnupg.  */
  opt.verbose = 1;

  /* First check whether we have a debug option on the commandline.  */
  orig_argc = argc;
  orig_argv = argv;
  pargs.argc = &argc;
  pargs.argv = &argv;
  pargs.flags= (ARGPARSE_FLAG_KEEP | ARGPARSE_FLAG_NOVERSION);
  while (arg_parse( &pargs, opts))
    {
      if (pargs.r_opt == oDebug || pargs.r_opt == oDebugAll)
        parse_debug++;
    }

  /* Initialize the secure memory. */
  gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
  maybe_setuid = 0;

  /*
     Now we are now working under our real uid
  */

  /* Setup malloc hooks. */
  {
    struct assuan_malloc_hooks malloc_hooks;

    malloc_hooks.malloc = gcry_malloc;
    malloc_hooks.realloc = gcry_realloc;
    malloc_hooks.free = gcry_free;
    assuan_set_malloc_hooks (&malloc_hooks);
  }

  /* Prepare libassuan.  */
  assuan_set_gpg_err_source (GPG_ERR_SOURCE_DEFAULT);
  /*assuan_set_system_hooks (ASSUAN_SYSTEM_NPTH);*/
  setup_libassuan_logging (&opt.debug);

  /* Setup a default control structure for command line mode.  */
  memset (&ctrl, 0, sizeof ctrl);
  g13_syshelp_init_default_ctrl (&ctrl);
  ctrl.no_server = 1;
  ctrl.status_fd = -1; /* No status output. */

  if (default_config )
    configname = make_filename (gnupg_sysconfdir (),
                                G13_NAME"-syshelp.conf", NULL);

  argc        = orig_argc;
  argv        = orig_argv;
  pargs.argc  = &argc;
  pargs.argv  = &argv;
  pargs.flags =  1;  /* Do not remove the args.  */

 next_pass:
  if (configname)
    {
      configlineno = 0;
      configfp = fopen (configname, "r");
      if (!configfp)
        {
          if (default_config)
            {
              if (parse_debug)
                log_info (_("NOTE: no default option file '%s'\n"), configname);
            }
          else
            {
              log_error (_("option file '%s': %s\n"),
                         configname, strerror(errno));
              g13_exit(2);
            }
          xfree (configname);
          configname = NULL;
        }
      if (parse_debug && configname)
        log_info (_("reading options from '%s'\n"), configname);
      default_config = 0;
    }

  while (!no_more_options
         && optfile_parse (configfp, configname, &configlineno, &pargs, opts))
    {
      switch (pargs.r_opt)
        {
        case oQuiet: opt.quiet = 1; break;

        case oDryRun: opt.dry_run = 1; break;

        case oVerbose:
          opt.verbose++;
          gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
          break;
        case oNoVerbose:
          opt.verbose = 0;
          gcry_control (GCRYCTL_SET_VERBOSITY, (int)opt.verbose);
          break;

        case oLogFile: logfile = pargs.r.ret_str; break;
        case oNoLogFile: logfile = NULL; break;

        case oNoDetach: /*nodetach = 1; */break;

        case oDebug:
          if (parse_debug_flag (pargs.r.ret_str, &opt.debug, debug_flags))
            {
              pargs.r_opt = ARGPARSE_INVALID_ARG;
              pargs.err = ARGPARSE_PRINT_ERROR;
            }
            break;
        case oDebugAll: debug_value = ~0; break;
        case oDebugNone: debug_value = 0; break;
        case oDebugLevel: debug_level = pargs.r.ret_str; break;
        case oDebugWait: /*debug_wait = pargs.r.ret_int; */break;
        case oDebugAllowCoreDump:
          may_coredump = enable_core_dumps ();
          break;

        case oStatusFD: ctrl.status_fd = pargs.r.ret_int; break;
        case oLoggerFD: log_set_fd (pargs.r.ret_int ); break;

        case oHomedir: opt.homedir = pargs.r.ret_str; break;

        case oFakedSystemTime:
          {
            time_t faked_time = isotime2epoch (pargs.r.ret_str);
            if (faked_time == (time_t)(-1))
              faked_time = (time_t)strtoul (pargs.r.ret_str, NULL, 10);
            gnupg_set_time (faked_time, 0);
          }
          break;

        case oNoSecmemWarn: gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); break;

        case oNoRandomSeedFile: use_random_seed = 0; break;

        default:
          pargs.err = configfp? ARGPARSE_PRINT_WARNING:ARGPARSE_PRINT_ERROR;
          break;
	}
    }

  if (configfp)
    {
      fclose (configfp);
      configfp = NULL;
      /* Keep a copy of the config filename. */
      opt.config_filename = configname;
      configname = NULL;
      goto next_pass;
    }
  xfree (configname);
  configname = NULL;

  if (!opt.config_filename)
    opt.config_filename = make_filename (opt.homedir, G13_NAME".conf", NULL);

  if (log_get_errorcount(0))
    g13_exit(2);

  /* Now that we have the options parsed we need to update the default
     control structure.  */
  g13_syshelp_init_default_ctrl (&ctrl);

  if (may_coredump && !opt.quiet)
    log_info (_("WARNING: program may create a core file!\n"));

  if (logfile)
    {
      log_set_file (logfile);
      log_set_prefix (NULL, 1|2|4);
    }

  if (gnupg_faked_time_p ())
    {
      gnupg_isotime_t tbuf;

      log_info (_("WARNING: running with faked system time: "));
      gnupg_get_isotime (tbuf);
      dump_isotime (tbuf);
      log_printf ("\n");
    }

  /* Print any pending secure memory warnings.  */
  gcry_control (GCRYCTL_RESUME_SECMEM_WARN);

  /* Setup the debug flags for all subsystems.  */
  set_debug ();

  /* Install a regular exit handler to make real sure that the secure
     memory gets wiped out.  */
  g13_install_emergency_cleanup ();

  /* Terminate if we found any error until now.  */
  if (log_get_errorcount(0))
    g13_exit (2);

  /* Set the standard GnuPG random seed file.  */
  if (use_random_seed)
    {
      char *p = make_filename (opt.homedir, "random_seed", NULL);
      gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, p);
      xfree(p);
    }

  /* Get the UID of the caller.  */
#if defined(HAVE_PWD_H) && defined(HAVE_GETPWUID)
  {
    const char *uidstr;
    struct passwd *pwd = NULL;

    uidstr = getenv ("USERV_UID");

    /* Print a quick note if we are not started via userv.  */
    if (!uidstr)
      {
        if (getuid ())
          {
            log_info ("WARNING: Not started via userv\n");
            ctrl.fail_all_cmds = 1;
          }
        ctrl.client.uid = getuid ();
      }
    else
      {
        unsigned long myuid;

        errno = 0;
        myuid = strtoul (uidstr, NULL, 10);
        if (myuid == ULONG_MAX && errno)
          {
            log_info ("WARNING: Started via broken userv: %s\n",
                      strerror (errno));
            ctrl.fail_all_cmds = 1;
            ctrl.client.uid = getuid ();
          }
        else
          ctrl.client.uid = (uid_t)myuid;
      }

    pwd = getpwuid (ctrl.client.uid);
    if (!pwd || !*pwd->pw_name)
      {
        log_info ("WARNING: Name for UID not found: %s\n", strerror (errno));
        ctrl.fail_all_cmds = 1;
        ctrl.client.uname = xstrdup ("?");
      }
    else
      ctrl.client.uname = xstrdup (pwd->pw_name);

    /* Check that the user name does not contain a directory
       separator. */
    if (strchr (ctrl.client.uname, '/'))
      {
        log_info ("WARNING: Invalid user name passed\n");
        ctrl.fail_all_cmds = 1;
      }
  }
#else /*!HAVE_PWD_H || !HAVE_GETPWUID*/
  log_info ("WARNING: System does not support required syscalls\n");
  ctrl.fail_all_cmds = 1;
  ctrl.client.uid = getuid ();
  ctrl.client.uname = xstrdup ("?");
#endif /*!HAVE_PWD_H || !HAVE_GETPWUID*/

  /* Read the table entries for this user.  */
  if (!ctrl.fail_all_cmds
      && !(ctrl.client.tab = parse_g13tab (ctrl.client.uname)))
    ctrl.fail_all_cmds = 1;

  /* Start the server.  */
  err = syshelp_server (&ctrl);
  if (err)
    log_error ("server exited with error: %s <%s>\n",
               gpg_strerror (err), gpg_strsource (err));

  /* Cleanup.  */
  g13_syshelp_deinit_default_ctrl (&ctrl);
  g13_exit (0);
  return 8; /*NOTREACHED*/
}
示例#6
0
/* gpgconf main. */
int
main (int argc, char **argv)
{
  ARGPARSE_ARGS pargs;
  const char *fname;
  int no_more_options = 0;
  enum cmd_and_opt_values cmd = 0;
  FILE *outfp = NULL;

  gnupg_reopen_std ("gpgconf");
  set_strusage (my_strusage);
  log_set_prefix ("gpgconf", 1);

  /* Make sure that our subsystems are ready.  */
  i18n_init();
  init_common_subsystems ();

  /* Parse the command line. */
  pargs.argc  = &argc;
  pargs.argv  = &argv;
  pargs.flags =  1;  /* Do not remove the args.  */
  while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts))
    {
      switch (pargs.r_opt)
        {
        case oOutput:    opt.outfile = pargs.r.ret_str; break;
	case oQuiet:     opt.quiet = 1; break;
        case oDryRun:    opt.dry_run = 1; break;
        case oRuntime:
	  opt.runtime = 1;
	  break;
        case oVerbose:   opt.verbose++; break;
        case oNoVerbose: opt.verbose = 0; break;

	case aListDirs:
        case aListComponents:
        case aCheckPrograms:
        case aListOptions:
        case aChangeOptions:
        case aCheckOptions:
        case aApplyDefaults:
        case aListConfig:
        case aCheckConfig:
        case aReload:
	  cmd = pargs.r_opt;
	  break;

        default: pargs.err = 2; break;
	}
    }

  if (log_get_errorcount (0))
    exit (2);
  
  fname = argc ? *argv : NULL;
  
  switch (cmd)
    {
    case aListComponents:
    default:
      /* List all components. */
      gc_component_list_components (get_outfp (&outfp));
      break;

    case aCheckPrograms:
      /* Check all programs. */
      gc_check_programs (get_outfp (&outfp));
      break;

    case aListOptions:
    case aChangeOptions:
    case aCheckOptions:
      if (!fname)
	{
	  fputs (_("usage: gpgconf [options] "), stderr);
	  putc ('\n',stderr);
	  fputs (_("Need one component argument"), stderr);
	  putc ('\n',stderr);
	  exit (2);
	}
      else
	{
	  int idx = gc_component_find (fname);
	  if (idx < 0)
	    {
	      fputs (_("Component not found"), stderr);
	      putc ('\n', stderr);
	      exit (1);
	    }
	  if (cmd == aCheckOptions)
	    gc_component_check_options (idx, get_outfp (&outfp), NULL);
          else
            {
              gc_component_retrieve_options (idx);
              if (gc_process_gpgconf_conf (NULL, 1, 0, NULL))
                exit (1);
              if (cmd == aListOptions)
                gc_component_list_options (idx, get_outfp (&outfp));
              else if (cmd == aChangeOptions)
                gc_component_change_options (idx, stdin, get_outfp (&outfp));
            }
	}
      break;

    case aReload:
      if (!fname)
	{
          /* Reload all.  */
          gc_component_reload (-1);
	}
      else
        {
          /* Reload given component.  */
          int idx;

          idx = gc_component_find (fname);
          if (idx < 0)
            {
              fputs (_("Component not found"), stderr);
              putc ('\n', stderr);
              exit (1);
            }
          else
            {
              gc_component_reload (idx);
            }
        }
      break;

    case aListConfig:
      if (gc_process_gpgconf_conf (fname, 0, 0, get_outfp (&outfp)))
        exit (1);
      break;

    case aCheckConfig:
      if (gc_process_gpgconf_conf (fname, 0, 0, NULL))
        exit (1);
      break;

    case aApplyDefaults:
      if (fname)
	{
	  fputs (_("usage: gpgconf [options] "), stderr);
	  putc ('\n',stderr);
	  fputs (_("No argument allowed"), stderr);
	  putc ('\n',stderr);
	  exit (2);
	}
      gc_component_retrieve_options (-1);
      if (gc_process_gpgconf_conf (NULL, 1, 1, NULL))
        exit (1);
      break;
      
    case aListDirs:
      /* Show the system configuration directories for gpgconf.  */
      get_outfp (&outfp);
      fprintf (outfp, "sysconfdir:%s\n",
	       gc_percent_escape (gnupg_sysconfdir ()));
      fprintf (outfp, "bindir:%s\n",
	       gc_percent_escape (gnupg_bindir ()));
      fprintf (outfp, "libexecdir:%s\n",
	       gc_percent_escape (gnupg_libexecdir ()));
      fprintf (outfp, "libdir:%s\n",
	       gc_percent_escape (gnupg_libdir ()));
      fprintf (outfp, "datadir:%s\n",
	       gc_percent_escape (gnupg_datadir ()));
      fprintf (outfp, "localedir:%s\n",
	       gc_percent_escape (gnupg_localedir ()));
      fprintf (outfp, "dirmngr-socket:%s\n",
	       gc_percent_escape (dirmngr_socket_name ()));
      {
        char *infostr = getenv ("GPG_AGENT_INFO");

        if (!infostr || !*infostr)
          infostr = make_filename (default_homedir (), "S.gpg-agent", NULL);
        else
          {
            char *tmp;

            infostr = xstrdup (infostr);
            tmp = strchr (infostr, PATHSEP_C);
            if (!tmp || tmp == infostr)
              {
                xfree (infostr);
                infostr = NULL;
              }
            else
              *tmp = 0;
          }
        fprintf (outfp, "agent-socket:%s\n",
                 infostr? gc_percent_escape (infostr) : "");
        xfree (infostr);
      }
      {
        /* We need to use make_filename to expand a possible "~/".  */
        char *tmp = make_filename (default_homedir (), NULL);
        fprintf (outfp, "homedir:%s\n", gc_percent_escape (tmp));
        xfree (tmp);
      }
      break;
    }

  if (outfp && outfp != stdout)
    if (fclose (outfp))
      gc_error (1, errno, "error closing `%s'", opt.outfile);

  return 0; 
}
示例#7
0
文件: gpgconf.c 项目: 0ndorio/gnupg
/* gpgconf main. */
int
main (int argc, char **argv)
{
  ARGPARSE_ARGS pargs;
  const char *fname;
  int no_more_options = 0;
  enum cmd_and_opt_values cmd = 0;
  estream_t outfp = NULL;

  early_system_init ();
  gnupg_reopen_std (GPGCONF_NAME);
  set_strusage (my_strusage);
  log_set_prefix (GPGCONF_NAME, 1);

  /* Make sure that our subsystems are ready.  */
  i18n_init();
  init_common_subsystems (&argc, &argv);

  /* Parse the command line. */
  pargs.argc  = &argc;
  pargs.argv  = &argv;
  pargs.flags =  1;  /* Do not remove the args.  */
  while (!no_more_options && optfile_parse (NULL, NULL, NULL, &pargs, opts))
    {
      switch (pargs.r_opt)
        {
        case oOutput:    opt.outfile = pargs.r.ret_str; break;
	case oQuiet:     opt.quiet = 1; break;
        case oDryRun:    opt.dry_run = 1; break;
        case oRuntime:
	  opt.runtime = 1;
	  break;
        case oVerbose:   opt.verbose++; break;
        case oNoVerbose: opt.verbose = 0; break;

	case aListDirs:
        case aListComponents:
        case aCheckPrograms:
        case aListOptions:
        case aChangeOptions:
        case aCheckOptions:
        case aApplyDefaults:
        case aListConfig:
        case aCheckConfig:
        case aReload:
        case aLaunch:
        case aKill:
	  cmd = pargs.r_opt;
	  break;

        default: pargs.err = 2; break;
	}
    }

  if (log_get_errorcount (0))
    exit (2);

  /* Print a warning if an argument looks like an option.  */
  if (!opt.quiet && !(pargs.flags & ARGPARSE_FLAG_STOP_SEEN))
    {
      int i;

      for (i=0; i < argc; i++)
        if (argv[i][0] == '-' && argv[i][1] == '-')
          log_info (_("Note: '%s' is not considered an option\n"), argv[i]);
    }

  fname = argc ? *argv : NULL;

  switch (cmd)
    {
    case aListComponents:
    default:
      /* List all components. */
      gc_component_list_components (get_outfp (&outfp));
      break;

    case aCheckPrograms:
      /* Check all programs. */
      gc_check_programs (get_outfp (&outfp));
      break;

    case aListOptions:
    case aChangeOptions:
    case aCheckOptions:
      if (!fname)
	{
	  es_fprintf (es_stderr, _("usage: %s [options] "), GPGCONF_NAME);
	  es_putc ('\n', es_stderr);
	  es_fputs (_("Need one component argument"), es_stderr);
	  es_putc ('\n', es_stderr);
	  exit (2);
	}
      else
	{
	  int idx = gc_component_find (fname);
	  if (idx < 0)
	    {
	      es_fputs (_("Component not found"), es_stderr);
	      es_putc ('\n', es_stderr);
	      exit (1);
	    }
          if (cmd == aCheckOptions)
	    gc_component_check_options (idx, get_outfp (&outfp), NULL);
          else
            {
              gc_component_retrieve_options (idx);
              if (gc_process_gpgconf_conf (NULL, 1, 0, NULL))
                exit (1);
              if (cmd == aListOptions)
                gc_component_list_options (idx, get_outfp (&outfp));
              else if (cmd == aChangeOptions)
                gc_component_change_options (idx, es_stdin, get_outfp (&outfp));
            }
	}
      break;

    case aLaunch:
    case aKill:
      if (!fname)
	{
	  es_fprintf (es_stderr, _("usage: %s [options] "), GPGCONF_NAME);
	  es_putc ('\n', es_stderr);
	  es_fputs (_("Need one component argument"), es_stderr);
	  es_putc ('\n', es_stderr);
	  exit (2);
	}
      else
        {
          /* Launch/Kill a given component.  */
          int idx;

          idx = gc_component_find (fname);
          if (idx < 0)
            {
              es_fputs (_("Component not found"), es_stderr);
              es_putc ('\n', es_stderr);
              exit (1);
            }
          else if (cmd == aLaunch)
            {
              if (gc_component_launch (idx))
                exit (1);
            }
          else
            {
              /* We don't error out if the kill failed because this
                 command should do nothing if the component is not
                 running.  */
              gc_component_kill (idx);
            }
        }
      break;

    case aReload:
      if (!fname)
	{
          /* Reload all.  */
          gc_component_reload (-1);
	}
      else
        {
          /* Reload given component.  */
          int idx;

          idx = gc_component_find (fname);
          if (idx < 0)
            {
              es_fputs (_("Component not found"), es_stderr);
              es_putc ('\n', es_stderr);
              exit (1);
            }
          else
            {
              gc_component_reload (idx);
            }
        }
      break;

    case aListConfig:
      if (gc_process_gpgconf_conf (fname, 0, 0, get_outfp (&outfp)))
        exit (1);
      break;

    case aCheckConfig:
      if (gc_process_gpgconf_conf (fname, 0, 0, NULL))
        exit (1);
      break;

    case aApplyDefaults:
      if (fname)
	{
	  es_fprintf (es_stderr, _("usage: %s [options] "), GPGCONF_NAME);
	  es_putc ('\n', es_stderr);
	  es_fputs (_("No argument allowed"), es_stderr);
	  es_putc ('\n', es_stderr);
	  exit (2);
	}
      gc_component_retrieve_options (-1);
      if (gc_process_gpgconf_conf (NULL, 1, 1, NULL))
        exit (1);
      break;

    case aListDirs:
      /* Show the system configuration directories for gpgconf.  */
      get_outfp (&outfp);
      es_fprintf (outfp, "sysconfdir:%s\n",
                  gc_percent_escape (gnupg_sysconfdir ()));
      es_fprintf (outfp, "bindir:%s\n",
                  gc_percent_escape (gnupg_bindir ()));
      es_fprintf (outfp, "libexecdir:%s\n",
                  gc_percent_escape (gnupg_libexecdir ()));
      es_fprintf (outfp, "libdir:%s\n",
                  gc_percent_escape (gnupg_libdir ()));
      es_fprintf (outfp, "datadir:%s\n",
                  gc_percent_escape (gnupg_datadir ()));
      es_fprintf (outfp, "localedir:%s\n",
                  gc_percent_escape (gnupg_localedir ()));

      if (dirmngr_user_socket_name ())
        {
          es_fprintf (outfp, "dirmngr-socket:%s\n",
                      gc_percent_escape (dirmngr_user_socket_name ()));
          es_fprintf (outfp, "dirmngr-sys-socket:%s\n",
                      gc_percent_escape (dirmngr_sys_socket_name ()));
        }
      else
        {
          es_fprintf (outfp, "dirmngr-socket:%s\n",
                      gc_percent_escape (dirmngr_sys_socket_name ()));
        }

      {
        char *tmp = make_filename (default_homedir (),
                                   GPG_AGENT_SOCK_NAME, NULL);
        es_fprintf (outfp, "agent-socket:%s\n", gc_percent_escape (tmp));
        xfree (tmp);
      }
      {
        /* We need to use make_filename to expand a possible "~/".  */
        char *tmp = make_filename (default_homedir (), NULL);
        es_fprintf (outfp, "homedir:%s\n", gc_percent_escape (tmp));
        xfree (tmp);
      }
      break;
    }

  if (outfp != es_stdout)
    if (es_fclose (outfp))
      gc_error (1, errno, "error closing '%s'", opt.outfile);

  return 0;
}
示例#8
0
/* Read the trust files and update the global table on success.  */
static gpg_error_t
read_trustfiles (void)
{
  gpg_error_t err;
  trustitem_t *table, *ti;
  int tableidx;
  size_t tablesize;
  char *fname;
  int allow_include = 1;

  tablesize = 20;
  table = xtrycalloc (tablesize, sizeof *table);
  if (!table)
    return gpg_error_from_syserror ();
  tableidx = 0;

  fname = make_filename (opt.homedir, "trustlist.txt", NULL);
  if ( access (fname, F_OK) )
    {
      if ( errno == ENOENT )
        ; /* Silently ignore a non-existing trustfile.  */
      else
        {
          err = gpg_error_from_syserror ();
          log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err));
        }
      xfree (fname);
      fname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL);
      allow_include = 0;
    }
  err = read_one_trustfile (fname, allow_include,
                            &table, &tablesize, &tableidx);
  xfree (fname);

  if (err)
    {
      xfree (table);
      if (gpg_err_code (err) == GPG_ERR_ENOENT)
        {
          /* Take a missing trustlist as an empty one.  */
          lock_trusttable ();
          xfree (trusttable);
          trusttable = NULL;
          trusttablesize = 0;
          unlock_trusttable ();
          err = 0;
        }
      return err;
    }

  /* Fixme: we should drop duplicates and sort the table. */
  ti = xtryrealloc (table, (tableidx?tableidx:1) * sizeof *table);
  if (!ti)
    {
      err = gpg_error_from_syserror ();
      xfree (table);
      return err;
    }

  lock_trusttable ();
  xfree (trusttable);
  trusttable = ti;
  trusttablesize = tableidx;
  unlock_trusttable ();
  return 0;
}
示例#9
0
static gpg_error_t
read_one_trustfile (const char *fname, int allow_include,
                    trustitem_t **addr_of_table,
                    size_t *addr_of_tablesize,
                    int *addr_of_tableidx)
{
  gpg_error_t err = 0;
  estream_t fp;
  int n, c;
  char *p, line[256];
  trustitem_t *table, *ti;
  int tableidx;
  size_t tablesize;
  int lnr = 0;

  table = *addr_of_table;
  tablesize = *addr_of_tablesize;
  tableidx = *addr_of_tableidx;

  fp = es_fopen (fname, "r");
  if (!fp)
    {
      err = gpg_error_from_syserror ();
      log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err));
      goto leave;
    }

  while (es_fgets (line, DIM(line)-1, fp))
    {
      lnr++;

      n = strlen (line);
      if (!n || line[n-1] != '\n')
        {
          /* Eat until end of line. */
          while ( (c=es_getc (fp)) != EOF && c != '\n')
            ;
          err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
                           : GPG_ERR_INCOMPLETE_LINE);
          log_error (_("file `%s', line %d: %s\n"),
                     fname, lnr, gpg_strerror (err));
          continue;
        }
      line[--n] = 0; /* Chop the LF. */
      if (n && line[n-1] == '\r')
        line[--n] = 0; /* Chop an optional CR. */

      /* Allow for empty lines and spaces */
      for (p=line; spacep (p); p++)
        ;
      if (!*p || *p == '#')
        continue;

      if (!strncmp (p, "include-default", 15)
          && (!p[15] || spacep (p+15)))
        {
          char *etcname;
          gpg_error_t err2;

          if (!allow_include)
            {
              log_error (_("statement \"%s\" ignored in `%s', line %d\n"),
                         "include-default", fname, lnr);
              continue;
            }
          /* fixme: Should check for trailing garbage.  */

          etcname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL);
          if ( !strcmp (etcname, fname) ) /* Same file. */
            log_info (_("statement \"%s\" ignored in `%s', line %d\n"),
                      "include-default", fname, lnr);
          else if ( access (etcname, F_OK) && errno == ENOENT )
            {
              /* A non existent system trustlist is not an error.
                 Just print a note. */
              log_info (_("system trustlist `%s' not available\n"), etcname);
            }
          else
            {
              err2 = read_one_trustfile (etcname, 0,
                                         &table, &tablesize, &tableidx);
              if (err2)
                err = err2;
            }
          xfree (etcname);

          continue;
        }

      if (tableidx == tablesize)  /* Need more space. */
        {
          trustitem_t *tmp;
          size_t tmplen;

          tmplen = tablesize + 20;
          tmp = xtryrealloc (table, tmplen * sizeof *table);
          if (!tmp)
            {
              err = gpg_error_from_syserror ();
              goto leave;
            }
          table = tmp;
          tablesize = tmplen;
        }

      ti = table + tableidx;

      memset (&ti->flags, 0, sizeof ti->flags);
      if (*p == '!')
        {
          ti->flags.disabled = 1;
          p++;
          while (spacep (p))
            p++;
        }

      n = hexcolon2bin (p, ti->fpr, 20);
      if (n < 0)
        {
          log_error (_("bad fingerprint in `%s', line %d\n"), fname, lnr);
          err = gpg_error (GPG_ERR_BAD_DATA);
          continue;
        }
      p += n;
      for (; spacep (p); p++)
        ;

      /* Process the first flag which needs to be the first for
         backward compatibility. */
      if (!*p || *p == '*' )
        {
          ti->flags.for_smime = 1;
          ti->flags.for_pgp = 1;
        }
      else if ( *p == 'P' || *p == 'p')
        {
          ti->flags.for_pgp = 1;
        }
      else if ( *p == 'S' || *p == 's')
        {
          ti->flags.for_smime = 1;
        }
      else
        {
          log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr);
          err = gpg_error (GPG_ERR_BAD_DATA);
          continue;
        }
      p++;
      if ( *p && !spacep (p) )
        {
          log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr);
          err = gpg_error (GPG_ERR_BAD_DATA);
          continue;
        }

      /* Now check for more key-value pairs of the form NAME[=VALUE]. */
      while (*p)
        {
          for (; spacep (p); p++)
            ;
          if (!*p)
            break;
          n = strcspn (p, "= \t");
          if (p[n] == '=')
            {
              log_error ("assigning a value to a flag is not yet supported; "
                         "in `%s', line %d\n", fname, lnr);
              err = gpg_error (GPG_ERR_BAD_DATA);
              p++;
            }
          else if (n == 5 && !memcmp (p, "relax", 5))
            ti->flags.relax = 1;
          else if (n == 2 && !memcmp (p, "cm", 2))
            ti->flags.cm = 1;
          else
            log_error ("flag `%.*s' in `%s', line %d ignored\n",
                       n, p, fname, lnr);
          p += n;
        }
      tableidx++;
    }
  if ( !err && !es_feof (fp) )
    {
      err = gpg_error_from_syserror ();
      log_error (_("error reading `%s', line %d: %s\n"),
                 fname, lnr, gpg_strerror (err));
    }

 leave:
  es_fclose (fp);
  *addr_of_table = table;
  *addr_of_tablesize = tablesize;
  *addr_of_tableidx = tableidx;
  return err;
}