Commit 15733217 authored by Ondřej Surý's avatar Ondřej Surý Committed by Daniel Salzman

kdig: add TLS support

parent 48e27e21
This diff is collapsed.
......@@ -29,6 +29,7 @@
#include <netdb.h>
#include <stdint.h>
#include <sys/socket.h>
#include <gnutls/gnutls.h>
#include "utils/common/params.h"
......@@ -74,6 +75,13 @@ typedef struct {
* used.
*/
struct addrinfo *local_info;
/*! TLS Privacy Profile. */
tls_profile_t tls;
/*! TLS Privacy Profile Pin. */
char *tls_pin;
/*! GnuTLS session handle */
gnutls_session_t tls_session;
gnutls_certificate_credentials_t tls_creds;
} net_t;
/*!
......@@ -147,12 +155,14 @@ void get_addr_str(const struct sockaddr_storage *ss,
* \retval KNOT_EOK if success.
* \retval errcode if error.
*/
int net_init(const srv_info_t *local,
const srv_info_t *remote,
const int iptype,
const int socktype,
const int wait,
net_t *net);
int net_init(const srv_info_t *local,
const srv_info_t *remote,
const int iptype,
const int socktype,
const int wait,
const tls_profile_t tls,
const char *tls_pin,
net_t *net);
/*!
* \brief Creates socket and connects (if TCP) to remote address specified
......
......@@ -34,6 +34,7 @@
#define DEFAULT_IPV4_NAME "127.0.0.1"
#define DEFAULT_IPV6_NAME "::1"
#define DEFAULT_DNS_PORT "53"
#define DEFAULT_DNS_TLS_PORT "853"
#define DEFAULT_UDP_SIZE 512
#define DEFAULT_EDNS_SIZE 4096
#define MAX_PACKET_SIZE 65535
......@@ -66,6 +67,16 @@ typedef enum {
FORMAT_NSUPDATE
} format_t;
/*! \brief DNS over TLS Privacy Profiles. */
typedef enum {
/*!< No TLS */
TLS_PROFILE_NONE,
/*!< Opportunistic Privacy Profile. */
TLS_PROFILE_OPPORTUNISTIC,
/*!< Out-of-Band Key-Pinned Privacy Profile. */
TLS_PROFILE_OOB_PINNED,
} tls_profile_t;
/*! \brief Text output settings. */
typedef struct {
/*!< Output format. */
......
......@@ -705,7 +705,7 @@ static void process_query(const query_t *query)
for (size_t i = 0; i <= query->retries; i++) {
// Initialize network structure for current server.
ret = net_init(query->local, remote, iptype, socktype,
query->wait, &net);
query->wait, query->tls, query->tls_pin, &net);
if (ret != KNOT_EOK) {
continue;
}
......@@ -988,7 +988,7 @@ static void process_xfr(const query_t *query)
// Initialize network structure.
ret = net_init(query->local, remote, iptype, socktype,
query->wait, &net);
query->wait, query->tls, query->tls_pin, &net);
if (ret != KNOT_EOK) {
sign_context_deinit(&sign_ctx);
knot_pkt_free(&out_packet);
......@@ -1032,7 +1032,7 @@ int kdig_exec(const kdig_params_t *params)
// Loop over query list.
WALK_LIST(n, params->queries) {
query_t *query = (query_t *)n;
switch (query->operation) {
case OPERATION_QUERY:
process_query(query);
......
......@@ -530,6 +530,41 @@ static int opt_notcp(const char *arg, void *query)
return KNOT_EOK;
}
static int opt_tls(const char *arg, void *query)
{
query_t *q = query;
if (arg == NULL) {
// Opportunistic Privacy Profile
q->tls = TLS_PROFILE_OPPORTUNISTIC;
} else if (*arg == '\0') {
ERR("missing tls profile");
return KNOT_EFEWDATA;
} else {
// Out-of-Band Key-Pinned Privacy Profile
// hostname="hostname"
// pin-sha256="foo";pin-sha256="bar"
// ca-file="/etc/ssl/certs/ca-certificates.crt"
q->tls = TLS_PROFILE_OOB_PINNED;
q->tls_pin = strdup(arg);
}
if (q->protocol == PROTO_UDP) {
WARN("+tls cannot be used with +notcp; switching to +notcp\n");
}
return opt_tcp(arg, query);
}
static int opt_notls(const char *arg, void *query)
{
query_t *q = query;
q->tls = TLS_PROFILE_NONE;
return KNOT_EOK;
}
static int opt_ignore(const char *arg, void *query)
{
query_t *q = query;
......@@ -881,6 +916,9 @@ static const param_t kdig_opts2[] = {
{ "tcp", ARG_NONE, opt_tcp },
{ "notcp", ARG_NONE, opt_notcp },
{ "tls", ARG_OPTIONAL, opt_tls },
{ "notls", ARG_NONE, opt_notls },
{ "ignore", ARG_NONE, opt_ignore },
{ "noignore", ARG_NONE, opt_noignore },
......@@ -995,6 +1033,12 @@ query_t *query_create(const char *owner, const query_t *conf)
query->edns = conf->edns;
query->padding = conf->padding;
query->alignment = conf->alignment;
query->tls = conf->tls;
if (conf->tls_pin != NULL) {
query->tls_pin = strdup(conf->tls_pin); // FIXME
} else {
query->tls_pin = NULL;
}
if (conf->tsig_key.name != NULL) {
int ret = knot_tsig_key_copy(&query->tsig_key,
&conf->tsig_key);
......@@ -1337,6 +1381,8 @@ static void complete_servers(query_t *query, const query_t *conf)
def_port = query->port;
} else if (strlen(conf->port) > 0) {
def_port = conf->port;
} else if (conf->tls != TLS_PROFILE_NONE) {
def_port = DEFAULT_DNS_TLS_PORT;
} else {
def_port = DEFAULT_DNS_PORT;
}
......@@ -1472,6 +1518,11 @@ static void print_help(void)
" +[no]class Show DNS class.\n"
" +[no]ttl Show TTL value.\n"
" +[no]tcp Use TCP protocol.\n"
" +[no]tls Use DNS over TLS with Opportunistic Privacy Profile.\n"
" +[no]tls=pin Use DNS over TLS with Out-Of-Band Privacy Profile.\n"
" ca-file=/etc/ssl/ca-certificates.crt\n"
" pin-sha256=hpkp-style-pin\n"
" hostname=remote_peer_hostname\n"
" +[no]ignore Don't use TCP automatically if truncated.\n"
" +[no]nsid Request NSID.\n"
" +[no]bufsize=B Set EDNS buffer size.\n"
......
......@@ -136,6 +136,10 @@ struct query {
int32_t padding;
/*!< Query alignment with EDNS0 padding (0 ~ uninitialized). */
uint16_t alignment;
/*!< TLS Privacy Profile. */
tls_profile_t tls;
/*!< TLS Privacy Profile PIN. */
char *tls_pin;
#if USE_DNSTAP
/*!< Context for dnstap reader input. */
dt_reader_t *dt_reader;
......
......@@ -434,6 +434,8 @@ static int pkt_sendrecv(knsupdate_params_t *params)
get_iptype(params->ip),
get_socktype(params->protocol, KNOT_RRTYPE_SOA),
params->wait,
TLS_PROFILE_NONE, // TLS
NULL,
&net);
if (ret != KNOT_EOK) {
return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment