Ensure all calls to getaddrinfo are headed by a block_dns check.
If block_dns is set, call getaddrinfo with AI_NUMERICHOST set and AI_CANONNAME clear. Some paths may not have set AI_CANONNAME, but it's easier to audit this way when the getaddrinfo prelude is uniform across call sites, and the compiler can optimize it away.
This commit is contained in:

committed by
Nico Williams

parent
fa4c4430f6
commit
fd77c4000d
@@ -246,6 +246,11 @@ start_server(krb5_context contextp, const char *port_str)
|
||||
hints.ai_flags = AI_PASSIVE;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns",
|
||||
NULL)) {
|
||||
hints.ai_flags &= ~AI_CANONNAME;
|
||||
hints.ai_flags |= AI_NUMERICHOST|AI_NUMERICSERV;
|
||||
}
|
||||
e = getaddrinfo(NULL, p->port, &hints, &ai);
|
||||
if(e) {
|
||||
snprintf(portstr, sizeof(portstr), "%u", p->def_port);
|
||||
|
@@ -61,6 +61,11 @@ open_socket(krb5_context context, const char *hostname, const char *port)
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
hints.ai_protocol = IPPROTO_TCP;
|
||||
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns",
|
||||
NULL)) {
|
||||
hints.ai_flags &= ~AI_CANONNAME;
|
||||
hints.ai_flags |= AI_NUMERICHOST|AI_NUMERICSERV;
|
||||
}
|
||||
error = getaddrinfo (hostname, port, &hints, &ai);
|
||||
if (error) {
|
||||
warnx ("%s: %s", hostname, gai_strerror(error));
|
||||
|
@@ -571,6 +571,11 @@ kadm_connect(kadm5_client_context *ctx)
|
||||
if (slash != NULL)
|
||||
hostname = slash + 1;
|
||||
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns",
|
||||
NULL)) {
|
||||
hints.ai_flags &= ~AI_CANONNAME;
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
}
|
||||
error = getaddrinfo(hostname, portstr, &hints, &ai);
|
||||
if (error) {
|
||||
ret = KADM5_BAD_SERVER_NAME;
|
||||
|
@@ -70,6 +70,11 @@ connect_to_master (krb5_context context, const char *master,
|
||||
port_str = port;
|
||||
}
|
||||
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns",
|
||||
NULL)) {
|
||||
hints.ai_flags &= ~AI_CANONNAME;
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
}
|
||||
error = getaddrinfo(master, port_str, &hints, &ai);
|
||||
if (error) {
|
||||
krb5_warnx(context, "Failed to get address of to %s: %s",
|
||||
|
@@ -1210,6 +1210,11 @@ krb5_parse_address(krb5_context context,
|
||||
/* if not parsed as numeric address, do a name lookup */
|
||||
memset(&hint, 0, sizeof(hint));
|
||||
hint.ai_family = AF_UNSPEC;
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns",
|
||||
NULL)) {
|
||||
hint.ai_flags &= ~AI_CANONNAME;
|
||||
hint.ai_flags |= AI_NUMERICHOST;
|
||||
}
|
||||
error = getaddrinfo (string, NULL, &hint, &ai);
|
||||
if (error) {
|
||||
krb5_error_code ret2;
|
||||
|
@@ -68,7 +68,8 @@ krb5_expand_hostname (krb5_context context,
|
||||
struct addrinfo *ai, *a, hints;
|
||||
int error;
|
||||
|
||||
if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0)
|
||||
if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0 ||
|
||||
krb5_config_get_bool(context, NULL, "libdefaults", "block_dns", NULL))
|
||||
return copy_hostname (context, orig_hostname, new_hostname);
|
||||
|
||||
memset (&hints, 0, sizeof(hints));
|
||||
|
@@ -50,6 +50,14 @@ gethostname_fallback (krb5_context context, krb5_addresses *res)
|
||||
char hostname[MAXHOSTNAMELEN];
|
||||
struct hostent *hostent;
|
||||
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns",
|
||||
NULL)) {
|
||||
ret = ENXIO;
|
||||
krb5_set_error_message(context, ret,
|
||||
"DNS blocked in gethostname fallback");
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (gethostname (hostname, sizeof(hostname))) {
|
||||
ret = errno;
|
||||
krb5_set_error_message(context, ret, "gethostname: %s", strerror(ret));
|
||||
|
@@ -329,7 +329,7 @@ get_addresses(krb5_context context,
|
||||
krb5_creds *ticket;
|
||||
krb5_const_realm realm;
|
||||
krb5_boolean noaddr;
|
||||
struct addrinfo *ai;
|
||||
struct addrinfo *ai, hints;
|
||||
int eai;
|
||||
|
||||
if (hostname == 0)
|
||||
@@ -349,8 +349,13 @@ get_addresses(krb5_context context,
|
||||
return 0;
|
||||
|
||||
/* Need addresses, get the address of the remote host. */
|
||||
|
||||
eai = getaddrinfo (hostname, NULL, NULL, &ai);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns",
|
||||
NULL)) {
|
||||
hints.ai_flags &= ~AI_CANONNAME;
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
}
|
||||
eai = getaddrinfo(hostname, NULL, &hints, &ai);
|
||||
if (eai) {
|
||||
ret = krb5_eai_to_heim_errno(eai, errno);
|
||||
krb5_set_error_message(context, ret,
|
||||
|
@@ -430,6 +430,11 @@ krb5_krbhst_get_addrinfo(krb5_context context, krb5_krbhst_info *host,
|
||||
snprintf (portstr, sizeof(portstr), "%d", host->port);
|
||||
make_hints(&hints, host->proto);
|
||||
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns",
|
||||
NULL)) {
|
||||
hints.ai_flags &= ~AI_CANONNAME;
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
}
|
||||
ret = getaddrinfo(host->hostname, portstr, &hints, &host->ai);
|
||||
if (ret) {
|
||||
ret = krb5_eai_to_heim_errno(ret, errno);
|
||||
@@ -550,6 +555,11 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd,
|
||||
|
||||
make_hints(&hints, proto);
|
||||
snprintf(portstr, sizeof(portstr), "%d", port);
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns",
|
||||
NULL)) {
|
||||
hints.ai_flags &= ~AI_CANONNAME;
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
}
|
||||
ret = getaddrinfo(host, portstr, &hints, &ai);
|
||||
if (ret) {
|
||||
/* no more hosts, so we're done here */
|
||||
@@ -718,6 +728,13 @@ plugin_get_hosts(krb5_context context,
|
||||
{
|
||||
struct plctx ctx = { type, kd, 0 };
|
||||
|
||||
/*
|
||||
* XXX Need a way to pass this through -- unsure if any of this is
|
||||
* useful without DNS, though.
|
||||
*/
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns", NULL))
|
||||
return;
|
||||
|
||||
if (_krb5_homedir_access(context))
|
||||
ctx.flags |= KRB5_PLF_ALLOW_HOMEDIR;
|
||||
|
||||
|
@@ -857,6 +857,11 @@ submit_request(krb5_context context, krb5_sendto_ctx ctx, krb5_krbhst_info *hi)
|
||||
nport = init_port(el, htons(80));
|
||||
snprintf(portstr, sizeof(portstr), "%d", ntohs(nport));
|
||||
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns",
|
||||
NULL)) {
|
||||
hints.ai_flags &= ~AI_CANONNAME;
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
}
|
||||
ret = getaddrinfo(proxy, portstr, &hints, &ai);
|
||||
free(proxy2);
|
||||
if (ret)
|
||||
|
@@ -202,6 +202,11 @@ check_host(krb5_context context, const char *path, char *data)
|
||||
defport = tmp;
|
||||
snprintf(service, sizeof(service), "%u", defport);
|
||||
}
|
||||
if (krb5_config_get_bool(context, NULL, "libdefaults", "block_dns",
|
||||
NULL)) {
|
||||
hints.ai_flags &= ~AI_CANONNAME;
|
||||
hints.ai_flags |= AI_NUMERICHOST;
|
||||
}
|
||||
ret = getaddrinfo(hostname, service, &hints, &ai);
|
||||
if (ret == EAI_SERVICE && !isdigit((unsigned char)service[0])) {
|
||||
snprintf(service, sizeof(service), "%u", defport);
|
||||
|
Reference in New Issue
Block a user