mirror of
git://git.gnupg.org/gnupg.git
synced 2025-02-01 16:33:02 +01:00
5e7ac031f5
* dirmngr/dns-stuff.c (resolve_name_standard): On failure retry by first resolving the CNAME. (get_dns_cname): New. * dirmngr/t-dns-stuff.c (main): Add option --cname. -- At least the getaddrinfo implementation in glibc 2.19-13 from Debian returns EAI_NONAME if the CNAME points to a too long list of A/AAAA addresses. Looking at the wire the data is correctly returned from the server but getaddrinfo seems to get confused by truncation and retry. To fix this we resolve the CNAME again and call getaddrinfo again with the canonical name. Signed-off-by: Werner Koch <wk@gnupg.org>
278 lines
6.9 KiB
C
278 lines
6.9 KiB
C
/* t-dns-cert.c - Module test for dns-stuff.c
|
|
* Copyright (C) 2011 Free Software Foundation, Inc.
|
|
* Copyright (C) 2011, 2015 Werner Koch
|
|
*
|
|
* This file is part of GnuPG.
|
|
*
|
|
* GnuPG is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* GnuPG is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <config.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
|
|
|
|
#include "util.h"
|
|
#include "dns-stuff.h"
|
|
|
|
#define PGM "t-dns-stuff"
|
|
|
|
static int verbose;
|
|
static int debug;
|
|
|
|
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
int last_argc = -1;
|
|
gpg_error_t err;
|
|
int any_options = 0;
|
|
int opt_tor = 0;
|
|
int opt_cert = 0;
|
|
int opt_srv = 0;
|
|
int opt_bracket = 0;
|
|
int opt_cname = 0;
|
|
char const *name = NULL;
|
|
|
|
gpgrt_init ();
|
|
log_set_prefix (PGM, GPGRT_LOG_WITH_PREFIX);
|
|
if (argc)
|
|
{ argc--; argv++; }
|
|
while (argc && last_argc != argc )
|
|
{
|
|
last_argc = argc;
|
|
if (!strcmp (*argv, "--"))
|
|
{
|
|
argc--; argv++;
|
|
break;
|
|
}
|
|
else if (!strcmp (*argv, "--help"))
|
|
{
|
|
fputs ("usage: " PGM " [HOST]\n"
|
|
"Options:\n"
|
|
" --verbose print timings etc.\n"
|
|
" --debug flyswatter\n"
|
|
" --use-tor use Tor\n"
|
|
" --bracket enclose v6 addresses in brackets\n"
|
|
" --cert lookup a CERT RR\n"
|
|
" --srv lookup a SRV RR\n"
|
|
" --cname lookup a CNAME RR\n"
|
|
, stdout);
|
|
exit (0);
|
|
}
|
|
else if (!strcmp (*argv, "--verbose"))
|
|
{
|
|
verbose++;
|
|
argc--; argv++;
|
|
}
|
|
else if (!strcmp (*argv, "--debug"))
|
|
{
|
|
verbose += 2;
|
|
debug++;
|
|
argc--; argv++;
|
|
}
|
|
else if (!strcmp (*argv, "--use-tor"))
|
|
{
|
|
opt_tor = 1;
|
|
argc--; argv++;
|
|
}
|
|
else if (!strcmp (*argv, "--bracket"))
|
|
{
|
|
opt_bracket = 1;
|
|
argc--; argv++;
|
|
}
|
|
else if (!strcmp (*argv, "--cert"))
|
|
{
|
|
any_options = opt_cert = 1;
|
|
argc--; argv++;
|
|
}
|
|
else if (!strcmp (*argv, "--srv"))
|
|
{
|
|
any_options = opt_srv = 1;
|
|
argc--; argv++;
|
|
}
|
|
else if (!strcmp (*argv, "--cname"))
|
|
{
|
|
any_options = opt_cname = 1;
|
|
argc--; argv++;
|
|
}
|
|
else if (!strncmp (*argv, "--", 2))
|
|
{
|
|
fprintf (stderr, PGM ": unknown option '%s'\n", *argv);
|
|
exit (1);
|
|
}
|
|
}
|
|
|
|
if (!argc && !any_options)
|
|
{
|
|
opt_cert = 1;
|
|
name = "simon.josefsson.org";
|
|
}
|
|
else if (argc == 1)
|
|
name = *argv;
|
|
else
|
|
{
|
|
fprintf (stderr, PGM ": none or too many host names given\n");
|
|
exit (1);
|
|
}
|
|
|
|
if (opt_tor)
|
|
{
|
|
err = enable_dns_tormode ();
|
|
if (err)
|
|
{
|
|
fprintf (stderr, "error switching into Tor mode: %s\n",
|
|
gpg_strerror (err));
|
|
exit (1);
|
|
}
|
|
}
|
|
|
|
if (opt_cert)
|
|
{
|
|
unsigned char *fpr;
|
|
size_t fpr_len;
|
|
char *url;
|
|
void *key;
|
|
size_t keylen;
|
|
|
|
printf ("CERT lookup on '%s'\n", name);
|
|
|
|
err = get_dns_cert (name, DNS_CERTTYPE_ANY, &key, &keylen,
|
|
&fpr, &fpr_len, &url);
|
|
if (err)
|
|
printf ("get_dns_cert failed: %s <%s>\n",
|
|
gpg_strerror (err), gpg_strsource (err));
|
|
else if (key)
|
|
{
|
|
printf ("Key found (%u bytes)\n", (unsigned int)keylen);
|
|
}
|
|
else
|
|
{
|
|
if (fpr)
|
|
{
|
|
int i;
|
|
|
|
printf ("Fingerprint found (%d bytes): ", (int)fpr_len);
|
|
for (i = 0; i < fpr_len; i++)
|
|
printf ("%02X", fpr[i]);
|
|
putchar ('\n');
|
|
}
|
|
else
|
|
printf ("No fingerprint found\n");
|
|
|
|
if (url)
|
|
printf ("URL found: %s\n", url);
|
|
else
|
|
printf ("No URL found\n");
|
|
|
|
}
|
|
|
|
xfree (key);
|
|
xfree (fpr);
|
|
xfree (url);
|
|
}
|
|
else if (opt_cname)
|
|
{
|
|
char *cname;
|
|
|
|
printf ("CNAME lookup on '%s'\n", name);
|
|
err = get_dns_cname (name, &cname);
|
|
if (err)
|
|
printf ("get_dns_cname failed: %s <%s>\n",
|
|
gpg_strerror (err), gpg_strsource (err));
|
|
else
|
|
{
|
|
printf ("CNAME found: '%s'\n", cname);
|
|
}
|
|
|
|
xfree (cname);
|
|
}
|
|
else if (opt_srv)
|
|
{
|
|
struct srventry *srv;
|
|
int rc,i;
|
|
|
|
rc=getsrv("_hkp._tcp.wwwkeys.pgp.net",&srv);
|
|
printf("Count=%d\n\n",rc);
|
|
for(i=0;i<rc;i++)
|
|
{
|
|
printf("priority=%hu\n",srv[i].priority);
|
|
printf("weight=%hu\n",srv[i].weight);
|
|
printf("port=%hu\n",srv[i].port);
|
|
printf("target=%s\n",srv[i].target);
|
|
printf("\n");
|
|
}
|
|
|
|
xfree(srv);
|
|
}
|
|
else /* Standard lookup. */
|
|
{
|
|
char *cname;
|
|
dns_addrinfo_t aibuf, ai;
|
|
char *host;
|
|
|
|
printf ("Lookup on '%s'\n", name);
|
|
|
|
err = resolve_dns_name (name, 0, 0, SOCK_STREAM, &aibuf, &cname);
|
|
if (err)
|
|
{
|
|
fprintf (stderr, PGM": resolving '%s' failed: %s\n",
|
|
name, gpg_strerror (err));
|
|
exit (1);
|
|
}
|
|
|
|
if (cname)
|
|
printf ("cname: %s\n", cname);
|
|
for (ai = aibuf; ai; ai = ai->next)
|
|
{
|
|
printf ("%s %3d %3d ",
|
|
ai->family == AF_INET6? "inet6" :
|
|
ai->family == AF_INET? "inet4" : "? ",
|
|
ai->socktype, ai->protocol);
|
|
|
|
err = resolve_dns_addr (ai->addr, ai->addrlen,
|
|
(DNS_NUMERICHOST
|
|
| (opt_bracket? DNS_WITHBRACKET:0)),
|
|
&host);
|
|
if (err)
|
|
printf ("[resolve_dns_addr failed: %s]", gpg_strerror (err));
|
|
else
|
|
{
|
|
printf ("%s", host);
|
|
xfree (host);
|
|
}
|
|
|
|
err = resolve_dns_addr (ai->addr, ai->addrlen,
|
|
(opt_bracket? DNS_WITHBRACKET:0),
|
|
&host);
|
|
if (err)
|
|
printf ("[resolve_dns_addr failed (2): %s]", gpg_strerror (err));
|
|
else
|
|
{
|
|
if (!is_ip_address (host))
|
|
printf (" (%s)", host);
|
|
xfree (host);
|
|
}
|
|
putchar ('\n');
|
|
}
|
|
xfree (cname);
|
|
free_dns_addrinfo (aibuf);
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|