net_help.c revision 307729
1/*
2 * util/net_help.c - implementation of the network helper code
3 *
4 * Copyright (c) 2007, NLnet Labs. All rights reserved.
5 *
6 * This software is open source.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * Neither the name of the NLNET LABS nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35/**
36 * \file
37 * Implementation of net_help.h.
38 */
39
40#include "config.h"
41#include "util/net_help.h"
42#include "util/log.h"
43#include "util/data/dname.h"
44#include "util/module.h"
45#include "util/regional.h"
46#include "sldns/parseutil.h"
47#include "sldns/wire2str.h"
48#include <fcntl.h>
49#ifdef HAVE_OPENSSL_SSL_H
50#include <openssl/ssl.h>
51#endif
52#ifdef HAVE_OPENSSL_ERR_H
53#include <openssl/err.h>
54#endif
55
56/** max length of an IP address (the address portion) that we allow */
57#define MAX_ADDR_STRLEN 128 /* characters */
58/** default value for EDNS ADVERTISED size */
59uint16_t EDNS_ADVERTISED_SIZE = 4096;
60
61/** minimal responses when positive answer: default is no */
62int MINIMAL_RESPONSES = 0;
63
64/** rrset order roundrobin: default is no */
65int RRSET_ROUNDROBIN = 0;
66
67/* returns true is string addr is an ip6 specced address */
68int
69str_is_ip6(const char* str)
70{
71	if(strchr(str, ':'))
72		return 1;
73	else    return 0;
74}
75
76int
77fd_set_nonblock(int s)
78{
79#ifdef HAVE_FCNTL
80	int flag;
81	if((flag = fcntl(s, F_GETFL)) == -1) {
82		log_err("can't fcntl F_GETFL: %s", strerror(errno));
83		flag = 0;
84	}
85	flag |= O_NONBLOCK;
86	if(fcntl(s, F_SETFL, flag) == -1) {
87		log_err("can't fcntl F_SETFL: %s", strerror(errno));
88		return 0;
89	}
90#elif defined(HAVE_IOCTLSOCKET)
91	unsigned long on = 1;
92	if(ioctlsocket(s, FIONBIO, &on) != 0) {
93		log_err("can't ioctlsocket FIONBIO on: %s",
94			wsa_strerror(WSAGetLastError()));
95	}
96#endif
97	return 1;
98}
99
100int
101fd_set_block(int s)
102{
103#ifdef HAVE_FCNTL
104	int flag;
105	if((flag = fcntl(s, F_GETFL)) == -1) {
106		log_err("cannot fcntl F_GETFL: %s", strerror(errno));
107		flag = 0;
108	}
109	flag &= ~O_NONBLOCK;
110	if(fcntl(s, F_SETFL, flag) == -1) {
111		log_err("cannot fcntl F_SETFL: %s", strerror(errno));
112		return 0;
113	}
114#elif defined(HAVE_IOCTLSOCKET)
115	unsigned long off = 0;
116	if(ioctlsocket(s, FIONBIO, &off) != 0) {
117		log_err("can't ioctlsocket FIONBIO off: %s",
118			wsa_strerror(WSAGetLastError()));
119	}
120#endif
121	return 1;
122}
123
124int
125is_pow2(size_t num)
126{
127	if(num == 0) return 1;
128	return (num & (num-1)) == 0;
129}
130
131void*
132memdup(void* data, size_t len)
133{
134	void* d;
135	if(!data) return NULL;
136	if(len == 0) return NULL;
137	d = malloc(len);
138	if(!d) return NULL;
139	memcpy(d, data, len);
140	return d;
141}
142
143void
144log_addr(enum verbosity_value v, const char* str,
145	struct sockaddr_storage* addr, socklen_t addrlen)
146{
147	uint16_t port;
148	const char* family = "unknown";
149	char dest[100];
150	int af = (int)((struct sockaddr_in*)addr)->sin_family;
151	void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
152	if(verbosity < v)
153		return;
154	switch(af) {
155		case AF_INET: family="ip4"; break;
156		case AF_INET6: family="ip6";
157			sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
158			break;
159		case AF_LOCAL:
160			dest[0]=0;
161			(void)inet_ntop(af, sinaddr, dest,
162				(socklen_t)sizeof(dest));
163			verbose(v, "%s local %s", str, dest);
164			return; /* do not continue and try to get port */
165		default: break;
166	}
167	if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
168		(void)strlcpy(dest, "(inet_ntop error)", sizeof(dest));
169	}
170	dest[sizeof(dest)-1] = 0;
171	port = ntohs(((struct sockaddr_in*)addr)->sin_port);
172	if(verbosity >= 4)
173		verbose(v, "%s %s %s port %d (len %d)", str, family, dest,
174			(int)port, (int)addrlen);
175	else	verbose(v, "%s %s port %d", str, dest, (int)port);
176}
177
178int
179extstrtoaddr(const char* str, struct sockaddr_storage* addr,
180	socklen_t* addrlen)
181{
182	char* s;
183	int port = UNBOUND_DNS_PORT;
184	if((s=strchr(str, '@'))) {
185		char buf[MAX_ADDR_STRLEN];
186		if(s-str >= MAX_ADDR_STRLEN) {
187			return 0;
188		}
189		(void)strlcpy(buf, str, sizeof(buf));
190		buf[s-str] = 0;
191		port = atoi(s+1);
192		if(port == 0 && strcmp(s+1,"0")!=0) {
193			return 0;
194		}
195		return ipstrtoaddr(buf, port, addr, addrlen);
196	}
197	return ipstrtoaddr(str, port, addr, addrlen);
198}
199
200
201int
202ipstrtoaddr(const char* ip, int port, struct sockaddr_storage* addr,
203	socklen_t* addrlen)
204{
205	uint16_t p;
206	if(!ip) return 0;
207	p = (uint16_t) port;
208	if(str_is_ip6(ip)) {
209		char buf[MAX_ADDR_STRLEN];
210		char* s;
211		struct sockaddr_in6* sa = (struct sockaddr_in6*)addr;
212		*addrlen = (socklen_t)sizeof(struct sockaddr_in6);
213		memset(sa, 0, *addrlen);
214		sa->sin6_family = AF_INET6;
215		sa->sin6_port = (in_port_t)htons(p);
216		if((s=strchr(ip, '%'))) { /* ip6%interface, rfc 4007 */
217			if(s-ip >= MAX_ADDR_STRLEN)
218				return 0;
219			(void)strlcpy(buf, ip, sizeof(buf));
220			buf[s-ip]=0;
221			sa->sin6_scope_id = (uint32_t)atoi(s+1);
222			ip = buf;
223		}
224		if(inet_pton((int)sa->sin6_family, ip, &sa->sin6_addr) <= 0) {
225			return 0;
226		}
227	} else { /* ip4 */
228		struct sockaddr_in* sa = (struct sockaddr_in*)addr;
229		*addrlen = (socklen_t)sizeof(struct sockaddr_in);
230		memset(sa, 0, *addrlen);
231		sa->sin_family = AF_INET;
232		sa->sin_port = (in_port_t)htons(p);
233		if(inet_pton((int)sa->sin_family, ip, &sa->sin_addr) <= 0) {
234			return 0;
235		}
236	}
237	return 1;
238}
239
240int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr,
241        socklen_t* addrlen, int* net)
242{
243	char* s = NULL;
244	*net = (str_is_ip6(str)?128:32);
245	if((s=strchr(str, '/'))) {
246		if(atoi(s+1) > *net) {
247			log_err("netblock too large: %s", str);
248			return 0;
249		}
250		*net = atoi(s+1);
251		if(*net == 0 && strcmp(s+1, "0") != 0) {
252			log_err("cannot parse netblock: '%s'", str);
253			return 0;
254		}
255		if(!(s = strdup(str))) {
256			log_err("out of memory");
257			return 0;
258		}
259		*strchr(s, '/') = '\0';
260	}
261	if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) {
262		free(s);
263		log_err("cannot parse ip address: '%s'", str);
264		return 0;
265	}
266	if(s) {
267		free(s);
268		addr_mask(addr, *addrlen, *net);
269	}
270	return 1;
271}
272
273void
274log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name,
275	uint16_t type, uint16_t dclass)
276{
277	char buf[LDNS_MAX_DOMAINLEN+1];
278	char t[12], c[12];
279	const char *ts, *cs;
280	if(verbosity < v)
281		return;
282	dname_str(name, buf);
283	if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG";
284	else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR";
285	else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR";
286	else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB";
287	else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA";
288	else if(type == LDNS_RR_TYPE_ANY) ts = "ANY";
289	else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name)
290		ts = sldns_rr_descript(type)->_name;
291	else {
292		snprintf(t, sizeof(t), "TYPE%d", (int)type);
293		ts = t;
294	}
295	if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) &&
296		sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name)
297		cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name;
298	else {
299		snprintf(c, sizeof(c), "CLASS%d", (int)dclass);
300		cs = c;
301	}
302	log_info("%s %s %s %s", str, buf, ts, cs);
303}
304
305void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone,
306	struct sockaddr_storage* addr, socklen_t addrlen)
307{
308	uint16_t port;
309	const char* family = "unknown_family ";
310	char namebuf[LDNS_MAX_DOMAINLEN+1];
311	char dest[100];
312	int af = (int)((struct sockaddr_in*)addr)->sin_family;
313	void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
314	if(verbosity < v)
315		return;
316	switch(af) {
317		case AF_INET: family=""; break;
318		case AF_INET6: family="";
319			sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
320			break;
321		case AF_LOCAL: family="local "; break;
322		default: break;
323	}
324	if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
325		(void)strlcpy(dest, "(inet_ntop error)", sizeof(dest));
326	}
327	dest[sizeof(dest)-1] = 0;
328	port = ntohs(((struct sockaddr_in*)addr)->sin_port);
329	dname_str(zone, namebuf);
330	if(af != AF_INET && af != AF_INET6)
331		verbose(v, "%s <%s> %s%s#%d (addrlen %d)",
332			str, namebuf, family, dest, (int)port, (int)addrlen);
333	else	verbose(v, "%s <%s> %s%s#%d",
334			str, namebuf, family, dest, (int)port);
335}
336
337void log_err_addr(const char* str, const char* err,
338	struct sockaddr_storage* addr, socklen_t addrlen)
339{
340	uint16_t port;
341	char dest[100];
342	int af = (int)((struct sockaddr_in*)addr)->sin_family;
343	void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
344	if(af == AF_INET6)
345		sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
346	if(inet_ntop(af, sinaddr, dest, (socklen_t)sizeof(dest)) == 0) {
347		(void)strlcpy(dest, "(inet_ntop error)", sizeof(dest));
348	}
349	dest[sizeof(dest)-1] = 0;
350	port = ntohs(((struct sockaddr_in*)addr)->sin_port);
351	if(verbosity >= 4)
352		log_err("%s: %s for %s port %d (len %d)", str, err, dest,
353			(int)port, (int)addrlen);
354	else	log_err("%s: %s for %s", str, err, dest);
355}
356
357int
358sockaddr_cmp(struct sockaddr_storage* addr1, socklen_t len1,
359	struct sockaddr_storage* addr2, socklen_t len2)
360{
361	struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1;
362	struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2;
363	struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1;
364	struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2;
365	if(len1 < len2)
366		return -1;
367	if(len1 > len2)
368		return 1;
369	log_assert(len1 == len2);
370	if( p1_in->sin_family < p2_in->sin_family)
371		return -1;
372	if( p1_in->sin_family > p2_in->sin_family)
373		return 1;
374	log_assert( p1_in->sin_family == p2_in->sin_family );
375	/* compare ip4 */
376	if( p1_in->sin_family == AF_INET ) {
377		/* just order it, ntohs not required */
378		if(p1_in->sin_port < p2_in->sin_port)
379			return -1;
380		if(p1_in->sin_port > p2_in->sin_port)
381			return 1;
382		log_assert(p1_in->sin_port == p2_in->sin_port);
383		return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE);
384	} else if (p1_in6->sin6_family == AF_INET6) {
385		/* just order it, ntohs not required */
386		if(p1_in6->sin6_port < p2_in6->sin6_port)
387			return -1;
388		if(p1_in6->sin6_port > p2_in6->sin6_port)
389			return 1;
390		log_assert(p1_in6->sin6_port == p2_in6->sin6_port);
391		return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr,
392			INET6_SIZE);
393	} else {
394		/* eek unknown type, perform this comparison for sanity. */
395		return memcmp(addr1, addr2, len1);
396	}
397}
398
399int
400sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1,
401	struct sockaddr_storage* addr2, socklen_t len2)
402{
403	struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1;
404	struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2;
405	struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1;
406	struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2;
407	if(len1 < len2)
408		return -1;
409	if(len1 > len2)
410		return 1;
411	log_assert(len1 == len2);
412	if( p1_in->sin_family < p2_in->sin_family)
413		return -1;
414	if( p1_in->sin_family > p2_in->sin_family)
415		return 1;
416	log_assert( p1_in->sin_family == p2_in->sin_family );
417	/* compare ip4 */
418	if( p1_in->sin_family == AF_INET ) {
419		return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE);
420	} else if (p1_in6->sin6_family == AF_INET6) {
421		return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr,
422			INET6_SIZE);
423	} else {
424		/* eek unknown type, perform this comparison for sanity. */
425		return memcmp(addr1, addr2, len1);
426	}
427}
428
429int
430addr_is_ip6(struct sockaddr_storage* addr, socklen_t len)
431{
432	if(len == (socklen_t)sizeof(struct sockaddr_in6) &&
433		((struct sockaddr_in6*)addr)->sin6_family == AF_INET6)
434		return 1;
435	else    return 0;
436}
437
438void
439addr_mask(struct sockaddr_storage* addr, socklen_t len, int net)
440{
441	uint8_t mask[8] = {0x0, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe};
442	int i, max;
443	uint8_t* s;
444	if(addr_is_ip6(addr, len)) {
445		s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr;
446		max = 128;
447	} else {
448		s = (uint8_t*)&((struct sockaddr_in*)addr)->sin_addr;
449		max = 32;
450	}
451	if(net >= max)
452		return;
453	for(i=net/8+1; i<max/8; i++) {
454		s[i] = 0;
455	}
456	s[net/8] &= mask[net&0x7];
457}
458
459int
460addr_in_common(struct sockaddr_storage* addr1, int net1,
461	struct sockaddr_storage* addr2, int net2, socklen_t addrlen)
462{
463	int min = (net1<net2)?net1:net2;
464	int i, to;
465	int match = 0;
466	uint8_t* s1, *s2;
467	if(addr_is_ip6(addr1, addrlen)) {
468		s1 = (uint8_t*)&((struct sockaddr_in6*)addr1)->sin6_addr;
469		s2 = (uint8_t*)&((struct sockaddr_in6*)addr2)->sin6_addr;
470		to = 16;
471	} else {
472		s1 = (uint8_t*)&((struct sockaddr_in*)addr1)->sin_addr;
473		s2 = (uint8_t*)&((struct sockaddr_in*)addr2)->sin_addr;
474		to = 4;
475	}
476	/* match = bits_in_common(s1, s2, to); */
477	for(i=0; i<to; i++) {
478		if(s1[i] == s2[i]) {
479			match += 8;
480		} else {
481			uint8_t z = s1[i]^s2[i];
482			log_assert(z);
483			while(!(z&0x80)) {
484				match++;
485				z<<=1;
486			}
487			break;
488		}
489	}
490	if(match > min) match = min;
491	return match;
492}
493
494void
495addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen,
496	char* buf, size_t len)
497{
498	int af = (int)((struct sockaddr_in*)addr)->sin_family;
499	void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
500	if(addr_is_ip6(addr, addrlen))
501		sinaddr = &((struct sockaddr_in6*)addr)->sin6_addr;
502	if(inet_ntop(af, sinaddr, buf, (socklen_t)len) == 0) {
503		snprintf(buf, len, "(inet_ntop_error)");
504	}
505}
506
507int
508addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen)
509{
510	/* prefix for ipv4 into ipv6 mapping is ::ffff:x.x.x.x */
511	const uint8_t map_prefix[16] =
512		{0,0,0,0,  0,0,0,0, 0,0,0xff,0xff, 0,0,0,0};
513	uint8_t* s;
514	if(!addr_is_ip6(addr, addrlen))
515		return 0;
516	/* s is 16 octet ipv6 address string */
517	s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr;
518	return (memcmp(s, map_prefix, 12) == 0);
519}
520
521int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen)
522{
523	int af = (int)((struct sockaddr_in*)addr)->sin_family;
524	void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
525	return af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in)
526		&& memcmp(sinaddr, "\377\377\377\377", 4) == 0;
527}
528
529int addr_is_any(struct sockaddr_storage* addr, socklen_t addrlen)
530{
531	int af = (int)((struct sockaddr_in*)addr)->sin_family;
532	void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr;
533	void* sin6addr = &((struct sockaddr_in6*)addr)->sin6_addr;
534	if(af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in)
535		&& memcmp(sinaddr, "\000\000\000\000", 4) == 0)
536		return 1;
537	else if(af==AF_INET6 && addrlen>=(socklen_t)sizeof(struct sockaddr_in6)
538		&& memcmp(sin6addr, "\000\000\000\000\000\000\000\000"
539		"\000\000\000\000\000\000\000\000", 16) == 0)
540		return 1;
541	return 0;
542}
543
544void sock_list_insert(struct sock_list** list, struct sockaddr_storage* addr,
545	socklen_t len, struct regional* region)
546{
547	struct sock_list* add = (struct sock_list*)regional_alloc(region,
548		sizeof(*add) - sizeof(add->addr) + (size_t)len);
549	if(!add) {
550		log_err("out of memory in socketlist insert");
551		return;
552	}
553	log_assert(list);
554	add->next = *list;
555	add->len = len;
556	*list = add;
557	if(len) memmove(&add->addr, addr, len);
558}
559
560void sock_list_prepend(struct sock_list** list, struct sock_list* add)
561{
562	struct sock_list* last = add;
563	if(!last)
564		return;
565	while(last->next)
566		last = last->next;
567	last->next = *list;
568	*list = add;
569}
570
571int sock_list_find(struct sock_list* list, struct sockaddr_storage* addr,
572        socklen_t len)
573{
574	while(list) {
575		if(len == list->len) {
576			if(len == 0 || sockaddr_cmp_addr(addr, len,
577				&list->addr, list->len) == 0)
578				return 1;
579		}
580		list = list->next;
581	}
582	return 0;
583}
584
585void sock_list_merge(struct sock_list** list, struct regional* region,
586	struct sock_list* add)
587{
588	struct sock_list* p;
589	for(p=add; p; p=p->next) {
590		if(!sock_list_find(*list, &p->addr, p->len))
591			sock_list_insert(list, &p->addr, p->len, region);
592	}
593}
594
595void
596log_crypto_err(const char* str)
597{
598#ifdef HAVE_SSL
599	/* error:[error code]:[library name]:[function name]:[reason string] */
600	char buf[128];
601	unsigned long e;
602	ERR_error_string_n(ERR_get_error(), buf, sizeof(buf));
603	log_err("%s crypto %s", str, buf);
604	while( (e=ERR_get_error()) ) {
605		ERR_error_string_n(e, buf, sizeof(buf));
606		log_err("and additionally crypto %s", buf);
607	}
608#else
609	(void)str;
610#endif /* HAVE_SSL */
611}
612
613void* listen_sslctx_create(char* key, char* pem, char* verifypem)
614{
615#ifdef HAVE_SSL
616	SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method());
617	if(!ctx) {
618		log_crypto_err("could not SSL_CTX_new");
619		return NULL;
620	}
621	/* no SSLv2, SSLv3 because has defects */
622	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
623		!= SSL_OP_NO_SSLv2){
624		log_crypto_err("could not set SSL_OP_NO_SSLv2");
625		SSL_CTX_free(ctx);
626		return NULL;
627	}
628	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
629		!= SSL_OP_NO_SSLv3){
630		log_crypto_err("could not set SSL_OP_NO_SSLv3");
631		SSL_CTX_free(ctx);
632		return NULL;
633	}
634	if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) {
635		log_err("error for cert file: %s", pem);
636		log_crypto_err("error in SSL_CTX use_certificate_chain_file");
637		SSL_CTX_free(ctx);
638		return NULL;
639	}
640	if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) {
641		log_err("error for private key file: %s", key);
642		log_crypto_err("Error in SSL_CTX use_PrivateKey_file");
643		SSL_CTX_free(ctx);
644		return NULL;
645	}
646	if(!SSL_CTX_check_private_key(ctx)) {
647		log_err("error for key file: %s", key);
648		log_crypto_err("Error in SSL_CTX check_private_key");
649		SSL_CTX_free(ctx);
650		return NULL;
651	}
652#if HAVE_DECL_SSL_CTX_SET_ECDH_AUTO
653	if(!SSL_CTX_set_ecdh_auto(ctx,1)) {
654		log_crypto_err("Error in SSL_CTX_ecdh_auto, not enabling ECDHE");
655	}
656#elif defined(USE_ECDSA)
657	if(1) {
658		EC_KEY *ecdh = EC_KEY_new_by_curve_name (NID_X9_62_prime256v1);
659		if (!ecdh) {
660			log_crypto_err("could not find p256, not enabling ECDHE");
661		} else {
662			if (1 != SSL_CTX_set_tmp_ecdh (ctx, ecdh)) {
663				log_crypto_err("Error in SSL_CTX_set_tmp_ecdh, not enabling ECDHE");
664			}
665			EC_KEY_free (ecdh);
666		}
667	}
668#endif
669
670	if(verifypem && verifypem[0]) {
671		if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) {
672			log_crypto_err("Error in SSL_CTX verify locations");
673			SSL_CTX_free(ctx);
674			return NULL;
675		}
676		SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(
677			verifypem));
678		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
679	}
680	return ctx;
681#else
682	(void)key; (void)pem; (void)verifypem;
683	return NULL;
684#endif
685}
686
687void* connect_sslctx_create(char* key, char* pem, char* verifypem)
688{
689#ifdef HAVE_SSL
690	SSL_CTX* ctx = SSL_CTX_new(SSLv23_client_method());
691	if(!ctx) {
692		log_crypto_err("could not allocate SSL_CTX pointer");
693		return NULL;
694	}
695	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2)
696		!= SSL_OP_NO_SSLv2) {
697		log_crypto_err("could not set SSL_OP_NO_SSLv2");
698		SSL_CTX_free(ctx);
699		return NULL;
700	}
701	if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3) & SSL_OP_NO_SSLv3)
702		!= SSL_OP_NO_SSLv3) {
703		log_crypto_err("could not set SSL_OP_NO_SSLv3");
704		SSL_CTX_free(ctx);
705		return NULL;
706	}
707	if(key && key[0]) {
708		if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) {
709			log_err("error in client certificate %s", pem);
710			log_crypto_err("error in certificate file");
711			SSL_CTX_free(ctx);
712			return NULL;
713		}
714		if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) {
715			log_err("error in client private key %s", key);
716			log_crypto_err("error in key file");
717			SSL_CTX_free(ctx);
718			return NULL;
719		}
720		if(!SSL_CTX_check_private_key(ctx)) {
721			log_err("error in client key %s", key);
722			log_crypto_err("error in SSL_CTX_check_private_key");
723			SSL_CTX_free(ctx);
724			return NULL;
725		}
726	}
727	if(verifypem && verifypem[0]) {
728		if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) {
729			log_crypto_err("error in SSL_CTX verify");
730			SSL_CTX_free(ctx);
731			return NULL;
732		}
733		SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
734	}
735	return ctx;
736#else
737	(void)key; (void)pem; (void)verifypem;
738	return NULL;
739#endif
740}
741
742void* incoming_ssl_fd(void* sslctx, int fd)
743{
744#ifdef HAVE_SSL
745	SSL* ssl = SSL_new((SSL_CTX*)sslctx);
746	if(!ssl) {
747		log_crypto_err("could not SSL_new");
748		return NULL;
749	}
750	SSL_set_accept_state(ssl);
751	(void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
752	if(!SSL_set_fd(ssl, fd)) {
753		log_crypto_err("could not SSL_set_fd");
754		SSL_free(ssl);
755		return NULL;
756	}
757	return ssl;
758#else
759	(void)sslctx; (void)fd;
760	return NULL;
761#endif
762}
763
764void* outgoing_ssl_fd(void* sslctx, int fd)
765{
766#ifdef HAVE_SSL
767	SSL* ssl = SSL_new((SSL_CTX*)sslctx);
768	if(!ssl) {
769		log_crypto_err("could not SSL_new");
770		return NULL;
771	}
772	SSL_set_connect_state(ssl);
773	(void)SSL_set_mode(ssl, SSL_MODE_AUTO_RETRY);
774	if(!SSL_set_fd(ssl, fd)) {
775		log_crypto_err("could not SSL_set_fd");
776		SSL_free(ssl);
777		return NULL;
778	}
779	return ssl;
780#else
781	(void)sslctx; (void)fd;
782	return NULL;
783#endif
784}
785
786#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L
787/** global lock list for openssl locks */
788static lock_basic_t *ub_openssl_locks = NULL;
789
790/** callback that gets thread id for openssl */
791static unsigned long
792ub_crypto_id_cb(void)
793{
794	return (unsigned long)log_thread_get();
795}
796
797static void
798ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file),
799	int ATTR_UNUSED(line))
800{
801	if((mode&CRYPTO_LOCK)) {
802		lock_basic_lock(&ub_openssl_locks[type]);
803	} else {
804		lock_basic_unlock(&ub_openssl_locks[type]);
805	}
806}
807#endif /* OPENSSL_THREADS */
808
809int ub_openssl_lock_init(void)
810{
811#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L
812	int i;
813	ub_openssl_locks = (lock_basic_t*)reallocarray(
814		NULL, (size_t)CRYPTO_num_locks(), sizeof(lock_basic_t));
815	if(!ub_openssl_locks)
816		return 0;
817	for(i=0; i<CRYPTO_num_locks(); i++) {
818		lock_basic_init(&ub_openssl_locks[i]);
819	}
820	CRYPTO_set_id_callback(&ub_crypto_id_cb);
821	CRYPTO_set_locking_callback(&ub_crypto_lock_cb);
822#endif /* OPENSSL_THREADS */
823	return 1;
824}
825
826void ub_openssl_lock_delete(void)
827{
828#if defined(HAVE_SSL) && defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) && defined(CRYPTO_LOCK) && OPENSSL_VERSION_NUMBER < 0x10100000L
829	int i;
830	if(!ub_openssl_locks)
831		return;
832	CRYPTO_set_id_callback(NULL);
833	CRYPTO_set_locking_callback(NULL);
834	for(i=0; i<CRYPTO_num_locks(); i++) {
835		lock_basic_destroy(&ub_openssl_locks[i]);
836	}
837	free(ub_openssl_locks);
838#endif /* OPENSSL_THREADS */
839}
840
841