mirror of
git://git.gnupg.org/gnupg.git
synced 2025-04-17 15:44:34 +02: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 "host2net.h"
|
||||||
#include "dns-stuff.h"
|
#include "dns-stuff.h"
|
||||||
|
|
||||||
|
/* We allow the use of 0 instead of AF_UNSPEC - check this assumption. */
|
||||||
#if AF_UNSPEC != 0
|
#if AF_UNSPEC != 0
|
||||||
# error AF_UNSPEC does not have the value 0
|
# error AF_UNSPEC does not have the value 0
|
||||||
#endif
|
#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
|
#ifndef AI_ADDRCONFIG
|
||||||
# define AI_ADDRCONFIG 0
|
# define AI_ADDRCONFIG 0
|
||||||
#endif
|
#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. */
|
/* Resolve a name using the standard system function. */
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
resolve_name_standard (const char *name, unsigned short port,
|
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;
|
*r_dai = daihead;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
#endif /*!USE_ADNS*/
|
||||||
|
|
||||||
|
|
||||||
/* Resolve an address using the standard system function. */
|
/* 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,
|
int want_family, int want_socktype,
|
||||||
dns_addrinfo_t *r_ai, char **r_canonname)
|
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,
|
return resolve_name_adns (name, port, want_family, want_socktype,
|
||||||
r_ai, r_canonname);
|
r_ai, r_canonname);
|
||||||
#else
|
#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
|
/* 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
|
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
|
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))),
|
: (want_certtype - DNS_CERTTYPE_RRBASE))),
|
||||||
adns_qf_quoteok_query, &answer))
|
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)); */
|
/* log_error ("DNS query failed: %s\n", strerror (errno)); */
|
||||||
adns_finish (state);
|
adns_finish (state);
|
||||||
return err;
|
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", */
|
/* log_error ("DNS query returned an error: %s (%s)\n", */
|
||||||
/* adns_strerror (answer->status), */
|
/* adns_strerror (answer->status), */
|
||||||
/* adns_errabbrev (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;
|
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++)
|
for (count = 0; count < answer->nrrs; count++)
|
||||||
{
|
{
|
||||||
int datalen = answer->rrs.byteblock[count].len;
|
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. */
|
/* Found the requested record - return it. */
|
||||||
*r_key = xtrymalloc (datalen);
|
*r_key = xtrymalloc (datalen);
|
||||||
if (!*r_key)
|
if (!*r_key)
|
||||||
err = gpg_err_make (default_errsource,
|
err = gpg_error_from_syserror ();
|
||||||
gpg_err_code_from_syserror ());
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy (*r_key, data, datalen);
|
memcpy (*r_key, data, datalen);
|
||||||
@ -538,8 +638,7 @@ get_dns_cert (const char *name, int want_certtype,
|
|||||||
thus we do the same. */
|
thus we do the same. */
|
||||||
*r_key = xtrymalloc (datalen);
|
*r_key = xtrymalloc (datalen);
|
||||||
if (!*r_key)
|
if (!*r_key)
|
||||||
err = gpg_err_make (default_errsource,
|
err = gpg_error_from_syserror ();
|
||||||
gpg_err_code_from_syserror ());
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy (*r_key, data, datalen);
|
memcpy (*r_key, data, datalen);
|
||||||
@ -560,8 +659,7 @@ get_dns_cert (const char *name, int want_certtype,
|
|||||||
*r_fpr = xtrymalloc (*r_fprlen);
|
*r_fpr = xtrymalloc (*r_fprlen);
|
||||||
if (!*r_fpr)
|
if (!*r_fpr)
|
||||||
{
|
{
|
||||||
err = gpg_err_make (default_errsource,
|
err = gpg_error_from_syserror ();
|
||||||
gpg_err_code_from_syserror ());
|
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
memcpy (*r_fpr, data + 1, *r_fprlen);
|
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);
|
*r_url = xtrymalloc (datalen - (*r_fprlen + 1) + 1);
|
||||||
if (!*r_url)
|
if (!*r_url)
|
||||||
{
|
{
|
||||||
err = gpg_err_make (default_errsource,
|
err = gpg_error_from_syserror ();
|
||||||
gpg_err_code_from_syserror ());
|
|
||||||
xfree (*r_fpr);
|
xfree (*r_fpr);
|
||||||
*r_fpr = NULL;
|
*r_fpr = NULL;
|
||||||
goto leave;
|
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. */
|
/* Allocate a 64k buffer which is the limit for an DNS response. */
|
||||||
answer = xtrymalloc (65536);
|
answer = xtrymalloc (65536);
|
||||||
if (!answer)
|
if (!answer)
|
||||||
return gpg_err_make (default_errsource, gpg_err_code_from_syserror ());
|
return gpg_error_from_syserror ();
|
||||||
|
|
||||||
err = gpg_err_make (default_errsource, GPG_ERR_NOT_FOUND);
|
|
||||||
|
|
||||||
|
err = gpg_error (GPG_ERR_NOT_FOUND);
|
||||||
r = res_query (name, C_IN,
|
r = res_query (name, C_IN,
|
||||||
(want_certtype < DNS_CERTTYPE_RRBASE
|
(want_certtype < DNS_CERTTYPE_RRBASE
|
||||||
? T_CERT
|
? T_CERT
|
||||||
@ -641,7 +737,7 @@ get_dns_cert (const char *name, int want_certtype,
|
|||||||
rc = dn_skipname (pt, emsg);
|
rc = dn_skipname (pt, emsg);
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
{
|
{
|
||||||
err = gpg_err_make (default_errsource, GPG_ERR_INV_OBJ);
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
pt += rc + QFIXEDSZ;
|
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 */
|
rc = dn_skipname (pt, emsg); /* the name we just queried for */
|
||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
{
|
{
|
||||||
err = gpg_err_make (default_errsource, GPG_ERR_INV_OBJ);
|
err = gpg_error (GPG_ERR_INV_OBJ);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -693,8 +789,7 @@ get_dns_cert (const char *name, int want_certtype,
|
|||||||
{
|
{
|
||||||
*r_key = xtrymalloc (dlen);
|
*r_key = xtrymalloc (dlen);
|
||||||
if (!*r_key)
|
if (!*r_key)
|
||||||
err = gpg_err_make (default_errsource,
|
err = gpg_error_from_syserror ();
|
||||||
gpg_err_code_from_syserror ());
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy (*r_key, pt, dlen);
|
memcpy (*r_key, pt, dlen);
|
||||||
@ -727,8 +822,7 @@ get_dns_cert (const char *name, int want_certtype,
|
|||||||
/* PGP type */
|
/* PGP type */
|
||||||
*r_key = xtrymalloc (dlen);
|
*r_key = xtrymalloc (dlen);
|
||||||
if (!*r_key)
|
if (!*r_key)
|
||||||
err = gpg_err_make (default_errsource,
|
err = gpg_error_from_syserror ();
|
||||||
gpg_err_code_from_syserror ());
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
memcpy (*r_key, pt, dlen);
|
memcpy (*r_key, pt, dlen);
|
||||||
@ -747,8 +841,7 @@ get_dns_cert (const char *name, int want_certtype,
|
|||||||
*r_fpr = xtrymalloc (*r_fprlen);
|
*r_fpr = xtrymalloc (*r_fprlen);
|
||||||
if (!*r_fpr)
|
if (!*r_fpr)
|
||||||
{
|
{
|
||||||
err = gpg_err_make (default_errsource,
|
err = gpg_error_from_syserror ();
|
||||||
gpg_err_code_from_syserror ());
|
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
memcpy (*r_fpr, &pt[1], *r_fprlen);
|
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);
|
*r_url = xtrymalloc (dlen - (*r_fprlen + 1) + 1);
|
||||||
if (!*r_fpr)
|
if (!*r_fpr)
|
||||||
{
|
{
|
||||||
err = gpg_err_make (default_errsource,
|
err = gpg_error_from_syserror ();
|
||||||
gpg_err_code_from_syserror ());
|
|
||||||
xfree (*r_fpr);
|
xfree (*r_fpr);
|
||||||
*r_fpr = NULL;
|
*r_fpr = NULL;
|
||||||
goto leave;
|
goto leave;
|
||||||
@ -804,7 +896,7 @@ get_dns_cert (const char *name, int want_certtype,
|
|||||||
*r_fprlen = 0;
|
*r_fprlen = 0;
|
||||||
*r_url = NULL;
|
*r_url = NULL;
|
||||||
|
|
||||||
return gpg_err_make (default_errsource, GPG_ERR_NOT_SUPPORTED);
|
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user