mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-05 12:31:50 +01:00
dirmngr: Fix bugs in the standard resolver code.
* dirmngr/dns-stuff.c: Include dirmngr-err.h to set the correct error source. (get_h_errno_as_gpg_error): New. (get_dns_cert_libdns): Fix error code. (getsrv_libdns): Add arg R_COUNT and return an error code. (getsrv_standard): Ditto. Fix handling of res_query errors and provide the correct size for the return buffer. (getsrv): Adjust for changed worker functions. (get_dns_cname_standard): Fix handling of res_query errors and provide the correct size for the return buffer. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
392966aed9
commit
4a030f682e
@ -56,6 +56,7 @@
|
|||||||
# include <npth.h>
|
# include <npth.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "./dirmngr-err.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "host2net.h"
|
#include "host2net.h"
|
||||||
#include "dns-stuff.h"
|
#include "dns-stuff.h"
|
||||||
@ -168,6 +169,23 @@ free_dns_addrinfo (dns_addrinfo_t ai)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return H_ERRNO mapped to a gpg-error code. Will never return 0. */
|
||||||
|
static gpg_error_t
|
||||||
|
get_h_errno_as_gpg_error (void)
|
||||||
|
{
|
||||||
|
gpg_err_code_t ec;
|
||||||
|
|
||||||
|
switch (h_errno)
|
||||||
|
{
|
||||||
|
case HOST_NOT_FOUND: ec = GPG_ERR_UNKNOWN_HOST; break;
|
||||||
|
case TRY_AGAIN: ec = GPG_ERR_TRY_LATER; break;
|
||||||
|
case NO_RECOVERY: ec = GPG_ERR_SERVER_FAILED; break;
|
||||||
|
case NO_DATA: ec = GPG_ERR_NO_DATA; break;
|
||||||
|
default: ec = GPG_ERR_UNKNOWN_ERRNO; break;
|
||||||
|
}
|
||||||
|
return gpg_error (ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static gpg_error_t
|
static gpg_error_t
|
||||||
map_eai_to_gpg_error (int ec)
|
map_eai_to_gpg_error (int ec)
|
||||||
@ -670,7 +688,7 @@ get_dns_cert_libdns (const char *name, int want_certtype,
|
|||||||
void **r_key, size_t *r_keylen,
|
void **r_key, size_t *r_keylen,
|
||||||
unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
|
unsigned char **r_fpr, size_t *r_fprlen, char **r_url)
|
||||||
{
|
{
|
||||||
return gpg_error (ENOTSUP);
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -922,17 +940,21 @@ priosort(const void *a,const void *b)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Standard resolver based helper for getsrv. */
|
/* Libdns based helper for getsrv. Note that it is expected that NULL
|
||||||
static int
|
* is stored at the address of LIST and 0 is stored at the address of
|
||||||
getsrv_standard (const char *name, struct srventry **list)
|
* R_COUNT. */
|
||||||
|
static gpg_error_t
|
||||||
|
getsrv_libdns (const char *name, struct srventry **list, int *r_count)
|
||||||
{
|
{
|
||||||
return gpg_error (ENOTSUP);
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* libdns based helper for getsrv. */
|
/* Standard resolver based helper for getsrv. Note that it is
|
||||||
|
* expected that NULL is stored at the address of LIST and 0 is stored
|
||||||
|
* at the address of R_COUNT. */
|
||||||
static int
|
static int
|
||||||
getsrv_libdns (const char *name, struct srventry **list)
|
getsrv_standard (const char *name, struct srventry **list, int *r_count)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_SYSTEM_RESOLVER
|
#ifdef HAVE_SYSTEM_RESOLVER
|
||||||
union {
|
union {
|
||||||
@ -949,14 +971,19 @@ getsrv_libdns (const char *name, struct srventry **list)
|
|||||||
|
|
||||||
/* Do not allow a query using the standard resolver in Tor mode. */
|
/* Do not allow a query using the standard resolver in Tor mode. */
|
||||||
if (tor_mode)
|
if (tor_mode)
|
||||||
return -1;
|
return gpg_error (GPG_ERR_NOT_ENABLED);
|
||||||
|
|
||||||
my_unprotect ();
|
my_unprotect ();
|
||||||
r = res_query (name, C_IN, T_SRV, answer, sizeof answer);
|
r = res_query (name, C_IN, T_SRV, answer, sizeof res.ans);
|
||||||
my_protect ();
|
my_protect ();
|
||||||
if (r < sizeof (HEADER) || r > sizeof answer
|
if (r < 0)
|
||||||
|| header->rcode != NOERROR || !(count=ntohs (header->ancount)))
|
return get_h_errno_as_gpg_error ();
|
||||||
return 0; /* Error or no record found. */
|
if (r < sizeof (HEADER))
|
||||||
|
return gpg_error (GPG_ERR_SERVER_FAILED);
|
||||||
|
if (r > sizeof res.ans)
|
||||||
|
return gpg_error (GPG_ERR_SYSTEM_BUG);
|
||||||
|
if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
|
||||||
|
return gpg_error (GPG_ERR_NO_NAME); /* Error or no record found. */
|
||||||
|
|
||||||
emsg = &answer[r];
|
emsg = &answer[r];
|
||||||
pt = &answer[sizeof(HEADER)];
|
pt = &answer[sizeof(HEADER)];
|
||||||
@ -970,7 +997,7 @@ getsrv_libdns (const char *name, struct srventry **list)
|
|||||||
|
|
||||||
while (count-- > 0 && pt < emsg)
|
while (count-- > 0 && pt < emsg)
|
||||||
{
|
{
|
||||||
struct srventry *srv = NULL;
|
struct srventry *srv;
|
||||||
u16 type, class;
|
u16 type, class;
|
||||||
struct srventry *newlist;
|
struct srventry *newlist;
|
||||||
|
|
||||||
@ -1031,18 +1058,20 @@ getsrv_libdns (const char *name, struct srventry **list)
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
return srvcount;
|
*r_count = srvcount;
|
||||||
|
return 0;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
xfree (*list);
|
xfree (*list);
|
||||||
*list = NULL;
|
*list = NULL;
|
||||||
return -1;
|
return gpg_error (GPG_ERR_GENERAL);
|
||||||
|
|
||||||
#else /*!HAVE_SYSTEM_RESOLVER*/
|
#else /*!HAVE_SYSTEM_RESOLVER*/
|
||||||
|
|
||||||
(void)name;
|
(void)name;
|
||||||
(void)list;
|
(void)list;
|
||||||
return -1;
|
(void)r_count;
|
||||||
|
return gpg_error (GPG_ERR_NOT_SUPPORTED);
|
||||||
|
|
||||||
#endif /*!HAVE_SYSTEM_RESOLVER*/
|
#endif /*!HAVE_SYSTEM_RESOLVER*/
|
||||||
}
|
}
|
||||||
@ -1051,18 +1080,19 @@ getsrv_libdns (const char *name, struct srventry **list)
|
|||||||
int
|
int
|
||||||
getsrv (const char *name, struct srventry **list)
|
getsrv (const char *name, struct srventry **list)
|
||||||
{
|
{
|
||||||
|
gpg_error_t err;
|
||||||
int srvcount;
|
int srvcount;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
*list = NULL;
|
*list = NULL;
|
||||||
|
srvcount = 0;
|
||||||
if (!standard_resolver)
|
if (!standard_resolver)
|
||||||
srvcount = getsrv_libdns (name, list);
|
err = getsrv_libdns (name, list, &srvcount);
|
||||||
else
|
else
|
||||||
srvcount = getsrv_standard (name, list);
|
err = getsrv_standard (name, list, &srvcount);
|
||||||
|
|
||||||
if (srvcount <= 0)
|
if (err)
|
||||||
return srvcount;
|
return -1; /* Ugly. FIXME: Return an error code. */
|
||||||
|
|
||||||
/* Now we have an array of all the srv records. */
|
/* Now we have an array of all the srv records. */
|
||||||
|
|
||||||
@ -1172,9 +1202,15 @@ get_dns_cname_standard (const char *name, char **r_cname)
|
|||||||
if (tor_mode)
|
if (tor_mode)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
r = res_query (name, C_IN, T_CERT, answer, sizeof answer);
|
my_unprotect ();
|
||||||
if (r < sizeof (HEADER) || r > sizeof answer)
|
r = res_query (name, C_IN, T_CERT, answer, sizeof res.ans);
|
||||||
|
my_protect ();
|
||||||
|
if (r < 0)
|
||||||
|
return get_h_errno_as_gpg_error ();
|
||||||
|
if (r < sizeof (HEADER))
|
||||||
return gpg_error (GPG_ERR_SERVER_FAILED);
|
return gpg_error (GPG_ERR_SERVER_FAILED);
|
||||||
|
if (r > sizeof res.ans)
|
||||||
|
return gpg_error (GPG_ERR_SYSTEM_BUG);
|
||||||
if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
|
if (header->rcode != NOERROR || !(count=ntohs (header->ancount)))
|
||||||
return gpg_error (GPG_ERR_NO_NAME); /* Error or no record found. */
|
return gpg_error (GPG_ERR_NO_NAME); /* Error or no record found. */
|
||||||
if (count != 1)
|
if (count != 1)
|
||||||
@ -1221,7 +1257,7 @@ get_dns_cname_standard (const char *name, char **r_cname)
|
|||||||
|
|
||||||
(void)name;
|
(void)name;
|
||||||
(void)r_cname;
|
(void)r_cname;
|
||||||
return -1;
|
return gpg_error (GPG_ERR_NOT_IMPLEMENTED);
|
||||||
|
|
||||||
#endif /*!HAVE_SYSTEM_RESOLVER*/
|
#endif /*!HAVE_SYSTEM_RESOLVER*/
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user