Beispiel #1
0
static GtkWidget *
check_default_keyserver (SettingsDlg *dialog)
{
  keyserver_spec_t kspec;

  if (dialog->gnupg21)
    return NULL; /* GnuPG manages the keyservers.  */

  keyserver_selected_from_list_cb (dialog);

  if (!dialog->keyserver.url)
    return NULL; /* No keyserver is just fine.  */

  kspec = parse_keyserver_uri (dialog->keyserver.url, 0, NULL, 0);
  if (!kspec)
    return GTK_WIDGET (dialog->keyserver.combo);
  if (!kspec->host
      || (kspec->scheme && !(!strcmp (kspec->scheme, "hkp")
                             || !strcmp (kspec->scheme, "http")
                             || !strcmp (kspec->scheme, "ldap")
                             || !strcmp (kspec->scheme, "finger")
                             || !strcmp (kspec->scheme, "mailto"))))
    {
      free_keyserver_spec (kspec);
      return GTK_WIDGET (dialog->keyserver.combo);
    }

  free_keyserver_spec (kspec);
  return NULL;
}
Beispiel #2
0
/* Import key pointed to by a PKA record. Return the requested
   fingerprint in fpr. */
int
keyserver_import_pka (ctrl_t ctrl,
                      const char *name,unsigned char **fpr,size_t *fpr_len)
{
  char *uri;
  int rc = G10ERR_NO_PUBKEY;

  *fpr = xmalloc (20);
  *fpr_len = 20;

  uri = get_pka_info (name, *fpr);
  if (uri && *uri)
    {
      /* An URI is available.  Lookup the key. */
      struct keyserver_spec *spec;
      spec = parse_keyserver_uri (uri, 1, NULL, 0);
      if (spec)
	{
	  rc = keyserver_import_fprint (ctrl, *fpr, 20, spec);
	  free_keyserver_spec (spec);
	}
      xfree (uri);
    }

  if (rc)
    {
      xfree(*fpr);
      *fpr = NULL;
    }

  return rc;
}
Beispiel #3
0
static void
gpg_free_akl (akl_t akl)
{
  if (akl->spec)
    free_keyserver_spec (akl->spec);

  xfree (akl);
}
Beispiel #4
0
keyserver_spec_t
parse_keyserver_uri (const char *string,int require_scheme,
		     const char *configname,unsigned int configlineno)
{
  int assume_hkp=0;
  struct keyserver_spec *keyserver;
  const char *idx;
  int count;
  char *uri,*options;

  assert(string!=NULL);

  keyserver=xmalloc_clear(sizeof(struct keyserver_spec));

  uri=xstrdup(string);

  options=strchr(uri,' ');
  if(options)
    {
      char *tok;

      *options='\0';
      options++;

      while((tok=optsep(&options)))
	add_canonical_option(tok,&keyserver->options);
    }

  /* Get the scheme */

  for(idx=uri,count=0;*idx && *idx!=':';idx++)
    {
      count++;

      /* Do we see the start of an RFC-2732 ipv6 address here?  If so,
	 there clearly isn't a scheme so get out early. */
      if(*idx=='[')
	{
	  /* Was the '[' the first thing in the string?  If not, we
	     have a mangled scheme with a [ in it so fail. */
	  if(count==1)
	    break;
	  else
	    goto fail;
	}
    }

  if(count==0)
    goto fail;

  if(*idx=='\0' || *idx=='[')
    {
      if(require_scheme)
	return NULL;

      /* Assume HKP if there is no scheme */
      assume_hkp=1;
      keyserver->scheme=xstrdup("hkp");

      keyserver->uri=xmalloc(strlen(keyserver->scheme)+3+strlen(uri)+1);
      strcpy(keyserver->uri,keyserver->scheme);
      strcat(keyserver->uri,"://");
      strcat(keyserver->uri,uri);
    }
  else
    {
      int i;

      keyserver->uri=xstrdup(uri);

      keyserver->scheme=xmalloc(count+1);

      /* Force to lowercase */
      for(i=0;i<count;i++)
	keyserver->scheme[i]=ascii_tolower(uri[i]);

      keyserver->scheme[i]='\0';

      /* Skip past the scheme and colon */
      uri+=count+1;
    }

  if(ascii_strcasecmp(keyserver->scheme,"x-broken-hkp")==0)
    {
      deprecated_warning(configname,configlineno,"x-broken-hkp",
			 "--keyserver-options ","broken-http-proxy");
      xfree(keyserver->scheme);
      keyserver->scheme=xstrdup("hkp");
      append_to_strlist(&opt.keyserver_options.other,"broken-http-proxy");
    }
  else if(ascii_strcasecmp(keyserver->scheme,"x-hkp")==0)
    {
      /* Canonicalize this to "hkp" so it works with both the internal
	 and external keyserver interface. */
      xfree(keyserver->scheme);
      keyserver->scheme=xstrdup("hkp");
    }

  if (uri[0]=='/' && uri[1]=='/' && uri[2] == '/')
    {
      /* Three slashes means network path with a default host name.
         This is a hack because it does not crok all possible
         combiantions.  We should better repalce all code bythe parser
         from http.c.  */
      keyserver->path = xstrdup (uri+2);
    }
  else if(assume_hkp || (uri[0]=='/' && uri[1]=='/'))
    {
      /* Two slashes means network path. */

      /* Skip over the "//", if any */
      if(!assume_hkp)
	uri+=2;

      /* Do we have userinfo auth data present? */
      for(idx=uri,count=0;*idx && *idx!='@' && *idx!='/';idx++)
	count++;

      /* We found a @ before the slash, so that means everything
	 before the @ is auth data. */
      if(*idx=='@')
	{
	  if(count==0)
	    goto fail;

	  keyserver->auth=xmalloc(count+1);
	  strncpy(keyserver->auth,uri,count);
	  keyserver->auth[count]='\0';
	  uri+=count+1;
	}

      /* Is it an RFC-2732 ipv6 [literal address] ? */
      if(*uri=='[')
	{
	  for(idx=uri+1,count=1;*idx
		&& ((isascii (*idx) && isxdigit(*idx))
                    || *idx==':' || *idx=='.');idx++)
	    count++;

	  /* Is the ipv6 literal address terminated? */
	  if(*idx==']')
	    count++;
	  else
	    goto fail;
	}
      else
	for(idx=uri,count=0;*idx && *idx!=':' && *idx!='/';idx++)
	  count++;

      if(count==0)
	goto fail;

      keyserver->host=xmalloc(count+1);
      strncpy(keyserver->host,uri,count);
      keyserver->host[count]='\0';

      /* Skip past the host */
      uri+=count;

      if(*uri==':')
	{
	  /* It would seem to be reasonable to limit the range of the
	     ports to values between 1-65535, but RFC 1738 and 1808
	     imply there is no limit.  Of course, the real world has
	     limits. */

	  for(idx=uri+1,count=0;*idx && *idx!='/';idx++)
	    {
	      count++;

	      /* Ports are digits only */
	      if(!digitp(idx))
		goto fail;
	    }

	  keyserver->port=xmalloc(count+1);
	  strncpy(keyserver->port,uri+1,count);
	  keyserver->port[count]='\0';

	  /* Skip past the colon and port number */
	  uri+=1+count;
	}

      /* Everything else is the path */
      if(*uri)
	keyserver->path=xstrdup(uri);
      else
	keyserver->path=xstrdup("/");

      if(keyserver->path[1])
	keyserver->flags.direct_uri=1;
    }
  else if(uri[0]!='/')
    {
      /* No slash means opaque.  Just record the opaque blob and get
	 out. */
      keyserver->opaque=xstrdup(uri);
    }
  else
    {
      /* One slash means absolute path.  We don't need to support that
	 yet. */
      goto fail;
    }

  return keyserver;

 fail:
  free_keyserver_spec(keyserver);

  return NULL;
}
Beispiel #5
0
/* Import a key by name using LDAP */
int
keyserver_import_ldap (ctrl_t ctrl,
                       const char *name,unsigned char **fpr,size_t *fpr_len)
{
  char *domain;
  struct keyserver_spec *keyserver;
  strlist_t list=NULL;
  int rc,hostlen=1;
#ifdef USE_DNS_SRV
  struct srventry *srvlist=NULL;
  int srvcount,i;
  char srvname[MAXDNAME];
#endif

  /* Parse out the domain */
  domain=strrchr(name,'@');
  if(!domain)
    return G10ERR_GENERAL;

  domain++;

  keyserver=xmalloc_clear(sizeof(struct keyserver_spec));
  keyserver->scheme=xstrdup("ldap");
  keyserver->host=xmalloc(1);
  keyserver->host[0]='\0';

#ifdef USE_DNS_SRV
  snprintf(srvname,MAXDNAME,"_pgpkey-ldap._tcp.%s",domain);

  srvcount=getsrv(srvname,&srvlist);

  for(i=0;i<srvcount;i++)
    {
      hostlen+=strlen(srvlist[i].target)+1;
      keyserver->host=xrealloc(keyserver->host,hostlen);

      strcat(keyserver->host,srvlist[i].target);

      if(srvlist[i].port!=389)
	{
	  char port[7];

	  hostlen+=6; /* a colon, plus 5 digits (unsigned 16-bit value) */
	  keyserver->host=xrealloc(keyserver->host,hostlen);

	  snprintf(port,7,":%u",srvlist[i].port);
	  strcat(keyserver->host,port);
	}

      strcat(keyserver->host," ");
    }

  free(srvlist);
#endif

  /* If all else fails, do the PGP Universal trick of
     ldap://keys.(domain) */

  hostlen+=5+strlen(domain);
  keyserver->host=xrealloc(keyserver->host,hostlen);
  strcat(keyserver->host,"keys.");
  strcat(keyserver->host,domain);

  append_to_strlist(&list,name);

  rc = gpg_error (GPG_ERR_NOT_IMPLEMENTED); /*FIXME*/
       /* keyserver_work (ctrl, KS_GETNAME, list, NULL, */
       /*                 0, fpr, fpr_len, keyserver); */

  free_strlist(list);

  free_keyserver_spec(keyserver);

  return rc;
}
Beispiel #6
0
/* Import key in a CERT or pointed to by a CERT */
int
keyserver_import_cert (ctrl_t ctrl,
                       const char *name,unsigned char **fpr,size_t *fpr_len)
{
  gpg_error_t err;
  char *domain,*look,*url;
  estream_t key;


  look=xstrdup(name);

  domain=strrchr(look,'@');
  if(domain)
    *domain='.';

  err = get_dns_cert (look, &key, fpr, fpr_len, &url);
  if (err)
    ;
  else if (key)
    {
      int armor_status=opt.no_armor;

      /* CERTs are always in binary format */
      opt.no_armor=1;

      err = import_keys_es_stream (ctrl, key, NULL, fpr, fpr_len,
                                  opt.keyserver_options.import_options);

      opt.no_armor=armor_status;

      es_fclose (key);
      key = NULL;
    }
  else if (*fpr)
    {
      /* We only consider the IPGP type if a fingerprint was provided.
	 This lets us select the right key regardless of what a URL
	 points to, or get the key from a keyserver. */
      if(url)
	{
	  struct keyserver_spec *spec;

	  spec=parse_keyserver_uri(url,1,NULL,0);
	  if(spec)
	    {
	      err = keyserver_import_fprint (ctrl, *fpr,*fpr_len,spec);
	      free_keyserver_spec(spec);
	    }
	}
      else if(opt.keyserver)
	{
	  /* If only a fingerprint is provided, try and fetch it from
	     our --keyserver */

	  err = keyserver_import_fprint (ctrl, *fpr,*fpr_len,opt.keyserver);
	}
      else
	log_info(_("no keyserver known (use option --keyserver)\n"));

      /* Give a better string here? "CERT fingerprint for \"%s\"
	 found, but no keyserver" " known (use option
	 --keyserver)\n" ? */

    }

  xfree(url);
  xfree(look);

  return err;
}
Beispiel #7
0
int
keyserver_refresh (ctrl_t ctrl, strlist_t users)
{
  int rc,count,numdesc,fakev3=0;
  KEYDB_SEARCH_DESC *desc;
  unsigned int options=opt.keyserver_options.import_options;

  /* We switch merge-only on during a refresh, as 'refresh' should
     never import new keys, even if their keyids match. */
  opt.keyserver_options.import_options|=IMPORT_MERGE_ONLY;

  /* Similarly, we switch on fast-import, since refresh may make
     multiple import sets (due to preferred keyserver URLs).  We don't
     want each set to rebuild the trustdb.  Instead we do it once at
     the end here. */
  opt.keyserver_options.import_options|=IMPORT_FAST;

  /* If refresh_add_fake_v3_keyids is on and it's a HKP or MAILTO
     scheme, then enable fake v3 keyid generation. */
  if((opt.keyserver_options.options&KEYSERVER_ADD_FAKE_V3) && opt.keyserver
     && (ascii_strcasecmp(opt.keyserver->scheme,"hkp")==0 ||
	 ascii_strcasecmp(opt.keyserver->scheme,"mailto")==0))
    fakev3=1;

  rc=keyidlist(users,&desc,&numdesc,fakev3);
  if(rc)
    return rc;

  count=numdesc;
  if(count>0)
    {
      int i;

      /* Try to handle preferred keyserver keys first */
      for(i=0;i<numdesc;i++)
	{
	  if(desc[i].skipfncvalue)
	    {
	      struct keyserver_spec *keyserver=desc[i].skipfncvalue;

	      /* We use the keyserver structure we parsed out before.
		 Note that a preferred keyserver without a scheme://
		 will be interpreted as hkp:// */
	      rc = keyserver_get (ctrl, &desc[i], 1, keyserver);
	      if(rc)
		log_info(_("WARNING: unable to refresh key %s"
			   " via %s: %s\n"),keystr_from_desc(&desc[i]),
			 keyserver->uri,g10_errstr(rc));
	      else
		{
		  /* We got it, so mark it as NONE so we don't try and
		     get it again from the regular keyserver. */

		  desc[i].mode=KEYDB_SEARCH_MODE_NONE;
		  count--;
		}

	      free_keyserver_spec(keyserver);
	    }
	}
    }

  if(count>0)
    {
      if(opt.keyserver)
	{
	  if(count==1)
	    log_info(_("refreshing 1 key from %s\n"),opt.keyserver->uri);
	  else
	    log_info(_("refreshing %d keys from %s\n"),
		     count,opt.keyserver->uri);
	}

      rc=keyserver_get (ctrl, desc, numdesc, NULL);
    }

  xfree(desc);

  opt.keyserver_options.import_options=options;

  /* If the original options didn't have fast import, and the trustdb
     is dirty, rebuild. */
  if(!(opt.keyserver_options.import_options&IMPORT_FAST))
    trustdb_check_or_update();

  return rc;
}