summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorreyk <>2015-02-09 09:23:39 +0000
committerreyk <>2015-02-09 09:23:39 +0000
commitba83f0a487d169240e07a7f1b6b97c6f5ae100ef (patch)
tree286e7d2e6be1a2a638c4d5b3c7070a8b70adf66a /src
parent24c49038fed6f28632c37bd797ee22d51c2f529f (diff)
downloadopenbsd-ba83f0a487d169240e07a7f1b6b97c6f5ae100ef.tar.gz
openbsd-ba83f0a487d169240e07a7f1b6b97c6f5ae100ef.tar.bz2
openbsd-ba83f0a487d169240e07a7f1b6b97c6f5ae100ef.zip
When parsing the host in tls_connect(), first check if it is a numeric
IPv4 or IPv6 address before trying to resolve the address with the AI_ADDRCONFIG flag set. This makes sure that attempts to connect to numeric IPs or loopback addresses are always possible and not prevented by AI_ADDRCONFIG. OK jsing@ tedu@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libtls/tls_client.c78
1 files changed, 49 insertions, 29 deletions
diff --git a/src/lib/libtls/tls_client.c b/src/lib/libtls/tls_client.c
index 0894ce6333..907c334f15 100644
--- a/src/lib/libtls/tls_client.c
+++ b/src/lib/libtls/tls_client.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: tls_client.c,v 1.12 2015/02/08 04:12:34 reyk Exp $ */ 1/* $OpenBSD: tls_client.c,v 1.13 2015/02/09 09:23:39 reyk Exp $ */
2/* 2/*
3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> 3 * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
4 * 4 *
@@ -44,10 +44,45 @@ tls_client(void)
44 return (ctx); 44 return (ctx);
45} 45}
46 46
47static int
48tls_connect_host(struct tls *ctx, const char *host, const char *port,
49 int af, int flag)
50{
51 struct addrinfo hints, *res, *res0;
52 int s = -1;
53
54 memset(&hints, 0, sizeof(hints));
55 hints.ai_family = af;
56 hints.ai_socktype = SOCK_STREAM;
57 hints.ai_flags = flag;
58
59 if ((s = getaddrinfo(host, port, &hints, &res0)) != 0) {
60 tls_set_error(ctx, "%s", gai_strerror(s));
61 return (-1);
62 }
63 for (res = res0; res; res = res->ai_next) {
64 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
65 if (s == -1) {
66 tls_set_error(ctx, "socket");
67 continue;
68 }
69 if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
70 tls_set_error(ctx, "connect");
71 close(s);
72 s = -1;
73 continue;
74 }
75
76 break; /* Connected. */
77 }
78 freeaddrinfo(res0);
79
80 return (s);
81}
82
47int 83int
48tls_connect(struct tls *ctx, const char *host, const char *port) 84tls_connect(struct tls *ctx, const char *host, const char *port)
49{ 85{
50 struct addrinfo hints, *res, *res0;
51 const char *h = NULL, *p = NULL; 86 const char *h = NULL, *p = NULL;
52 char *hs = NULL, *ps = NULL; 87 char *hs = NULL, *ps = NULL;
53 int rv = -1, s = -1, ret; 88 int rv = -1, s = -1, ret;
@@ -79,33 +114,18 @@ tls_connect(struct tls *ctx, const char *host, const char *port)
79 h = (hs != NULL) ? hs : host; 114 h = (hs != NULL) ? hs : host;
80 p = (ps != NULL) ? ps : port; 115 p = (ps != NULL) ? ps : port;
81 116
82 memset(&hints, 0, sizeof(hints)); 117 /*
83 hints.ai_family = AF_UNSPEC; 118 * First check if the host is specified as a numeric IP address,
84 hints.ai_socktype = SOCK_STREAM; 119 * either IPv4 or IPv6, before trying to resolve the host.
85 hints.ai_flags = AI_ADDRCONFIG; 120 * The AI_ADDRCONFIG resolver option will not return IPv4 or IPv6
86 121 * records if it is not configured on an interface; not considering
87 if ((ret = getaddrinfo(h, p, &hints, &res0)) != 0) { 122 * loopback addresses. Checking the numeric addresses first makes
88 tls_set_error(ctx, "%s", gai_strerror(ret)); 123 * sure that connection attempts to numeric addresses and especially
89 goto err; 124 * 127.0.0.1 or ::1 loopback addresses are always possible.
90 } 125 */
91 for (res = res0; res; res = res->ai_next) { 126 if ((s = tls_connect_host(ctx, h, p, AF_INET, AI_NUMERICHOST)) == -1 &&
92 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol); 127 (s = tls_connect_host(ctx, h, p, AF_INET6, AI_NUMERICHOST)) == -1 &&
93 if (s == -1) { 128 (s = tls_connect_host(ctx, h, p, AF_UNSPEC, AI_ADDRCONFIG)) == -1)
94 tls_set_error(ctx, "socket");
95 continue;
96 }
97 if (connect(s, res->ai_addr, res->ai_addrlen) == -1) {
98 tls_set_error(ctx, "connect");
99 close(s);
100 s = -1;
101 continue;
102 }
103
104 break; /* Connected. */
105 }
106 freeaddrinfo(res0);
107
108 if (s == -1)
109 goto err; 129 goto err;
110 130
111 if (tls_connect_socket(ctx, s, h) != 0) { 131 if (tls_connect_socket(ctx, s, h) != 0) {