Esempio n. 1
0
/* -------------------------------------------------------------------------- *
 * parse a line                                                               *
 * -------------------------------------------------------------------------- */
static int control_parse(control_t *cptr, char *line)
{
  int ac;
  char *av[16];

  ac = strtokenize(line, av, 16);

  if(ac == 0)
    return 0;
  
  return control_exec(cptr, ac, av);
}
Esempio n. 2
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;
}
Esempio n. 3
0
/* Run gpg on KEY and store the primary fingerprint at R_FPR and the
 * list of mailboxes at R_MBOXES.  Returns 0 on success; on error NULL
 * is stored at R_FPR and R_MBOXES and an error code is returned.
 * R_FPR may be NULL if the fingerprint is not needed.  */
gpg_error_t
wks_list_key (estream_t key, char **r_fpr, uidinfo_list_t *r_mboxes)
{
  gpg_error_t err;
  ccparray_t ccp;
  const char **argv;
  estream_t listing;
  char *line = NULL;
  size_t length_of_line = 0;
  size_t  maxlen;
  ssize_t len;
  char **fields = NULL;
  int nfields;
  int lnr;
  char *fpr = NULL;
  uidinfo_list_t mboxes = NULL;

  if (r_fpr)
    *r_fpr = NULL;
  *r_mboxes = NULL;

  /* Open a memory stream.  */
  listing = es_fopenmem (0, "w+b");
  if (!listing)
    {
      err = gpg_error_from_syserror ();
      log_error ("error allocating memory buffer: %s\n", gpg_strerror (err));
      return err;
    }

  ccparray_init (&ccp, 0);

  ccparray_put (&ccp, "--no-options");
  if (!opt.verbose)
    ccparray_put (&ccp, "--quiet");
  else if (opt.verbose > 1)
    ccparray_put (&ccp, "--verbose");
  ccparray_put (&ccp, "--batch");
  ccparray_put (&ccp, "--status-fd=2");
  ccparray_put (&ccp, "--always-trust");
  ccparray_put (&ccp, "--with-colons");
  ccparray_put (&ccp, "--dry-run");
  ccparray_put (&ccp, "--import-options=import-minimal,import-show");
  ccparray_put (&ccp, "--import");

  ccparray_put (&ccp, NULL);
  argv = ccparray_get (&ccp, NULL);
  if (!argv)
    {
      err = gpg_error_from_syserror ();
      goto leave;
    }
  err = gnupg_exec_tool_stream (opt.gpg_program, argv, key,
                                NULL, listing,
                                key_status_cb, NULL);
  if (err)
    {
      log_error ("import failed: %s\n", gpg_strerror (err));
      goto leave;
    }

  es_rewind (listing);
  lnr = 0;
  maxlen = 2048; /* Set limit.  */
  while ((len = es_read_line (listing, &line, &length_of_line, &maxlen)) > 0)
    {
      lnr++;
      if (!maxlen)
        {
          log_error ("received line too long\n");
          err = gpg_error (GPG_ERR_LINE_TOO_LONG);
          goto leave;
        }
      /* Strip newline and carriage return, if present.  */
      while (len > 0
	     && (line[len - 1] == '\n' || line[len - 1] == '\r'))
	line[--len] = '\0';
      /* log_debug ("line '%s'\n", line); */

      xfree (fields);
      fields = strtokenize (line, ":");
      if (!fields)
        {
          err = gpg_error_from_syserror ();
          log_error ("strtokenize failed: %s\n", gpg_strerror (err));
          goto leave;
        }
      for (nfields = 0; fields[nfields]; nfields++)
        ;
      if (!nfields)
        {
          err = gpg_error (GPG_ERR_INV_ENGINE);
          goto leave;
        }
      if (!strcmp (fields[0], "sec"))
        {
          /* gpg may return "sec" as the first record - but we do not
           * accept secret keys.  */
          err = gpg_error (GPG_ERR_NO_PUBKEY);
          goto leave;
        }
      if (lnr == 1 && strcmp (fields[0], "pub"))
        {
          /* First record is not a public key.  */
          err = gpg_error (GPG_ERR_INV_ENGINE);
          goto leave;
        }
      if (lnr > 1 && !strcmp (fields[0], "pub"))
        {
          /* More than one public key.  */
          err = gpg_error (GPG_ERR_TOO_MANY);
          goto leave;
        }
      if (!strcmp (fields[0], "sub") || !strcmp (fields[0], "ssb"))
        break; /* We can stop parsing here.  */

      if (!strcmp (fields[0], "fpr") && nfields > 9 && !fpr)
        {
          fpr = xtrystrdup (fields[9]);
          if (!fpr)
            {
              err = gpg_error_from_syserror ();
              goto leave;
            }
        }
      else if (!strcmp (fields[0], "uid") && nfields > 9)
        {
          /* Fixme: Unescape fields[9] */
          if (!append_to_uidinfo_list (&mboxes, fields[9],
                                       parse_timestamp (fields[5], NULL)))
            {
              err = gpg_error_from_syserror ();
              goto leave;
            }
        }
    }
  if (len < 0 || es_ferror (listing))
    {
      err = gpg_error_from_syserror ();
      log_error ("error reading memory stream\n");
      goto leave;
    }

  if (!fpr)
    {
      err = gpg_error (GPG_ERR_NO_PUBKEY);
      goto leave;
    }

  if (r_fpr)
    {
      *r_fpr = fpr;
      fpr = NULL;
    }
  *r_mboxes = mboxes;
  mboxes = NULL;

 leave:
  xfree (fpr);
  free_uidinfo_list (mboxes);
  xfree (fields);
  es_free (line);
  xfree (argv);
  es_fclose (listing);
  return err;
}