Beispiel #1
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;
}
Beispiel #2
0
CURLcode
curl_easy_perform(CURL *curl)
{
  int rc;
  CURLcode err=CURLE_OK;
  const char *errstr=NULL;
  char *proxy=NULL;
  struct http_srv srv;

  memset(&srv,0,sizeof(srv));

  /* Emulate the libcurl proxy behavior.  If the calling program set a
     proxy, use it.  If it didn't set a proxy or set it to NULL, check
     for one in the environment.  If the calling program explicitly
     set a null-string proxy the http code doesn't use a proxy at
     all. */

  if(curl->proxy)
    proxy=curl->proxy;
  else
    proxy=getenv(HTTP_PROXY_ENV);

  if(curl->srvtag)
    srv.srvtag=curl->srvtag;

  if(curl->flags.verbose)
    {
      fprintf(curl->errors,"* HTTP proxy is \"%s\"\n",proxy?proxy:"null");
      fprintf(curl->errors,"* HTTP URL is \"%s\"\n",curl->url);
      if(srv.srvtag)
	fprintf(curl->errors,
		"* SRV tag is \"%s\": host and port may be overridden\n",
		srv.srvtag);
      fprintf(curl->errors,"* HTTP auth is \"%s\"\n",
	      curl->auth?curl->auth:"null");
      fprintf(curl->errors,"* HTTP method is %s\n",
	      curl->flags.post?"POST":"GET");
    }

  if(curl->flags.post)
    {
      rc = http_open (&curl->hd, HTTP_REQ_POST, curl->url, curl->auth,
                      0, proxy, NULL, &srv,
		      curl->headers?curl->headers->list:NULL);
      if (!rc)
	{
	  unsigned int post_len = strlen(curl->postfields);

	  if(curl->flags.verbose && srv.used_server && srv.used_port)
	    fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n",
		     srv.used_server, srv.used_port);

	  es_fprintf (http_get_write_ptr (curl->hd),
                      "Content-Type: application/x-www-form-urlencoded\r\n"
                      "Content-Length: %u\r\n", post_len);
	  http_start_data (curl->hd);
	  es_write (http_get_write_ptr (curl->hd),
                    curl->postfields, post_len, NULL);

	  rc = http_wait_response (curl->hd);
          curl->status = http_get_status_code (curl->hd);
	  if (!rc && curl->flags.failonerror && curl->status>=300)
	    err = CURLE_HTTP_RETURNED_ERROR;
          http_close (curl->hd, 0);
          curl->hd = NULL;
	}
    }
  else
    {
      rc = http_open (&curl->hd, HTTP_REQ_GET, curl->url, curl->auth,
                      0, proxy, NULL, &srv,
		      curl->headers?curl->headers->list:NULL);
      if (!rc)
	{
	  if(curl->flags.verbose && srv.used_server && srv.used_port)
	    fprintf (curl->errors, "* HTTP host:port post-SRV is \"%s:%hu\"\n",
		     srv.used_server, srv.used_port);

	  rc = http_wait_response (curl->hd);
          curl->status = http_get_status_code (curl->hd);
	  if (!rc)
	    {
	      if (curl->flags.failonerror && curl->status>=300)
		err = CURLE_HTTP_RETURNED_ERROR;
	      else
		{
		  size_t maxlen = 1024;
                  size_t buflen;
                  unsigned int len;
		  char *line = NULL;

		  while ((len = es_read_line (http_get_read_ptr (curl->hd),
                                              &line, &buflen, &maxlen)))
		    {
		      size_t ret;

		      maxlen=1024;

		      ret=(curl->writer)(line,len,1,curl->file);
		      if(ret!=len)
			{
			  err=CURLE_WRITE_ERROR;
			  break;
			}
		    }

		  es_free (line);
		  http_close(curl->hd, 0);
                  curl->hd = NULL;
		}
	    }
	  else
            {
              http_close (curl->hd, 0);
              curl->hd = NULL;
            }
	}
    }

  xfree(srv.used_server);

  switch(gpg_err_code (rc))
    {
    case 0:
      break;

    case GPG_ERR_INV_URI:
      err=CURLE_UNSUPPORTED_PROTOCOL;
      break;

    default:
      errstr=gpg_strerror (rc);
      err=CURLE_COULDNT_CONNECT;
      break;
    }
      
  return handle_error(curl,err,errstr);
}