mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
dirmngr: Add a getaddrinfo wrapper backend using ADNS.
* dirmngr/dns-stuff.c: Replace all use of default_errsource. (my_adns_init): Move to top. (resolve_name_adns): New. (resolve_dns_name) [USE_ADNS]: Divert to new func. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
a6c2c09843
commit
e026efb436
@ -54,12 +54,12 @@
|
||||
#include "host2net.h"
|
||||
#include "dns-stuff.h"
|
||||
|
||||
|
||||
/* We allow the use of 0 instead of AF_UNSPEC - check this assumption. */
|
||||
#if AF_UNSPEC != 0
|
||||
# error AF_UNSPEC does not have the value 0
|
||||
#endif
|
||||
|
||||
/* Windows does not support tge AI_ADDRCONFIG flag - use zero instead. */
|
||||
/* Windows does not support the AI_ADDRCONFIG flag - use zero instead. */
|
||||
#ifndef AI_ADDRCONFIG
|
||||
# define AI_ADDRCONFIG 0
|
||||
#endif
|
||||
@ -132,6 +132,129 @@ map_eai_to_gpg_error (int ec)
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_ADNS
|
||||
/* Init ADNS and store the new state at R_STATE. Returns 0 on
|
||||
success; prints an error message and returns an error code on
|
||||
failure. */
|
||||
static gpg_error_t
|
||||
my_adns_init (adns_state *r_state)
|
||||
{
|
||||
gpg_error_t err;
|
||||
|
||||
if (tor_mode? adns_init_strcfg (r_state,
|
||||
adns_if_noerrprint|adns_if_tormode,
|
||||
NULL, "nameserver 8.8.8.8")
|
||||
/* */: adns_init (r_state, adns_if_noerrprint, NULL))
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("error initializing adns: %s\n", gpg_strerror (err));
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /*USE_ADNS*/
|
||||
|
||||
|
||||
#ifdef USE_ADNS
|
||||
/* Resolve a name using the ADNS library. See resolve_dns_name for
|
||||
the description. */
|
||||
static gpg_error_t
|
||||
resolve_name_adns (const char *name, unsigned short port,
|
||||
int want_family, int want_socktype,
|
||||
dns_addrinfo_t *r_dai, char **r_canonname)
|
||||
{
|
||||
gpg_error_t err = 0;
|
||||
dns_addrinfo_t daihead = NULL;
|
||||
dns_addrinfo_t dai;
|
||||
adns_state state;
|
||||
adns_answer *answer = NULL;
|
||||
int count;
|
||||
|
||||
*r_dai = NULL;
|
||||
if (r_canonname)
|
||||
*r_canonname = NULL;
|
||||
|
||||
if (want_socktype != SOCK_STREAM && want_socktype != SOCK_DGRAM)
|
||||
return gpg_error (GPG_ERR_ESOCKTNOSUPPORT);
|
||||
|
||||
err = my_adns_init (&state);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (adns_synchronous (state, name, adns_r_addr,
|
||||
adns_qf_quoteok_query, &answer))
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
log_error ("DNS query failed: %s\n", gpg_strerror (err));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
err = gpg_error (GPG_ERR_NOT_FOUND);
|
||||
if (answer->status != adns_s_ok || answer->type != adns_r_addr)
|
||||
{
|
||||
log_error ("DNS query returned an error: %s (%s)\n",
|
||||
adns_strerror (answer->status),
|
||||
adns_errabbrev (answer->status));
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (r_canonname && answer->cname)
|
||||
{
|
||||
*r_canonname = xtrystrdup (answer->cname);
|
||||
if (!*r_canonname)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
for (count = 0; count < answer->nrrs; count++)
|
||||
{
|
||||
int len;
|
||||
adns_rr_addr *addr;
|
||||
|
||||
len = answer->rrs.addr[count].len;
|
||||
addr = &answer->rrs.addr[count];
|
||||
if (addr->addr.sa.sa_family != AF_INET6
|
||||
&& addr->addr.sa.sa_family != AF_INET)
|
||||
continue;
|
||||
|
||||
dai = xtrymalloc (sizeof *dai + len - 1);
|
||||
if (!dai)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
dai->family = addr->addr.sa.sa_family;
|
||||
dai->socktype = want_socktype == SOCK_STREAM? SOCK_STREAM : SOCK_DGRAM;
|
||||
dai->protocol = want_socktype == SOCK_STREAM? IPPROTO_TCP : IPPROTO_UDP;
|
||||
dai->addrlen = len;
|
||||
memcpy (dai->addr, &addr->addr.sa, len);
|
||||
dai->next = daihead;
|
||||
daihead = dai;
|
||||
err = 0;
|
||||
}
|
||||
|
||||
leave:
|
||||
adns_free (answer);
|
||||
adns_finish (state);
|
||||
if (err)
|
||||
{
|
||||
if (r_canonname)
|
||||
{
|
||||
xfree (*r_canonname);
|
||||
*r_canonname = NULL;
|
||||
}
|
||||
free_dns_addrinfo (daihead);
|
||||
}
|
||||
else
|
||||
*r_dai = daihead;
|
||||
return err;
|
||||
}
|
||||
#endif /*USE_ADNS*/
|
||||
|
||||
|
||||
#ifndef USE_ADNS
|
||||
/* Resolve a name using the standard system function. */
|
||||
static gpg_error_t
|
||||
resolve_name_standard (const char *name, unsigned short port,
|
||||
@ -236,6 +359,7 @@ resolve_name_standard (const char *name, unsigned short port,
|
||||
*r_dai = daihead;
|
||||
return err;
|
||||
}
|
||||
#endif /*!USE_ADNS*/
|
||||
|
||||
|
||||
/* Resolve an address using the standard system function. */
|
||||
@ -314,7 +438,7 @@ resolve_dns_name (const char *name, unsigned short port,
|
||||
int want_family, int want_socktype,
|
||||
dns_addrinfo_t *r_ai, char **r_canonname)
|
||||
{
|
||||
#ifdef USE_ADNS_disabled_for_now
|
||||
#ifdef USE_ADNS
|
||||
return resolve_name_adns (name, port, want_family, want_socktype,
|
||||
r_ai, r_canonname);
|
||||
#else
|
||||
@ -417,29 +541,6 @@ is_onion_address (const char *name)
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_ADNS
|
||||
/* Init ADNS and store the new state at R_STATE. Returns 0 on
|
||||
success; prints an error message and returns an error code on
|
||||
failure. */
|
||||
static gpg_error_t
|
||||
my_adns_init (adns_state *r_state)
|
||||
{
|
||||
gpg_error_t err;
|
||||
|
||||
if (tor_mode? adns_init_strcfg (r_state,
|
||||
adns_if_noerrprint|adns_if_tormode,
|
||||
NULL, "nameserver 8.8.8.8")
|
||||
/* */: adns_init (r_state, adns_if_noerrprint, NULL))
|
||||
{
|
||||
err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
|
||||
log_error ("error initializing adns: %s\n", gpg_strerror (err));
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /*USE_ADNS*/
|
||||
|
||||
|
||||
/* Returns 0 on success or an error code. If a PGP CERT record was
|
||||
found, the malloced data is returned at (R_KEY, R_KEYLEN) and
|
||||
the other return parameters are set to NULL/0. If an IPGP CERT
|
||||
@ -482,7 +583,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
: (want_certtype - DNS_CERTTYPE_RRBASE))),
|
||||
adns_qf_quoteok_query, &answer))
|
||||
{
|
||||
err = gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
|
||||
err = gpg_error_from_syserror ();
|
||||
/* log_error ("DNS query failed: %s\n", strerror (errno)); */
|
||||
adns_finish (state);
|
||||
return err;
|
||||
@ -492,11 +593,11 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
/* log_error ("DNS query returned an error: %s (%s)\n", */
|
||||
/* adns_strerror (answer->status), */
|
||||
/* adns_errabbrev (answer->status)); */
|
||||
err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
|
||||
err = gpg_error (GPG_ERR_NOT_FOUND);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
|
||||
err = gpg_error (GPG_ERR_NOT_FOUND);
|
||||
for (count = 0; count < answer->nrrs; count++)
|
||||
{
|
||||
int datalen = answer->rrs.byteblock[count].len;
|
||||
@ -511,8 +612,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
/* Found the requested record - return it. */
|
||||
*r_key = xtrymalloc (datalen);
|
||||
if (!*r_key)
|
||||
err = gpg_err_make (default_errsource,
|
||||
gpg_err_code_from_syserror ());
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
memcpy (*r_key, data, datalen);
|
||||
@ -538,8 +638,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
thus we do the same. */
|
||||
*r_key = xtrymalloc (datalen);
|
||||
if (!*r_key)
|
||||
err = gpg_err_make (default_errsource,
|
||||
gpg_err_code_from_syserror ());
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
memcpy (*r_key, data, datalen);
|
||||
@ -560,8 +659,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
*r_fpr = xtrymalloc (*r_fprlen);
|
||||
if (!*r_fpr)
|
||||
{
|
||||
err = gpg_err_make (default_errsource,
|
||||
gpg_err_code_from_syserror ());
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
memcpy (*r_fpr, data + 1, *r_fprlen);
|
||||
@ -574,8 +672,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
*r_url = xtrymalloc (datalen - (*r_fprlen + 1) + 1);
|
||||
if (!*r_url)
|
||||
{
|
||||
err = gpg_err_make (default_errsource,
|
||||
gpg_err_code_from_syserror ());
|
||||
err = gpg_error_from_syserror ();
|
||||
xfree (*r_fpr);
|
||||
*r_fpr = NULL;
|
||||
goto leave;
|
||||
@ -615,10 +712,9 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
/* Allocate a 64k buffer which is the limit for an DNS response. */
|
||||
answer = xtrymalloc (65536);
|
||||
if (!answer)
|
||||
return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
|
||||
|
||||
err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
|
||||
return gpg_error_from_syserror ();
|
||||
|
||||
err = gpg_error (GPG_ERR_NOT_FOUND);
|
||||
r = res_query (name, C_IN,
|
||||
(want_certtype < DNS_CERTTYPE_RRBASE
|
||||
? T_CERT
|
||||
@ -641,7 +737,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
rc = dn_skipname (pt, emsg);
|
||||
if (rc == -1)
|
||||
{
|
||||
err = gpg_err_make (default_errsource, GPG_ERR_INV_OBJ);
|
||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||
goto leave;
|
||||
}
|
||||
pt += rc + QFIXEDSZ;
|
||||
@ -659,7 +755,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
rc = dn_skipname (pt, emsg); /* the name we just queried for */
|
||||
if (rc == -1)
|
||||
{
|
||||
err = gpg_err_make (default_errsource, GPG_ERR_INV_OBJ);
|
||||
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||
goto leave;
|
||||
}
|
||||
|
||||
@ -693,8 +789,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
{
|
||||
*r_key = xtrymalloc (dlen);
|
||||
if (!*r_key)
|
||||
err = gpg_err_make (default_errsource,
|
||||
gpg_err_code_from_syserror ());
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
memcpy (*r_key, pt, dlen);
|
||||
@ -727,8 +822,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
/* PGP type */
|
||||
*r_key = xtrymalloc (dlen);
|
||||
if (!*r_key)
|
||||
err = gpg_err_make (default_errsource,
|
||||
gpg_err_code_from_syserror ());
|
||||
err = gpg_error_from_syserror ();
|
||||
else
|
||||
{
|
||||
memcpy (*r_key, pt, dlen);
|
||||
@ -747,8 +841,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
*r_fpr = xtrymalloc (*r_fprlen);
|
||||
if (!*r_fpr)
|
||||
{
|
||||
err = gpg_err_make (default_errsource,
|
||||
gpg_err_code_from_syserror ());
|
||||
err = gpg_error_from_syserror ();
|
||||
goto leave;
|
||||
}
|
||||
memcpy (*r_fpr, &pt[1], *r_fprlen);
|
||||
@ -761,8 +854,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
*r_url = xtrymalloc (dlen - (*r_fprlen + 1) + 1);
|
||||
if (!*r_fpr)
|
||||
{
|
||||
err = gpg_err_make (default_errsource,
|
||||
gpg_err_code_from_syserror ());
|
||||
err = gpg_error_from_syserror ();
|
||||
xfree (*r_fpr);
|
||||
*r_fpr = NULL;
|
||||
goto leave;
|
||||
@ -804,7 +896,7 @@ get_dns_cert (const char *name, int want_certtype,
|
||||
*r_fprlen = 0;
|
||||
*r_url = NULL;
|
||||
|
||||
return gpg_err_make (default_errsource, GPG_ERR_NOT_SUPPORTED);
|
||||
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user