Exemplo n.º 1
0
/* Retrieve keys from URL and write the result to the provided output
   stream OUTFP.  */
gpg_error_t
ks_action_fetch (ctrl_t ctrl, const char *url, estream_t outfp)
{
  gpg_error_t err = 0;
  estream_t infp;
  parsed_uri_t parsed_uri;  /* The broken down URI.  */

  if (!url)
    return gpg_error (GPG_ERR_INV_URI);

  err = http_parse_uri (&parsed_uri, url, 1);
  if (err)
    return err;

  if (parsed_uri->is_http)
    {
      err = ks_http_fetch (ctrl, url, &infp);
      if (!err)
        {
          err = copy_stream (infp, outfp);
          es_fclose (infp);
        }
    }
  else if (!parsed_uri->opaque)
    {
      err = gpg_error (GPG_ERR_INV_URI);
    }
  else if (!strcmp (parsed_uri->scheme, "finger"))
    {
      err = ks_finger_fetch (ctrl, parsed_uri, &infp);
      if (!err)
        {
          err = copy_stream (infp, outfp);
          es_fclose (infp);
        }
    }
  else if (!strcmp (parsed_uri->scheme, "kdns"))
    {
      err = ks_kdns_fetch (ctrl, parsed_uri, &infp);
      if (!err)
        {
          err = copy_stream (infp, outfp);
          es_fclose (infp);
        }
    }
  else
    err = gpg_error (GPG_ERR_INV_URI);

  http_release_parsed_uri (parsed_uri);
  return err;
}
Exemplo n.º 2
0
/* Get the requested keys (matching PATTERNS) using all configured
   keyservers and write the result to the provided output stream.  */
gpg_error_t
ks_action_get (ctrl_t ctrl, uri_item_t keyservers,
	       strlist_t patterns, estream_t outfp)
{
  gpg_error_t err = 0;
  gpg_error_t first_err = 0;
  int any_server = 0;
  int any_data = 0;
  strlist_t sl;
  uri_item_t uri;
  estream_t infp;

  if (!patterns)
    return gpg_error (GPG_ERR_NO_USER_ID);

  /* FIXME: We only take care of the first keyserver.  To fully
     support multiple keyservers we need to track the result for each
     pattern and use the next keyserver if one key was not found.  The
     keyservers might not all be fully synced thus it is not clear
     whether the first keyserver has the freshest copy of the key.
     Need to think about a better strategy.  */
  for (uri = keyservers; !err && uri; uri = uri->next)
    {
      int is_hkp_s = (strcmp (uri->parsed_uri->scheme, "hkp") == 0
                      || strcmp (uri->parsed_uri->scheme, "hkps") == 0);
      int is_http_s = (strcmp (uri->parsed_uri->scheme, "http") == 0
                       || strcmp (uri->parsed_uri->scheme, "https") == 0);
      int is_ldap = 0;

#if USE_LDAP
      is_ldap = (strcmp (uri->parsed_uri->scheme, "ldap") == 0
		 || strcmp (uri->parsed_uri->scheme, "ldaps") == 0
		 || strcmp (uri->parsed_uri->scheme, "ldapi") == 0);
#endif

      if (is_hkp_s || is_http_s || is_ldap)
        {
          any_server = 1;
          for (sl = patterns; !err && sl; sl = sl->next)
            {
#if USE_LDAP
	      if (is_ldap)
		err = ks_ldap_get (ctrl, uri->parsed_uri, sl->d, &infp);
	      else
#endif
              if (is_hkp_s)
                err = ks_hkp_get (ctrl, uri->parsed_uri, sl->d, &infp);
              else if (is_http_s)
                err = ks_http_fetch (ctrl, uri->parsed_uri->original, &infp);
              else
                BUG ();

              if (err)
                {
                  /* It is possible that a server does not carry a
                     key, thus we only save the error and continue
                     with the next pattern.  FIXME: It is an open
                     question how to return such an error condition to
                     the caller.  */
                  first_err = err;
                  err = 0;
                }
              else
                {
                  err = copy_stream (infp, outfp);
                  /* Reading from the keyserver should never fail, thus
                     return this error.  */
                  if (!err)
                    any_data = 1;
                  es_fclose (infp);
                  infp = NULL;
                }
            }
        }
      if (any_data)
        break; /* Stop loop after a keyserver returned something.  */
    }

  if (!any_server)
    err = gpg_error (GPG_ERR_NO_KEYSERVER);
  else if (!err && first_err && !any_data)
    err = first_err;
  return err;
}