changed from 1.0p1 to 1.0p2
[libradsec.git] / radsecproxy.c
1 /*
2  * Copyright (C) 2006-2008 Stig Venaas <venaas@uninett.no>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  */
8
9 /* For UDP there is one server instance consisting of udpserverrd and udpserverth
10  *              rd is responsible for init and launching wr
11  * For TLS there is a server instance that launches tlsserverrd for each TLS peer
12  *          each tlsserverrd launches tlsserverwr
13  * For each UDP/TLS peer there is clientrd and clientwr, clientwr is responsible
14  *          for init and launching rd
15  *
16  * serverrd will receive a request, processes it and puts it in the requestq of
17  *          the appropriate clientwr
18  * clientwr monitors its requestq and sends requests
19  * clientrd looks for responses, processes them and puts them in the replyq of
20  *          the peer the request came from
21  * serverwr monitors its reply and sends replies
22  *
23  * In addition to the main thread, we have:
24  * If UDP peers are configured, there will be 2 + 2 * #peers UDP threads
25  * If TLS peers are configured, there will initially be 2 * #peers TLS threads
26  * For each TLS peer connecting to us there will be 2 more TLS threads
27  *       This is only for connected peers
28  * Example: With 3 UDP peer and 30 TLS peers, there will be a max of
29  *          1 + (2 + 2 * 3) + (2 * 30) + (2 * 30) = 129 threads
30 */
31
32 #include <signal.h>
33 #include <sys/socket.h>
34 #include <netinet/in.h>
35 #include <netdb.h>
36 #include <string.h>
37 #include <unistd.h>
38 #include <sys/time.h>
39 #include <sys/types.h>
40 #include <arpa/inet.h>
41 #include <regex.h>
42 #include <libgen.h>
43 #include <pthread.h>
44 #include <openssl/ssl.h>
45 #include <openssl/rand.h>
46 #include <openssl/err.h>
47 #include <openssl/md5.h>
48 #include <openssl/hmac.h>
49 #include <openssl/x509v3.h>
50 #include "debug.h"
51 #include "radsecproxy.h"
52
53 static struct options options;
54 static struct client *clients = NULL;
55 static struct server *servers = NULL;
56 static struct realm *realms = NULL;
57 static struct tls *tlsconfs = NULL;
58
59 static int client_udp_count = 0;
60 static int client_tls_count = 0;
61 static int client_count = 0;
62 static int server_udp_count = 0;
63 static int server_tls_count = 0;
64 static int server_count = 0;
65 static int realm_count = 0;
66 static int tls_count = 0;
67
68 static struct peer *tcp_server_listen;
69 static struct peer *udp_server_listen;
70 static struct replyq udp_server_replyq;
71 static int udp_server_sock = -1;
72 static pthread_mutex_t *ssl_locks;
73 static long *ssl_lock_count;
74 extern int optind;
75 extern char *optarg;
76
77 /* callbacks for making OpenSSL thread safe */
78 unsigned long ssl_thread_id() {
79         return (unsigned long)pthread_self();
80 }
81
82 void ssl_locking_callback(int mode, int type, const char *file, int line) {
83     if (mode & CRYPTO_LOCK) {
84         pthread_mutex_lock(&ssl_locks[type]);
85         ssl_lock_count[type]++;
86     } else
87         pthread_mutex_unlock(&ssl_locks[type]);
88 }
89
90 static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) {
91     int pwdlen = strlen(userdata);
92     if (rwflag != 0 || pwdlen > size) /* not for decryption or too large */
93         return 0;
94     memcpy(buf, userdata, pwdlen);
95     return pwdlen;
96 }
97
98 static int verify_cb(int ok, X509_STORE_CTX *ctx) {
99   char buf[256];
100   X509 *err_cert;
101   int err, depth;
102
103   err_cert = X509_STORE_CTX_get_current_cert(ctx);
104   err = X509_STORE_CTX_get_error(ctx);
105   depth = X509_STORE_CTX_get_error_depth(ctx);
106
107   if (depth > MAX_CERT_DEPTH) {
108       ok = 0;
109       err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
110       X509_STORE_CTX_set_error(ctx, err);
111   }
112
113   if (!ok) {
114       X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
115       debug(DBG_WARN, "verify error: num=%d:%s:depth=%d:%s", err, X509_verify_cert_error_string(err), depth, buf);
116
117       switch (err) {
118       case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
119           X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
120           debug(DBG_WARN, "\tIssuer=%s", buf);
121           break;
122       case X509_V_ERR_CERT_NOT_YET_VALID:
123       case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
124           debug(DBG_WARN, "\tCertificate not yet valid");
125           break;
126       case X509_V_ERR_CERT_HAS_EXPIRED:
127           debug(DBG_WARN, "Certificate has expired");
128           break;
129       case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
130           debug(DBG_WARN, "Certificate no longer valid (after notAfter)");
131           break;
132       }
133   }
134 #ifdef DEBUG  
135   printf("certificate verify returns %d\n", ok);
136 #endif  
137   return ok;
138 }
139
140 int resolvepeer(struct peer *peer, int ai_flags) {
141     struct addrinfo hints, *addrinfo;
142     
143     memset(&hints, 0, sizeof(hints));
144     hints.ai_socktype = (peer->type == 'T' ? SOCK_STREAM : SOCK_DGRAM);
145     hints.ai_family = AF_UNSPEC;
146     hints.ai_flags = ai_flags;
147     if (getaddrinfo(peer->host, peer->port, &hints, &addrinfo)) {
148         debug(DBG_WARN, "resolvepeer: can't resolve %s port %s", peer->host, peer->port);
149         return 0;
150     }
151
152     if (peer->addrinfo)
153         freeaddrinfo(peer->addrinfo);
154     peer->addrinfo = addrinfo;
155     return 1;
156 }         
157
158 int connecttoserver(struct addrinfo *addrinfo) {
159     int s;
160     struct addrinfo *res;
161
162     s = -1;
163     for (res = addrinfo; res; res = res->ai_next) {
164         s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
165         if (s < 0) {
166             debug(DBG_WARN, "connecttoserver: socket failed");
167             continue;
168         }
169         if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
170             break;
171         debug(DBG_WARN, "connecttoserver: connect failed");
172         close(s);
173         s = -1;
174     }
175     return s;
176 }         
177
178 int bindtoaddr(struct addrinfo *addrinfo) {
179     int s, on = 1;
180     struct addrinfo *res;
181     
182     for (res = addrinfo; res; res = res->ai_next) {
183         s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
184         if (s < 0) {
185             debug(DBG_WARN, "bindtoaddr: socket failed");
186             continue;
187         }
188         setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
189         if (!bind(s, res->ai_addr, res->ai_addrlen))
190             return s;
191         debug(DBG_WARN, "bindtoaddr: bind failed");
192         close(s);
193     }
194     return -1;
195 }         
196
197 /* returns the client with matching address, or NULL */
198 /* if client argument is not NULL, we only check that one client */
199 struct client *find_client(char type, struct sockaddr *addr, struct client *client) {
200     struct sockaddr_in6 *sa6 = NULL;
201     struct in_addr *a4 = NULL;
202     struct client *c;
203     int i;
204     struct addrinfo *res;
205
206     if (addr->sa_family == AF_INET6) {
207         sa6 = (struct sockaddr_in6 *)addr;
208         if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
209             a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12];
210     } else
211         a4 = &((struct sockaddr_in *)addr)->sin_addr;
212
213     c = (client ? client : clients);
214     for (i = 0; i < client_count; i++) {
215         if (c->peer.type == type)
216             for (res = c->peer.addrinfo; res; res = res->ai_next)
217                 if ((a4 && res->ai_family == AF_INET &&
218                      !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) ||
219                     (sa6 && res->ai_family == AF_INET6 &&
220                      !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16)))
221                     return c;
222         if (client)
223             break;
224         c++;
225     }
226     return NULL;
227 }
228
229 /* returns the server with matching address, or NULL */
230 /* if server argument is not NULL, we only check that one server */
231 struct server *find_server(char type, struct sockaddr *addr, struct server *server) {
232     struct sockaddr_in6 *sa6 = NULL;
233     struct in_addr *a4 = NULL;
234     struct server *s;
235     int i;
236     struct addrinfo *res;
237
238     if (addr->sa_family == AF_INET6) {
239         sa6 = (struct sockaddr_in6 *)addr;
240         if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
241             a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12];
242     } else
243         a4 = &((struct sockaddr_in *)addr)->sin_addr;
244
245     s = (server ? server : servers);
246     for (i = 0; i < server_count; i++) {
247         if (s->peer.type == type)
248             for (res = s->peer.addrinfo; res; res = res->ai_next)
249                 if ((a4 && res->ai_family == AF_INET &&
250                      !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) ||
251                     (sa6 && res->ai_family == AF_INET6 &&
252                      !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16)))
253                     return s;
254         if (server)
255             break;
256         s++;
257     }
258     return NULL;
259 }
260
261 /* exactly one of client and server must be non-NULL */
262 /* if *peer == NULL we return who we received from, else require it to be from peer */
263 /* return from in sa if not NULL */
264 unsigned char *radudpget(int s, struct client **client, struct server **server, struct sockaddr_storage *sa) {
265     int cnt, len;
266     void *f;
267     unsigned char buf[65536], *rad;
268     struct sockaddr_storage from;
269     socklen_t fromlen = sizeof(from);
270
271     for (;;) {
272         cnt = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen);
273         if (cnt == -1) {
274             debug(DBG_WARN, "radudpget: recv failed");
275             continue;
276         }
277         debug(DBG_DBG, "radudpget: got %d bytes from %s", cnt, addr2string((struct sockaddr *)&from, fromlen));
278
279         if (cnt < 20) {
280             debug(DBG_WARN, "radudpget: packet too small");
281             continue;
282         }
283     
284         len = RADLEN(buf);
285         if (len < 20) {
286             debug(DBG_WARN, "radudpget: length too small");
287             continue;
288         }
289
290         if (cnt < len) {
291             debug(DBG_WARN, "radudpget: packet smaller than length field in radius header");
292             continue;
293         }
294         if (cnt > len)
295             debug(DBG_DBG, "radudpget: packet was padded with %d bytes", cnt - len);
296
297         f = (client
298              ? (void *)find_client('U', (struct sockaddr *)&from, *client)
299              : (void *)find_server('U', (struct sockaddr *)&from, *server));
300         if (!f) {
301             debug(DBG_WARN, "radudpget: got packet from wrong or unknown UDP peer, ignoring");
302             continue;
303         }
304
305         rad = malloc(len);
306         if (rad)
307             break;
308         debug(DBG_ERR, "radudpget: malloc failed");
309     }
310     memcpy(rad, buf, len);
311     if (client)
312         *client = (struct client *)f; /* only need this if *client == NULL, but if not NULL *client == f here */
313     else
314         *server = (struct server *)f; /* only need this if *server == NULL, but if not NULL *server == f here */
315     if (sa)
316         *sa = from;
317     return rad;
318 }
319
320 int subjectaltnameaddr(X509 *cert, int family, struct in6_addr *addr) {
321     int loc, i, l, n, r = 0;
322     char *v;
323     X509_EXTENSION *ex;
324     STACK_OF(GENERAL_NAME) *alt;
325     GENERAL_NAME *gn;
326     
327     debug(DBG_DBG, "subjectaltnameaddr");
328     
329     loc = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
330     if (loc < 0)
331         return r;
332     
333     ex = X509_get_ext(cert, loc);
334     alt = X509V3_EXT_d2i(ex);
335     if (!alt)
336         return r;
337     
338     n = sk_GENERAL_NAME_num(alt);
339     for (i = 0; i < n; i++) {
340         gn = sk_GENERAL_NAME_value(alt, i);
341         if (gn->type != GEN_IPADD)
342             continue;
343         r = -1;
344         v = (char *)ASN1_STRING_data(gn->d.ia5);
345         l = ASN1_STRING_length(gn->d.ia5);
346         if (((family == AF_INET && l == sizeof(struct in_addr)) || (family == AF_INET6 && l == sizeof(struct in6_addr)))
347             && !memcmp(v, &addr, l)) {
348             r = 1;
349             break;
350         }
351     }
352     GENERAL_NAMES_free(alt);
353     return r;
354 }
355
356 int subjectaltnameregexp(X509 *cert, int type, char *exact,  regex_t *regex) {
357     int loc, i, l, n, r = 0;
358     char *s, *v;
359     X509_EXTENSION *ex;
360     STACK_OF(GENERAL_NAME) *alt;
361     GENERAL_NAME *gn;
362     
363     debug(DBG_DBG, "subjectaltnameregexp");
364     
365     loc = X509_get_ext_by_NID(cert, NID_subject_alt_name, -1);
366     if (loc < 0)
367         return r;
368     
369     ex = X509_get_ext(cert, loc);
370     alt = X509V3_EXT_d2i(ex);
371     if (!alt)
372         return r;
373     
374     n = sk_GENERAL_NAME_num(alt);
375     for (i = 0; i < n; i++) {
376         gn = sk_GENERAL_NAME_value(alt, i);
377         if (gn->type != type)
378             continue;
379         r = -1;
380         v = (char *)ASN1_STRING_data(gn->d.ia5);
381         l = ASN1_STRING_length(gn->d.ia5);
382         if (l <= 0)
383             continue;
384 #ifdef DEBUG
385         printfchars(NULL, gn->type == GEN_DNS ? "dns" : "uri", NULL, v, l);
386 #endif  
387         if (exact) {
388             if (memcmp(v, exact, l))
389                 continue;
390         } else {
391             s = stringcopy((char *)v, l);
392             if (!s) {
393                 debug(DBG_ERR, "malloc failed");
394                 continue;
395             }
396             if (regexec(regex, s, 0, NULL, 0)) {
397                 free(s);
398                 continue;
399             }
400             free(s);
401         }
402         r = 1;
403         break;
404     }
405     GENERAL_NAMES_free(alt);
406     return r;
407 }
408
409 int tlsverifycert(struct peer *peer) {
410     int l, loc, r;
411     X509 *cert;
412     X509_NAME *nm;
413     X509_NAME_ENTRY *e;
414     ASN1_STRING *s;
415     char *v;
416     uint8_t type = 0; /* 0 for DNS, AF_INET for IPv4, AF_INET6 for IPv6 */
417     unsigned long error;
418     struct in6_addr addr;
419     
420     if (SSL_get_verify_result(peer->ssl) != X509_V_OK) {
421         debug(DBG_ERR, "tlsverifycert: basic validation failed");
422         while ((error = ERR_get_error()))
423             debug(DBG_ERR, "tlsverifycert: TLS: %s", ERR_error_string(error, NULL));
424         return 0;
425     }
426
427     cert = SSL_get_peer_certificate(peer->ssl);
428     if (!cert) {
429         debug(DBG_ERR, "tlsverifycert: failed to obtain certificate");
430         return 0;
431     }
432
433     if (inet_pton(AF_INET, peer->host, &addr))
434         type = AF_INET;
435     else if (inet_pton(AF_INET6, peer->host, &addr))
436         type = AF_INET6;
437
438     r = type ? subjectaltnameaddr(cert, type, &addr) : subjectaltnameregexp(cert, GEN_DNS, peer->host, NULL);
439     if (r) {
440         if (r < 0) {
441             X509_free(cert);
442             debug(DBG_DBG, "tlsverifycert: No subjectaltname matching %s %s", type ? "address" : "host", peer->host);
443             return 0;
444         }
445         debug(DBG_DBG, "tlsverifycert: Found subjectaltname matching %s %s", type ? "address" : "host", peer->host);
446     } else {
447         nm = X509_get_subject_name(cert);
448         loc = -1;
449         for (;;) {
450             loc = X509_NAME_get_index_by_NID(nm, NID_commonName, loc);
451             if (loc == -1)
452                 break;
453             e = X509_NAME_get_entry(nm, loc);
454             s = X509_NAME_ENTRY_get_data(e);
455             v = (char *) ASN1_STRING_data(s);
456             l = ASN1_STRING_length(s);
457             if (l < 0)
458                 continue;
459 #ifdef DEBUG
460             printfchars(NULL, "cn", NULL, v, l);
461 #endif  
462             if (l == strlen(peer->host) && !strncasecmp(peer->host, v, l)) {
463                 r = 1;
464                 debug(DBG_DBG, "tlsverifycert: Found cn matching host %s, All OK", peer->host);
465                 break;
466             }
467         }
468         if (!r) {
469             X509_free(cert);
470             debug(DBG_ERR, "tlsverifycert: cn not matching host %s", peer->host);
471             return 0;
472         }
473     }
474     if (peer->certuriregex) {
475         r = subjectaltnameregexp(cert, GEN_URI, NULL, peer->certuriregex);
476         if (r < 1) {
477             debug(DBG_DBG, "tlsverifycert: subjectaltname URI not matching regex");
478             X509_free(cert);
479             return 0;
480         }
481         debug(DBG_DBG, "tlsverifycert: subjectaltname URI matching regex");
482     }
483     X509_free(cert);
484     return 1;
485 }
486
487 void tlsconnect(struct server *server, struct timeval *when, char *text) {
488     struct timeval now;
489     time_t elapsed;
490
491     debug(DBG_DBG, "tlsconnect called from %s", text);
492     pthread_mutex_lock(&server->lock);
493     if (when && memcmp(&server->lastconnecttry, when, sizeof(struct timeval))) {
494         /* already reconnected, nothing to do */
495         debug(DBG_DBG, "tlsconnect(%s): seems already reconnected", text);
496         pthread_mutex_unlock(&server->lock);
497         return;
498     }
499
500     debug(DBG_DBG, "tlsconnect %s", text);
501
502     for (;;) {
503         gettimeofday(&now, NULL);
504         elapsed = now.tv_sec - server->lastconnecttry.tv_sec;
505         if (server->connectionok) {
506             server->connectionok = 0;
507             sleep(10);
508         } else if (elapsed < 5)
509             sleep(10);
510         else if (elapsed < 300) {
511             debug(DBG_INFO, "tlsconnect: sleeping %lds", elapsed);
512             sleep(elapsed);
513         } else if (elapsed < 100000) {
514             debug(DBG_INFO, "tlsconnect: sleeping %ds", 600);
515             sleep(600);
516         } else
517             server->lastconnecttry.tv_sec = now.tv_sec;  /* no sleep at startup */
518         debug(DBG_WARN, "tlsconnect: trying to open TLS connection to %s port %s", server->peer.host, server->peer.port);
519         if (server->sock >= 0)
520             close(server->sock);
521         if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0) {
522             debug(DBG_ERR, "tlsconnect: connecttoserver failed");
523             continue;
524         }
525         
526         SSL_free(server->peer.ssl);
527         server->peer.ssl = SSL_new(server->peer.ssl_ctx);
528         SSL_set_fd(server->peer.ssl, server->sock);
529         if (SSL_connect(server->peer.ssl) > 0 && tlsverifycert(&server->peer))
530             break;
531     }
532     debug(DBG_WARN, "tlsconnect: TLS connection to %s port %s up", server->peer.host, server->peer.port);
533     gettimeofday(&server->lastconnecttry, NULL);
534     pthread_mutex_unlock(&server->lock);
535 }
536
537 unsigned char *radtlsget(SSL *ssl) {
538     int cnt, total, len;
539     unsigned char buf[4], *rad;
540
541     for (;;) {
542         for (total = 0; total < 4; total += cnt) {
543             cnt = SSL_read(ssl, buf + total, 4 - total);
544             if (cnt <= 0) {
545                 debug(DBG_ERR, "radtlsget: connection lost");
546                 if (SSL_get_error(ssl, cnt) == SSL_ERROR_ZERO_RETURN) {
547                     /* remote end sent close_notify, send one back */
548                     SSL_shutdown(ssl);
549                 }
550                 return NULL;
551             }
552         }
553
554         len = RADLEN(buf);
555         rad = malloc(len);
556         if (!rad) {
557             debug(DBG_ERR, "radtlsget: malloc failed");
558             continue;
559         }
560         memcpy(rad, buf, 4);
561
562         for (; total < len; total += cnt) {
563             cnt = SSL_read(ssl, rad + total, len - total);
564             if (cnt <= 0) {
565                 debug(DBG_ERR, "radtlsget: connection lost");
566                 if (SSL_get_error(ssl, cnt) == SSL_ERROR_ZERO_RETURN) {
567                     /* remote end sent close_notify, send one back */
568                     SSL_shutdown(ssl);
569                 }
570                 free(rad);
571                 return NULL;
572             }
573         }
574     
575         if (total >= 20)
576             break;
577         
578         free(rad);
579         debug(DBG_WARN, "radtlsget: packet smaller than minimum radius size");
580     }
581     
582     debug(DBG_DBG, "radtlsget: got %d bytes", total);
583     return rad;
584 }
585
586 int clientradput(struct server *server, unsigned char *rad) {
587     int cnt;
588     size_t len;
589     unsigned long error;
590     struct timeval lastconnecttry;
591     
592     len = RADLEN(rad);
593     if (server->peer.type == 'U') {
594         if (send(server->sock, rad, len, 0) >= 0) {
595             debug(DBG_DBG, "clienradput: sent UDP of length %d to %s port %s", len, server->peer.host, server->peer.port);
596             return 1;
597         }
598         debug(DBG_WARN, "clientradput: send failed");
599         return 0;
600     }
601
602     lastconnecttry = server->lastconnecttry;
603     while ((cnt = SSL_write(server->peer.ssl, rad, len)) <= 0) {
604         while ((error = ERR_get_error()))
605             debug(DBG_ERR, "clientradput: TLS: %s", ERR_error_string(error, NULL));
606         tlsconnect(server, &lastconnecttry, "clientradput");
607         lastconnecttry = server->lastconnecttry;
608     }
609
610     server->connectionok = 1;
611     debug(DBG_DBG, "clientradput: Sent %d bytes, Radius packet of length %d to TLS peer %s",
612            cnt, len, server->peer.host);
613     return 1;
614 }
615
616 int radsign(unsigned char *rad, unsigned char *sec) {
617     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
618     static unsigned char first = 1;
619     static EVP_MD_CTX mdctx;
620     unsigned int md_len;
621     int result;
622     
623     pthread_mutex_lock(&lock);
624     if (first) {
625         EVP_MD_CTX_init(&mdctx);
626         first = 0;
627     }
628
629     result = (EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) &&
630         EVP_DigestUpdate(&mdctx, rad, RADLEN(rad)) &&
631         EVP_DigestUpdate(&mdctx, sec, strlen((char *)sec)) &&
632         EVP_DigestFinal_ex(&mdctx, rad + 4, &md_len) &&
633         md_len == 16);
634     pthread_mutex_unlock(&lock);
635     return result;
636 }
637
638 int validauth(unsigned char *rad, unsigned char *reqauth, unsigned char *sec) {
639     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
640     static unsigned char first = 1;
641     static EVP_MD_CTX mdctx;
642     unsigned char hash[EVP_MAX_MD_SIZE];
643     unsigned int len;
644     int result;
645     
646     pthread_mutex_lock(&lock);
647     if (first) {
648         EVP_MD_CTX_init(&mdctx);
649         first = 0;
650     }
651
652     len = RADLEN(rad);
653     
654     result = (EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) &&
655               EVP_DigestUpdate(&mdctx, rad, 4) &&
656               EVP_DigestUpdate(&mdctx, reqauth, 16) &&
657               (len <= 20 || EVP_DigestUpdate(&mdctx, rad + 20, len - 20)) &&
658               EVP_DigestUpdate(&mdctx, sec, strlen((char *)sec)) &&
659               EVP_DigestFinal_ex(&mdctx, hash, &len) &&
660               len == 16 &&
661               !memcmp(hash, rad + 4, 16));
662     pthread_mutex_unlock(&lock);
663     return result;
664 }
665               
666 int checkmessageauth(unsigned char *rad, uint8_t *authattr, char *secret) {
667     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
668     static unsigned char first = 1;
669     static HMAC_CTX hmacctx;
670     unsigned int md_len;
671     uint8_t auth[16], hash[EVP_MAX_MD_SIZE];
672     
673     pthread_mutex_lock(&lock);
674     if (first) {
675         HMAC_CTX_init(&hmacctx);
676         first = 0;
677     }
678
679     memcpy(auth, authattr, 16);
680     memset(authattr, 0, 16);
681     md_len = 0;
682     HMAC_Init_ex(&hmacctx, secret, strlen(secret), EVP_md5(), NULL);
683     HMAC_Update(&hmacctx, rad, RADLEN(rad));
684     HMAC_Final(&hmacctx, hash, &md_len);
685     memcpy(authattr, auth, 16);
686     if (md_len != 16) {
687         debug(DBG_WARN, "message auth computation failed");
688         pthread_mutex_unlock(&lock);
689         return 0;
690     }
691
692     if (memcmp(auth, hash, 16)) {
693         debug(DBG_WARN, "message authenticator, wrong value");
694         pthread_mutex_unlock(&lock);
695         return 0;
696     }   
697         
698     pthread_mutex_unlock(&lock);
699     return 1;
700 }
701
702 int createmessageauth(unsigned char *rad, unsigned char *authattrval, char *secret) {
703     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
704     static unsigned char first = 1;
705     static HMAC_CTX hmacctx;
706     unsigned int md_len;
707
708     if (!authattrval)
709         return 1;
710     
711     pthread_mutex_lock(&lock);
712     if (first) {
713         HMAC_CTX_init(&hmacctx);
714         first = 0;
715     }
716
717     memset(authattrval, 0, 16);
718     md_len = 0;
719     HMAC_Init_ex(&hmacctx, secret, strlen(secret), EVP_md5(), NULL);
720     HMAC_Update(&hmacctx, rad, RADLEN(rad));
721     HMAC_Final(&hmacctx, authattrval, &md_len);
722     if (md_len != 16) {
723         debug(DBG_WARN, "message auth computation failed");
724         pthread_mutex_unlock(&lock);
725         return 0;
726     }
727
728     pthread_mutex_unlock(&lock);
729     return 1;
730 }
731
732 unsigned char *attrget(unsigned char *attrs, int length, uint8_t type) {
733     while (length > 1) {
734         if (ATTRTYPE(attrs) == type)
735             return attrs;
736         length -= ATTRLEN(attrs);
737         attrs += ATTRLEN(attrs);
738     }
739     return NULL;
740 }
741
742 void sendrq(struct server *to, struct request *rq) {
743     int i;
744     uint8_t *attr;
745
746     pthread_mutex_lock(&to->newrq_mutex);
747     /* might simplify if only try nextid, might be ok */
748     for (i = to->nextid; i < MAX_REQUESTS; i++)
749         if (!to->requests[i].buf)
750             break;
751     if (i == MAX_REQUESTS) {
752         for (i = 0; i < to->nextid; i++)
753             if (!to->requests[i].buf)
754                 break;
755         if (i == to->nextid) {
756             debug(DBG_WARN, "No room in queue, dropping request");
757             free(rq->buf);
758             pthread_mutex_unlock(&to->newrq_mutex);
759             return;
760         }
761     }
762     
763     rq->buf[1] = (char)i;
764
765     attr = attrget(rq->buf + 20, RADLEN(rq->buf) - 20, RAD_Attr_Message_Authenticator);
766     if (attr && !createmessageauth(rq->buf, ATTRVAL(attr), to->peer.secret)) {
767         free(rq->buf);
768         pthread_mutex_unlock(&to->newrq_mutex);
769         return;
770     }
771
772     debug(DBG_DBG, "sendrq: inserting packet with id %d in queue for %s", i, to->peer.host);
773     to->requests[i] = *rq;
774     to->nextid = i + 1;
775
776     if (!to->newrq) {
777         to->newrq = 1;
778         debug(DBG_DBG, "signalling client writer");
779         pthread_cond_signal(&to->newrq_cond);
780     }
781     pthread_mutex_unlock(&to->newrq_mutex);
782 }
783
784 void sendreply(struct client *to, unsigned char *buf, struct sockaddr_storage *tosa) {
785     struct replyq *replyq = to->replyq;
786     
787     if (!radsign(buf, (unsigned char *)to->peer.secret)) {
788         free(buf);
789         debug(DBG_WARN, "sendreply: failed to sign message");
790         return;
791     }
792         
793     pthread_mutex_lock(&replyq->count_mutex);
794     if (replyq->count == replyq->size) {
795         debug(DBG_WARN, "No room in queue, dropping request");
796         pthread_mutex_unlock(&replyq->count_mutex);
797         free(buf);
798         return;
799     }
800
801     replyq->replies[replyq->count].buf = buf;
802     if (tosa)
803         replyq->replies[replyq->count].tosa = *tosa;
804     replyq->count++;
805
806     if (replyq->count == 1) {
807         debug(DBG_DBG, "signalling server writer");
808         pthread_cond_signal(&replyq->count_cond);
809     }
810     pthread_mutex_unlock(&replyq->count_mutex);
811 }
812
813 int pwdencrypt(uint8_t *in, uint8_t len, char *shared, uint8_t sharedlen, uint8_t *auth) {
814     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
815     static unsigned char first = 1;
816     static EVP_MD_CTX mdctx;
817     unsigned char hash[EVP_MAX_MD_SIZE], *input;
818     unsigned int md_len;
819     uint8_t i, offset = 0, out[128];
820     
821     pthread_mutex_lock(&lock);
822     if (first) {
823         EVP_MD_CTX_init(&mdctx);
824         first = 0;
825     }
826
827     input = auth;
828     for (;;) {
829         if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
830             !EVP_DigestUpdate(&mdctx, (uint8_t *)shared, sharedlen) ||
831             !EVP_DigestUpdate(&mdctx, input, 16) ||
832             !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
833             md_len != 16) {
834             pthread_mutex_unlock(&lock);
835             return 0;
836         }
837         for (i = 0; i < 16; i++)
838             out[offset + i] = hash[i] ^ in[offset + i];
839         input = out + offset - 16;
840         offset += 16;
841         if (offset == len)
842             break;
843     }
844     memcpy(in, out, len);
845     pthread_mutex_unlock(&lock);
846     return 1;
847 }
848
849 int pwddecrypt(uint8_t *in, uint8_t len, char *shared, uint8_t sharedlen, uint8_t *auth) {
850     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
851     static unsigned char first = 1;
852     static EVP_MD_CTX mdctx;
853     unsigned char hash[EVP_MAX_MD_SIZE], *input;
854     unsigned int md_len;
855     uint8_t i, offset = 0, out[128];
856     
857     pthread_mutex_lock(&lock);
858     if (first) {
859         EVP_MD_CTX_init(&mdctx);
860         first = 0;
861     }
862
863     input = auth;
864     for (;;) {
865         if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
866             !EVP_DigestUpdate(&mdctx, (uint8_t *)shared, sharedlen) ||
867             !EVP_DigestUpdate(&mdctx, input, 16) ||
868             !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
869             md_len != 16) {
870             pthread_mutex_unlock(&lock);
871             return 0;
872         }
873         for (i = 0; i < 16; i++)
874             out[offset + i] = hash[i] ^ in[offset + i];
875         input = in + offset;
876         offset += 16;
877         if (offset == len)
878             break;
879     }
880     memcpy(in, out, len);
881     pthread_mutex_unlock(&lock);
882     return 1;
883 }
884
885 int msmppencrypt(uint8_t *text, uint8_t len, uint8_t *shared, uint8_t sharedlen, uint8_t *auth, uint8_t *salt) {
886     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
887     static unsigned char first = 1;
888     static EVP_MD_CTX mdctx;
889     unsigned char hash[EVP_MAX_MD_SIZE];
890     unsigned int md_len;
891     uint8_t i, offset;
892     
893     pthread_mutex_lock(&lock);
894     if (first) {
895         EVP_MD_CTX_init(&mdctx);
896         first = 0;
897     }
898
899 #if 0
900     printfchars(NULL, "msppencrypt auth in", "%02x ", auth, 16);
901     printfchars(NULL, "msppencrypt salt in", "%02x ", salt, 2);
902     printfchars(NULL, "msppencrypt in", "%02x ", text, len);
903 #endif
904     
905     if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
906         !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
907         !EVP_DigestUpdate(&mdctx, auth, 16) ||
908         !EVP_DigestUpdate(&mdctx, salt, 2) ||
909         !EVP_DigestFinal_ex(&mdctx, hash, &md_len)) {
910         pthread_mutex_unlock(&lock);
911         return 0;
912     }
913
914 #if 0
915     printfchars(NULL, "msppencrypt hash", "%02x ", hash, 16);
916 #endif
917     
918     for (i = 0; i < 16; i++)
919         text[i] ^= hash[i];
920     
921     for (offset = 16; offset < len; offset += 16) {
922 #if 0   
923         printf("text + offset - 16 c(%d): ", offset / 16);
924         printfchars(NULL, NULL, "%02x ", text + offset - 16, 16);
925 #endif
926         if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
927             !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
928             !EVP_DigestUpdate(&mdctx, text + offset - 16, 16) ||
929             !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
930             md_len != 16) {
931             pthread_mutex_unlock(&lock);
932             return 0;
933         }
934 #if 0
935         printfchars(NULL, "msppencrypt hash", "%02x ", hash, 16);
936 #endif    
937         
938         for (i = 0; i < 16; i++)
939             text[offset + i] ^= hash[i];
940     }
941     
942 #if 0
943     printfchars(NULL, "msppencrypt out", "%02x ", text, len);
944 #endif
945
946     pthread_mutex_unlock(&lock);
947     return 1;
948 }
949
950 int msmppdecrypt(uint8_t *text, uint8_t len, uint8_t *shared, uint8_t sharedlen, uint8_t *auth, uint8_t *salt) {
951     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
952     static unsigned char first = 1;
953     static EVP_MD_CTX mdctx;
954     unsigned char hash[EVP_MAX_MD_SIZE];
955     unsigned int md_len;
956     uint8_t i, offset;
957     char plain[255];
958     
959     pthread_mutex_lock(&lock);
960     if (first) {
961         EVP_MD_CTX_init(&mdctx);
962         first = 0;
963     }
964
965 #if 0
966     printfchars(NULL, "msppdecrypt auth in", "%02x ", auth, 16);
967     printfchars(NULL, "msppdecrypt salt in", "%02x ", salt, 2);
968     printfchars(NULL, "msppdecrypt in", "%02x ", text, len);
969 #endif
970     
971     if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
972         !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
973         !EVP_DigestUpdate(&mdctx, auth, 16) ||
974         !EVP_DigestUpdate(&mdctx, salt, 2) ||
975         !EVP_DigestFinal_ex(&mdctx, hash, &md_len)) {
976         pthread_mutex_unlock(&lock);
977         return 0;
978     }
979
980 #if 0
981     printfchars(NULL, "msppdecrypt hash", "%02x ", hash, 16);
982 #endif
983     
984     for (i = 0; i < 16; i++)
985         plain[i] = text[i] ^ hash[i];
986     
987     for (offset = 16; offset < len; offset += 16) {
988 #if 0   
989         printf("text + offset - 16 c(%d): ", offset / 16);
990         printfchars(NULL, "msppdecrypt hash", "%02x ", hash, 16);
991 #endif
992         if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
993             !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
994             !EVP_DigestUpdate(&mdctx, text + offset - 16, 16) ||
995             !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
996             md_len != 16) {
997             pthread_mutex_unlock(&lock);
998             return 0;
999         }
1000 #if 0
1001         printfchars(NULL, "msppdecrypt hash", "%02x ", hash, 16);
1002 #endif    
1003
1004         for (i = 0; i < 16; i++)
1005             plain[offset + i] = text[offset + i] ^ hash[i];
1006     }
1007
1008     memcpy(text, plain, len);
1009 #if 0
1010     printfchars(NULL, "msppdecrypt out", "%02x ", text, len);
1011 #endif
1012
1013     pthread_mutex_unlock(&lock);
1014     return 1;
1015 }
1016
1017 struct realm *id2realm(char *id, uint8_t len) {
1018     int i;
1019     for (i = 0; i < realm_count; i++)
1020         if (!regexec(&realms[i].regex, id, 0, NULL, 0)) {
1021             debug(DBG_DBG, "found matching realm: %s", realms[i].name);
1022             return realms + i;
1023         }
1024     return NULL;
1025 }
1026
1027 int rqinqueue(struct server *to, struct client *from, uint8_t id) {
1028     int i;
1029     
1030     pthread_mutex_lock(&to->newrq_mutex);
1031     for (i = 0; i < MAX_REQUESTS; i++)
1032         if (to->requests[i].buf && !to->requests[i].received && to->requests[i].origid == id && to->requests[i].from == from)
1033             break;
1034     pthread_mutex_unlock(&to->newrq_mutex);
1035     
1036     return i < MAX_REQUESTS;
1037 }
1038
1039 int attrvalidate(unsigned char *attrs, int length) {
1040     while (length > 1) {
1041         if (ATTRLEN(attrs) < 2) {
1042             debug(DBG_WARN, "attrvalidate: invalid attribute length %d", ATTRLEN(attrs));
1043             return 0;
1044         }
1045         length -= ATTRLEN(attrs);
1046         if (length < 0) {
1047             debug(DBG_WARN, "attrvalidate: attribute length %d exceeds packet length", ATTRLEN(attrs));
1048             return 0;
1049         }
1050         attrs += ATTRLEN(attrs);
1051     }
1052     if (length)
1053         debug(DBG_WARN, "attrvalidate: malformed packet? remaining byte after last attribute");
1054     return 1;
1055 }
1056
1057 int pwdrecrypt(uint8_t *pwd, uint8_t len, char *oldsecret, char *newsecret, uint8_t *oldauth, uint8_t *newauth) {
1058     if (len < 16 || len > 128 || len % 16) {
1059         debug(DBG_WARN, "pwdrecrypt: invalid password length");
1060         return 0;
1061     }
1062         
1063     if (!pwddecrypt(pwd, len, oldsecret, strlen(oldsecret), oldauth)) {
1064         debug(DBG_WARN, "pwdrecrypt: cannot decrypt password");
1065         return 0;
1066     }
1067 #ifdef DEBUG
1068     printfchars(NULL, "pwdrecrypt: password", "%02x ", pwd, len);
1069 #endif  
1070     if (!pwdencrypt(pwd, len, newsecret, strlen(newsecret), newauth)) {
1071         debug(DBG_WARN, "pwdrecrypt: cannot encrypt password");
1072         return 0;
1073     }
1074     return 1;
1075 }
1076
1077 int msmpprecrypt(uint8_t *msmpp, uint8_t len, char *oldsecret, char *newsecret, unsigned char *oldauth, char *newauth) {
1078     if (len < 18)
1079         return 0;
1080     if (!msmppdecrypt(msmpp + 2, len - 2, (unsigned char *)oldsecret, strlen(oldsecret), oldauth, msmpp)) {
1081         debug(DBG_WARN, "msmpprecrypt: failed to decrypt msppe key");
1082         return 0;
1083     }
1084     if (!msmppencrypt(msmpp + 2, len - 2, (unsigned char *)newsecret, strlen(newsecret), (unsigned char *)newauth, msmpp)) {
1085         debug(DBG_WARN, "msmpprecrypt: failed to encrypt msppe key");
1086         return 0;
1087     }
1088     return 1;
1089 }
1090
1091 int msmppe(unsigned char *attrs, int length, uint8_t type, char *attrtxt, struct request *rq,
1092            char *oldsecret, char *newsecret) {
1093     unsigned char *attr;
1094     
1095     for (attr = attrs; (attr = attrget(attr, length - (attr - attrs), type)); attr += ATTRLEN(attr)) {
1096         debug(DBG_DBG, "msmppe: Got %s", attrtxt);
1097         if (!msmpprecrypt(ATTRVAL(attr), ATTRVALLEN(attr), oldsecret, newsecret, rq->buf + 4, rq->origauth))
1098             return 0;
1099     }
1100     return 1;
1101 }
1102
1103 void respondstatusserver(struct request *rq) {
1104     unsigned char *resp;
1105
1106     resp = malloc(20);
1107     if (!resp) {
1108         debug(DBG_ERR, "respondstatusserver: malloc failed");
1109         return;
1110     }
1111     memcpy(resp, rq->buf, 20);
1112     resp[0] = RAD_Access_Accept;
1113     resp[2] = 0;
1114     resp[3] = 20;
1115     debug(DBG_DBG, "respondstatusserver: responding to %s", rq->from->peer.host);
1116     sendreply(rq->from, resp, rq->from->peer.type == 'U' ? &rq->fromsa : NULL);
1117 }
1118
1119 void respondreject(struct request *rq, char *message) {
1120     unsigned char *resp;
1121     int len = 20;
1122
1123     if (message)
1124         len += 2 + strlen(message);
1125     
1126     resp = malloc(len);
1127     if (!resp) {
1128         debug(DBG_ERR, "respondreject: malloc failed");
1129         return;
1130     }
1131     memcpy(resp, rq->buf, 20);
1132     resp[0] = RAD_Access_Reject;
1133     *(uint16_t *)(resp + 2) = htons(len);
1134     if (message) {
1135         resp[20] = RAD_Attr_Reply_Message;
1136         resp[21] = len - 20;
1137         memcpy(resp + 22, message, len - 22);
1138     }
1139     sendreply(rq->from, resp, rq->from->peer.type == 'U' ? &rq->fromsa : NULL);
1140 }
1141
1142 void radsrv(struct request *rq) {
1143     uint8_t code, id, *auth, *attrs, *attr;
1144     uint16_t len;
1145     struct server *to = NULL;
1146     char username[256];
1147     unsigned char *buf, newauth[16];
1148     struct realm *realm = NULL;
1149     
1150     buf = rq->buf;
1151     code = *(uint8_t *)buf;
1152     id = *(uint8_t *)(buf + 1);
1153     len = RADLEN(buf);
1154     auth = (uint8_t *)(buf + 4);
1155
1156     debug(DBG_DBG, "radsrv: code %d, id %d, length %d", code, id, len);
1157     
1158     if (code != RAD_Access_Request && code != RAD_Status_Server) {
1159         debug(DBG_INFO, "radsrv: server currently accepts only access-requests and status-server, ignoring");
1160         free(buf);
1161         return;
1162     }
1163
1164     len -= 20;
1165     attrs = buf + 20;
1166
1167     if (!attrvalidate(attrs, len)) {
1168         debug(DBG_WARN, "radsrv: attribute validation failed, ignoring packet");
1169         free(buf);
1170         return;
1171     }
1172
1173     if (code == RAD_Access_Request) {
1174         attr = attrget(attrs, len, RAD_Attr_User_Name);
1175         if (!attr) {
1176             debug(DBG_WARN, "radsrv: ignoring request, no username attribute");
1177             free(buf);
1178             return;
1179         }
1180         memcpy(username, ATTRVAL(attr), ATTRVALLEN(attr));
1181         username[ATTRVALLEN(attr)] = '\0';
1182         debug(DBG_DBG, "Access Request with username: %s", username);
1183
1184         realm = id2realm(username, strlen(username));
1185         if (!realm) {
1186             debug(DBG_INFO, "radsrv: ignoring request, don't know where to send it");
1187             free(buf);
1188             return;
1189         }
1190         to = servers + realm->serverno;
1191
1192         if (to && rqinqueue(to, rq->from, id)) {
1193             debug(DBG_INFO, "radsrv: already got request from host %s with id %d, ignoring", rq->from->peer.host, id);
1194             free(buf);
1195             return;
1196         }
1197     }
1198     
1199     attr = attrget(attrs, len, RAD_Attr_Message_Authenticator);
1200     if (attr && (ATTRVALLEN(attr) != 16 || !checkmessageauth(buf, ATTRVAL(attr), rq->from->peer.secret))) {
1201         debug(DBG_WARN, "radsrv: message authentication failed");
1202         free(buf);
1203         return;
1204     }
1205     
1206     if (code == RAD_Status_Server) {
1207         respondstatusserver(rq);
1208         free(buf);
1209         return;
1210     }
1211
1212     if (!to) {
1213         debug(DBG_INFO, "radsrv: sending reject to %s for %s", rq->from->peer.host, username);
1214         respondreject(rq, realm->message);
1215         free(buf);
1216         return;
1217     }
1218     
1219     if (!RAND_bytes(newauth, 16)) {
1220         debug(DBG_WARN, "radsrv: failed to generate random auth");
1221         free(buf);
1222         return;
1223     }
1224
1225 #ifdef DEBUG    
1226     printfchars(NULL, "auth", "%02x ", auth, 16);
1227 #endif
1228
1229     attr = attrget(attrs, len, RAD_Attr_User_Password);
1230     if (attr) {
1231         debug(DBG_DBG, "radsrv: found userpwdattr with value length %d", ATTRVALLEN(attr));
1232         if (!pwdrecrypt(ATTRVAL(attr), ATTRVALLEN(attr), rq->from->peer.secret, to->peer.secret, auth, newauth)) {
1233             free(buf);
1234             return;
1235         }
1236     }
1237     
1238     attr = attrget(attrs, len, RAD_Attr_Tunnel_Password);
1239     if (attr) {
1240         debug(DBG_DBG, "radsrv: found tunnelpwdattr with value length %d", ATTRVALLEN(attr));
1241         if (!pwdrecrypt(ATTRVAL(attr), ATTRVALLEN(attr), rq->from->peer.secret, to->peer.secret, auth, newauth)) {
1242             free(buf);
1243             return;
1244         }
1245     }
1246
1247     rq->origid = id;
1248     memcpy(rq->origauth, auth, 16);
1249     memcpy(auth, newauth, 16);
1250     sendrq(to, rq);
1251 }
1252
1253 void *clientrd(void *arg) {
1254     struct server *server = (struct server *)arg;
1255     struct client *from;
1256     int i, len, sublen;
1257     unsigned char *buf, *messageauth, *subattrs, *attrs, *attr;
1258     struct sockaddr_storage fromsa;
1259     struct timeval lastconnecttry;
1260     char tmp[256];
1261     
1262     for (;;) {
1263         lastconnecttry = server->lastconnecttry;
1264         buf = (server->peer.type == 'U' ? radudpget(server->sock, NULL, &server, NULL) : radtlsget(server->peer.ssl));
1265         if (!buf && server->peer.type == 'T') {
1266             tlsconnect(server, &lastconnecttry, "clientrd");
1267             continue;
1268         }
1269     
1270         server->connectionok = 1;
1271
1272         i = buf[1]; /* i is the id */
1273
1274         switch (*buf) {
1275         case RAD_Access_Accept:
1276             debug(DBG_DBG, "got Access Accept with id %d", i);
1277             break;
1278         case RAD_Access_Reject:
1279             debug(DBG_DBG, "got Access Reject with id %d", i);
1280             break;
1281         case RAD_Access_Challenge:
1282             debug(DBG_DBG, "got Access Challenge with id %d", i);
1283             break;
1284         default:
1285             free(buf);
1286             debug(DBG_INFO, "clientrd: discarding, only accept access accept, access reject and access challenge messages");
1287             continue;
1288         }
1289         
1290         pthread_mutex_lock(&server->newrq_mutex);
1291         if (!server->requests[i].buf || !server->requests[i].tries) {
1292             pthread_mutex_unlock(&server->newrq_mutex);
1293             free(buf);
1294             debug(DBG_INFO, "clientrd: no matching request sent with this id, ignoring");
1295             continue;
1296         }
1297
1298         if (server->requests[i].received) {
1299             pthread_mutex_unlock(&server->newrq_mutex);
1300             free(buf);
1301             debug(DBG_INFO, "clientrd: already received, ignoring");
1302             continue;
1303         }
1304         
1305         if (!validauth(buf, server->requests[i].buf + 4, (unsigned char *)server->peer.secret)) {
1306             pthread_mutex_unlock(&server->newrq_mutex);
1307             free(buf);
1308             debug(DBG_WARN, "clientrd: invalid auth, ignoring");
1309             continue;
1310         }
1311         
1312         from = server->requests[i].from;
1313         len = RADLEN(buf) - 20;
1314         attrs = buf + 20;
1315
1316         if (!attrvalidate(attrs, len)) {
1317             pthread_mutex_unlock(&server->newrq_mutex);
1318             free(buf);
1319             debug(DBG_WARN, "clientrd: attribute validation failed, ignoring packet");
1320             continue;
1321         }
1322         
1323         /* Message Authenticator */
1324         messageauth = attrget(attrs, len, RAD_Attr_Message_Authenticator);
1325         if (messageauth) {
1326             if (ATTRVALLEN(messageauth) != 16) {
1327                 pthread_mutex_unlock(&server->newrq_mutex);
1328                 free(buf);
1329                 debug(DBG_WARN, "clientrd: illegal message auth attribute length, ignoring packet");
1330                 continue;
1331             }
1332             memcpy(tmp, buf + 4, 16);
1333             memcpy(buf + 4, server->requests[i].buf + 4, 16);
1334             if (!checkmessageauth(buf, ATTRVAL(messageauth), server->peer.secret)) {
1335                 pthread_mutex_unlock(&server->newrq_mutex);
1336                 free(buf);
1337                 debug(DBG_WARN, "clientrd: message authentication failed");
1338                 continue;
1339             }
1340             memcpy(buf + 4, tmp, 16);
1341             debug(DBG_DBG, "clientrd: message auth ok");
1342         }
1343         
1344         if (*server->requests[i].buf == RAD_Status_Server) {
1345             server->requests[i].received = 1;
1346             pthread_mutex_unlock(&server->newrq_mutex);
1347             free(buf);
1348             debug(DBG_INFO, "clientrd: got status server response from %s", server->peer.host);
1349             continue;
1350         }
1351
1352         /* MS MPPE */
1353         for (attr = attrs; (attr = attrget(attr, len - (attr - attrs), RAD_Attr_Vendor_Specific)); attr += ATTRLEN(attr)) {
1354             if (ATTRVALLEN(attr) <= 4)
1355                 break;
1356             
1357             if (attr[2] != 0 || attr[3] != 0 || attr[4] != 1 || attr[5] != 55)  /* 311 == MS */
1358                 continue;
1359             
1360             sublen = ATTRVALLEN(attr) - 4;
1361             subattrs = ATTRVAL(attr) + 4;  
1362             if (!attrvalidate(subattrs, sublen) ||
1363                 !msmppe(subattrs, sublen, RAD_VS_ATTR_MS_MPPE_Send_Key, "MS MPPE Send Key",
1364                         server->requests + i, server->peer.secret, from->peer.secret) ||
1365                 !msmppe(subattrs, sublen, RAD_VS_ATTR_MS_MPPE_Recv_Key, "MS MPPE Recv Key",
1366                         server->requests + i, server->peer.secret, from->peer.secret))
1367                 break;
1368         }
1369         if (attr) {
1370             pthread_mutex_unlock(&server->newrq_mutex);
1371             free(buf);
1372             debug(DBG_WARN, "clientrd: MS attribute handling failed, ignoring packet");
1373             continue;
1374         }
1375         
1376         if (*buf == RAD_Access_Accept || *buf == RAD_Access_Reject) {
1377             attr = attrget(server->requests[i].buf + 20, RADLEN(server->requests[i].buf) - 20, RAD_Attr_User_Name);
1378             /* we know the attribute exists */
1379             memcpy(tmp, ATTRVAL(attr), ATTRVALLEN(attr));
1380             tmp[ATTRVALLEN(attr)] = '\0';
1381             switch (*buf) {
1382             case RAD_Access_Accept:
1383                 debug(DBG_INFO, "Access Accept for %s from %s", tmp, server->peer.host);
1384                 break;
1385             case RAD_Access_Reject:
1386                 debug(DBG_INFO, "Access Reject for %s from %s", tmp, server->peer.host);
1387                 break;
1388             }
1389         }
1390         
1391         /* once we set received = 1, requests[i] may be reused */
1392         buf[1] = (char)server->requests[i].origid;
1393         memcpy(buf + 4, server->requests[i].origauth, 16);
1394 #ifdef DEBUG    
1395         printfchars(NULL, "origauth/buf+4", "%02x ", buf + 4, 16);
1396 #endif
1397         
1398         if (messageauth) {
1399             if (!createmessageauth(buf, ATTRVAL(messageauth), from->peer.secret)) {
1400                 pthread_mutex_unlock(&server->newrq_mutex);
1401                 free(buf);
1402                 continue;
1403             }
1404             debug(DBG_DBG, "clientrd: computed messageauthattr");
1405         }
1406
1407         if (from->peer.type == 'U')
1408             fromsa = server->requests[i].fromsa;
1409         server->requests[i].received = 1;
1410         pthread_mutex_unlock(&server->newrq_mutex);
1411
1412         debug(DBG_DBG, "clientrd: giving packet back to where it came from");
1413         sendreply(from, buf, from->peer.type == 'U' ? &fromsa : NULL);
1414     }
1415 }
1416
1417 void *clientwr(void *arg) {
1418     struct server *server = (struct server *)arg;
1419     struct request *rq;
1420     pthread_t clientrdth;
1421     int i;
1422     uint8_t rnd;
1423     struct timeval now, lastsend;
1424     struct timespec timeout;
1425     struct request statsrvrq;
1426     unsigned char statsrvbuf[38];
1427
1428     memset(&timeout, 0, sizeof(struct timespec));
1429     
1430     if (server->statusserver) {
1431         memset(&statsrvrq, 0, sizeof(struct request));
1432         memset(statsrvbuf, 0, sizeof(statsrvbuf));
1433         statsrvbuf[0] = RAD_Status_Server;
1434         statsrvbuf[3] = 38;
1435         statsrvbuf[20] = RAD_Attr_Message_Authenticator;
1436         statsrvbuf[21] = 18;
1437         gettimeofday(&lastsend, NULL);
1438     }
1439     
1440     if (server->peer.type == 'U') {
1441         if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0)
1442             debugx(1, DBG_ERR, "clientwr: connecttoserver failed");
1443     } else
1444         tlsconnect(server, NULL, "new client");
1445     
1446     if (pthread_create(&clientrdth, NULL, clientrd, (void *)server))
1447         debugx(1, DBG_ERR, "clientwr: pthread_create failed");
1448
1449     for (;;) {
1450         pthread_mutex_lock(&server->newrq_mutex);
1451         if (!server->newrq) {
1452             gettimeofday(&now, NULL);
1453             if (server->statusserver) {
1454                 /* random 0-7 seconds */
1455                 RAND_bytes(&rnd, 1);
1456                 rnd /= 32;
1457                 if (!timeout.tv_sec || timeout.tv_sec - now.tv_sec > lastsend.tv_sec + STATUS_SERVER_PERIOD + rnd)
1458                     timeout.tv_sec = lastsend.tv_sec + STATUS_SERVER_PERIOD + rnd;
1459             }   
1460             if (timeout.tv_sec) {
1461                 debug(DBG_DBG, "clientwr: waiting up to %ld secs for new request", timeout.tv_sec - now.tv_sec);
1462                 pthread_cond_timedwait(&server->newrq_cond, &server->newrq_mutex, &timeout);
1463                 timeout.tv_sec = 0;
1464             } else {
1465                 debug(DBG_DBG, "clientwr: waiting for new request");
1466                 pthread_cond_wait(&server->newrq_cond, &server->newrq_mutex);
1467             }
1468         }
1469         if (server->newrq) {
1470             debug(DBG_DBG, "clientwr: got new request");
1471             server->newrq = 0;
1472         } else
1473             debug(DBG_DBG, "clientwr: request timer expired, processing request queue");
1474         pthread_mutex_unlock(&server->newrq_mutex);
1475
1476         for (i = 0; i < MAX_REQUESTS; i++) {
1477             pthread_mutex_lock(&server->newrq_mutex);
1478             while (i < MAX_REQUESTS && !server->requests[i].buf)
1479                 i++;
1480             if (i == MAX_REQUESTS) {
1481                 pthread_mutex_unlock(&server->newrq_mutex);
1482                 break;
1483             }
1484             rq = server->requests + i;
1485
1486             if (rq->received) {
1487                 debug(DBG_DBG, "clientwr: packet %d in queue is marked as received", i);
1488                 if (rq->buf) {
1489                     debug(DBG_DBG, "clientwr: freeing received packet %d from queue", i);
1490                     free(rq->buf);
1491                     /* setting this to NULL means that it can be reused */
1492                     rq->buf = NULL;
1493                 }
1494                 pthread_mutex_unlock(&server->newrq_mutex);
1495                 continue;
1496             }
1497             
1498             gettimeofday(&now, NULL);
1499             if (now.tv_sec < rq->expiry.tv_sec) {
1500                 if (!timeout.tv_sec || rq->expiry.tv_sec < timeout.tv_sec)
1501                     timeout.tv_sec = rq->expiry.tv_sec;
1502                 pthread_mutex_unlock(&server->newrq_mutex);
1503                 continue;
1504             }
1505
1506             if (rq->tries == (*rq->buf == RAD_Status_Server || server->peer.type == 'T'
1507                               ? 1 : REQUEST_RETRIES)) {
1508                 debug(DBG_DBG, "clientwr: removing expired packet from queue");
1509                 if (*rq->buf == RAD_Status_Server)
1510                     debug(DBG_WARN, "clientwr: no status server response, %s dead?", server->peer.host);
1511                 free(rq->buf);
1512                 /* setting this to NULL means that it can be reused */
1513                 rq->buf = NULL;
1514                 pthread_mutex_unlock(&server->newrq_mutex);
1515                 continue;
1516             }
1517             pthread_mutex_unlock(&server->newrq_mutex);
1518
1519             rq->expiry.tv_sec = now.tv_sec +
1520                 (*rq->buf == RAD_Status_Server || server->peer.type == 'T'
1521                  ? REQUEST_EXPIRY : REQUEST_EXPIRY / REQUEST_RETRIES);
1522             if (!timeout.tv_sec || rq->expiry.tv_sec < timeout.tv_sec)
1523                 timeout.tv_sec = rq->expiry.tv_sec;
1524             rq->tries++;
1525             clientradput(server, server->requests[i].buf);
1526             gettimeofday(&lastsend, NULL);
1527         }
1528         if (server->statusserver) {
1529             gettimeofday(&now, NULL);
1530             if (now.tv_sec - lastsend.tv_sec >= STATUS_SERVER_PERIOD) {
1531                 if (!RAND_bytes(statsrvbuf + 4, 16)) {
1532                     debug(DBG_WARN, "clientwr: failed to generate random auth");
1533                     continue;
1534                 }
1535                 statsrvrq.buf = malloc(sizeof(statsrvbuf));
1536                 if (!statsrvrq.buf) {
1537                     debug(DBG_ERR, "clientwr: malloc failed");
1538                     continue;
1539                 }
1540                 memcpy(statsrvrq.buf, statsrvbuf, sizeof(statsrvbuf));
1541                 debug(DBG_DBG, "clientwr: sending status server to %s", server->peer.host);
1542                 lastsend.tv_sec = now.tv_sec;
1543                 sendrq(server, &statsrvrq);
1544             }
1545         }
1546     }
1547 }
1548
1549 void *udpserverwr(void *arg) {
1550     struct replyq *replyq = &udp_server_replyq;
1551     struct reply *reply = replyq->replies;
1552     
1553     pthread_mutex_lock(&replyq->count_mutex);
1554     for (;;) {
1555         while (!replyq->count) {
1556             debug(DBG_DBG, "udp server writer, waiting for signal");
1557             pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex);
1558             debug(DBG_DBG, "udp server writer, got signal");
1559         }
1560         pthread_mutex_unlock(&replyq->count_mutex);
1561         
1562         if (sendto(udp_server_sock, reply->buf, RADLEN(reply->buf), 0,
1563                    (struct sockaddr *)&reply->tosa, SOCKADDR_SIZE(reply->tosa)) < 0)
1564             debug(DBG_WARN, "sendudp: send failed");
1565         free(reply->buf);
1566         
1567         pthread_mutex_lock(&replyq->count_mutex);
1568         replyq->count--;
1569         memmove(replyq->replies, replyq->replies + 1,
1570                 replyq->count * sizeof(struct reply));
1571     }
1572 }
1573
1574 void *udpserverrd(void *arg) {
1575     struct request rq;
1576     pthread_t udpserverwrth;
1577
1578     if ((udp_server_sock = bindtoaddr(udp_server_listen->addrinfo)) < 0)
1579         debugx(1, DBG_ERR, "udpserverrd: socket/bind failed");
1580
1581     debug(DBG_WARN, "udpserverrd: listening for UDP on %s:%s",
1582           udp_server_listen->host ? udp_server_listen->host : "*", udp_server_listen->port);
1583
1584     if (pthread_create(&udpserverwrth, NULL, udpserverwr, NULL))
1585         debugx(1, DBG_ERR, "pthread_create failed");
1586     
1587     for (;;) {
1588         memset(&rq, 0, sizeof(struct request));
1589         rq.buf = radudpget(udp_server_sock, &rq.from, NULL, &rq.fromsa);
1590         radsrv(&rq);
1591     }
1592 }
1593
1594 void *tlsserverwr(void *arg) {
1595     int cnt;
1596     unsigned long error;
1597     struct client *client = (struct client *)arg;
1598     struct replyq *replyq;
1599     
1600     debug(DBG_DBG, "tlsserverwr starting for %s", client->peer.host);
1601     replyq = client->replyq;
1602     pthread_mutex_lock(&replyq->count_mutex);
1603     for (;;) {
1604         while (!replyq->count) {
1605             if (client->peer.ssl) {         
1606                 debug(DBG_DBG, "tls server writer, waiting for signal");
1607                 pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex);
1608                 debug(DBG_DBG, "tls server writer, got signal");
1609             }
1610             if (!client->peer.ssl) {
1611                 /* ssl might have changed while waiting */
1612                 pthread_mutex_unlock(&replyq->count_mutex);
1613                 debug(DBG_DBG, "tlsserverwr: exiting as requested");
1614                 pthread_exit(NULL);
1615             }
1616         }
1617         pthread_mutex_unlock(&replyq->count_mutex);
1618         cnt = SSL_write(client->peer.ssl, replyq->replies->buf, RADLEN(replyq->replies->buf));
1619         if (cnt > 0)
1620             debug(DBG_DBG, "tlsserverwr: Sent %d bytes, Radius packet of length %d",
1621                   cnt, RADLEN(replyq->replies->buf));
1622         else
1623             while ((error = ERR_get_error()))
1624                 debug(DBG_ERR, "tlsserverwr: SSL: %s", ERR_error_string(error, NULL));
1625         free(replyq->replies->buf);
1626
1627         pthread_mutex_lock(&replyq->count_mutex);
1628         replyq->count--;
1629         memmove(replyq->replies, replyq->replies + 1, replyq->count * sizeof(struct reply));
1630     }
1631 }
1632
1633 void *tlsserverrd(void *arg) {
1634     struct request rq;
1635     unsigned long error;
1636     int s;
1637     struct client *client = (struct client *)arg;
1638     pthread_t tlsserverwrth;
1639     SSL *ssl;
1640     
1641     debug(DBG_DBG, "tlsserverrd starting for %s", client->peer.host);
1642     ssl = client->peer.ssl;
1643
1644     if (SSL_accept(ssl) <= 0) {
1645         while ((error = ERR_get_error()))
1646             debug(DBG_ERR, "tlsserverrd: SSL: %s", ERR_error_string(error, NULL));
1647         debug(DBG_ERR, "SSL_accept failed");
1648         goto errexit;
1649     }
1650     if (tlsverifycert(&client->peer)) {
1651         if (pthread_create(&tlsserverwrth, NULL, tlsserverwr, (void *)client)) {
1652             debug(DBG_ERR, "tlsserverrd: pthread_create failed");
1653             goto errexit;
1654         }
1655         for (;;) {
1656             memset(&rq, 0, sizeof(struct request));
1657             rq.buf = radtlsget(client->peer.ssl);
1658             if (!rq.buf)
1659                 break;
1660             debug(DBG_DBG, "tlsserverrd: got Radius message from %s", client->peer.host);
1661             rq.from = client;
1662             radsrv(&rq);
1663         }
1664         debug(DBG_ERR, "tlsserverrd: connection lost");
1665         /* stop writer by setting peer.ssl to NULL and give signal in case waiting for data */
1666         client->peer.ssl = NULL;
1667         pthread_mutex_lock(&client->replyq->count_mutex);
1668         pthread_cond_signal(&client->replyq->count_cond);
1669         pthread_mutex_unlock(&client->replyq->count_mutex);
1670         debug(DBG_DBG, "tlsserverrd: waiting for writer to end");
1671         pthread_join(tlsserverwrth, NULL);
1672     }
1673     
1674  errexit:
1675     s = SSL_get_fd(ssl);
1676     SSL_free(ssl);
1677     shutdown(s, SHUT_RDWR);
1678     close(s);
1679     debug(DBG_DBG, "tlsserverrd thread for %s exiting", client->peer.host);
1680     client->peer.ssl = NULL;
1681     pthread_exit(NULL);
1682 }
1683
1684 int tlslistener() {
1685     pthread_t tlsserverth;
1686     int s, snew;
1687     struct sockaddr_storage from;
1688     size_t fromlen = sizeof(from);
1689     struct client *client;
1690
1691     if ((s = bindtoaddr(tcp_server_listen->addrinfo)) < 0)
1692         debugx(1, DBG_ERR, "tlslistener: socket/bind failed");
1693     
1694     listen(s, 0);
1695     debug(DBG_WARN, "listening for incoming TCP on %s:%s",
1696           tcp_server_listen->host ? tcp_server_listen->host : "*", tcp_server_listen->port);
1697
1698     for (;;) {
1699         snew = accept(s, (struct sockaddr *)&from, &fromlen);
1700         if (snew < 0) {
1701             debug(DBG_WARN, "accept failed");
1702             continue;
1703         }
1704         debug(DBG_WARN, "incoming TLS connection from %s", addr2string((struct sockaddr *)&from, fromlen));
1705
1706         client = find_client('T', (struct sockaddr *)&from, NULL);
1707         if (!client) {
1708             debug(DBG_WARN, "ignoring request, not a known TLS client");
1709             shutdown(snew, SHUT_RDWR);
1710             close(snew);
1711             continue;
1712         }
1713
1714         if (client->peer.ssl) {
1715             debug(DBG_WARN, "Ignoring incoming TLS connection, already have one from this client");
1716             shutdown(snew, SHUT_RDWR);
1717             close(snew);
1718             continue;
1719         }
1720         client->peer.ssl = SSL_new(client->peer.ssl_ctx);
1721         SSL_set_fd(client->peer.ssl, snew);
1722         if (pthread_create(&tlsserverth, NULL, tlsserverrd, (void *)client)) {
1723             debug(DBG_ERR, "tlslistener: pthread_create failed");
1724             SSL_free(client->peer.ssl);
1725             shutdown(snew, SHUT_RDWR);
1726             close(snew);
1727             client->peer.ssl = NULL;
1728             continue;
1729         }
1730         pthread_detach(tlsserverth);
1731     }
1732     return 0;
1733 }
1734
1735 void tlsadd(char *value, char *cacertfile, char *cacertpath, char *certfile, char *certkeyfile, char *certkeypwd) {
1736     struct tls *new;
1737     SSL_CTX *ctx;
1738     int i;
1739     unsigned long error;
1740     
1741     if (!certfile || !certkeyfile)
1742         debugx(1, DBG_ERR, "TLSCertificateFile and TLSCertificateKeyFile must be specified in TLS context %s", value);
1743
1744     if (!cacertfile && !cacertpath)
1745         debugx(1, DBG_ERR, "CA Certificate file or path need to be specified in TLS context %s", value);
1746
1747     if (!ssl_locks) {
1748         ssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
1749         ssl_lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
1750         for (i = 0; i < CRYPTO_num_locks(); i++) {
1751             ssl_lock_count[i] = 0;
1752             pthread_mutex_init(&ssl_locks[i], NULL);
1753         }
1754         CRYPTO_set_id_callback(ssl_thread_id);
1755         CRYPTO_set_locking_callback(ssl_locking_callback);
1756
1757         SSL_load_error_strings();
1758         SSL_library_init();
1759
1760         while (!RAND_status()) {
1761             time_t t = time(NULL);
1762             pid_t pid = getpid();
1763             RAND_seed((unsigned char *)&t, sizeof(time_t));
1764             RAND_seed((unsigned char *)&pid, sizeof(pid));
1765         }
1766     }
1767     ctx = SSL_CTX_new(TLSv1_method());
1768     if (certkeypwd) {
1769         SSL_CTX_set_default_passwd_cb_userdata(ctx, certkeypwd);
1770         SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
1771     }
1772     if (!SSL_CTX_use_certificate_chain_file(ctx, certfile) ||
1773         !SSL_CTX_use_PrivateKey_file(ctx, certkeyfile, SSL_FILETYPE_PEM) ||
1774         !SSL_CTX_check_private_key(ctx) ||
1775         !SSL_CTX_load_verify_locations(ctx, cacertfile, cacertpath)) {
1776         while ((error = ERR_get_error()))
1777             debug(DBG_ERR, "SSL: %s", ERR_error_string(error, NULL));
1778         debugx(1, DBG_ERR, "Error initialising SSL/TLS in TLS context %s", value);
1779     }
1780     
1781     SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
1782     SSL_CTX_set_verify_depth(ctx, MAX_CERT_DEPTH + 1);
1783     
1784     tls_count++;
1785     tlsconfs = realloc(tlsconfs, tls_count * sizeof(struct tls));
1786     if (!tlsconfs)
1787         debugx(1, DBG_ERR, "malloc failed");
1788     new = tlsconfs + tls_count - 1;
1789     memset(new, 0, sizeof(struct tls));
1790     new->name = stringcopy(value, 0);
1791     if (!new->name)
1792         debugx(1, DBG_ERR, "malloc failed");
1793     new->ctx = ctx;
1794     new->count = 0;
1795     debug(DBG_DBG, "tlsadd: added TLS context %s", value);
1796 }
1797
1798 void tlsfree() {
1799     int i;
1800     for (i = 0; i < tls_count; i++) {
1801         free(tlsconfs[i].name);
1802         if (!tlsconfs[i].count)
1803             SSL_CTX_free(tlsconfs[i].ctx);
1804     }
1805     tls_count = 0;
1806     free(tlsconfs);
1807     tlsconfs = NULL;
1808 }
1809
1810 SSL_CTX *tlsgetctx(char *alt1, char *alt2) {
1811     int i, c1 = -1, c2 = -1;
1812     for (i = 0; i < tls_count; i++) {
1813         if (!strcasecmp(tlsconfs[i].name, alt1)) {
1814             c1 = i;
1815             break;
1816         }
1817         if (c2 == -1 && alt2 && !strcasecmp(tlsconfs[i].name, alt2))
1818             c2 = i;
1819     }
1820
1821     i = (c1 == -1 ? c2 : c1);
1822     if (i == -1)
1823         return NULL;
1824     tlsconfs[i].count++;
1825     return tlsconfs[i].ctx;
1826 }
1827
1828 void addrealm(char *value, char *server, char *message) {
1829     int i, n;
1830     struct realm *realm;
1831     char *s, *regex = NULL;
1832
1833     if (server) {
1834         for (i = 0; i < server_count; i++)
1835             if (!strcasecmp(server, servers[i].peer.host))
1836                 break;
1837         if (i == server_count)
1838             debugx(1, DBG_ERR, "addrealm failed, no server %s", server);
1839     }
1840     
1841     if (*value == '/') {
1842         /* regexp, remove optional trailing / if present */
1843         if (value[strlen(value) - 1] == '/')
1844             value[strlen(value) - 1] = '\0';
1845     } else {
1846         /* not a regexp, let us make it one */
1847         if (*value == '*' && !value[1])
1848             regex = stringcopy(".*", 0);
1849         else {
1850             for (n = 0, s = value; *s;)
1851                 if (*s++ == '.')
1852                     n++;
1853             regex = malloc(strlen(value) + n + 3);
1854             if (regex) {
1855                 regex[0] = '@';
1856                 for (n = 1, s = value; *s; s++) {
1857                     if (*s == '.')
1858                         regex[n++] = '\\';
1859                     regex[n++] = *s;
1860                 }
1861                 regex[n++] = '$';
1862                 regex[n] = '\0';
1863             }
1864         }
1865         if (!regex)
1866             debugx(1, DBG_ERR, "malloc failed");
1867         debug(DBG_DBG, "addrealm: constructed regexp %s from %s", regex, value);
1868     }
1869
1870     realm_count++;
1871     realms = realloc(realms, realm_count * sizeof(struct realm));
1872     if (!realms)
1873         debugx(1, DBG_ERR, "malloc failed");
1874     realm = realms + realm_count - 1;
1875     memset(realm, 0, sizeof(struct realm));
1876     realm->name = stringcopy(value, 0);
1877     if (!realm->name)
1878         debugx(1, DBG_ERR, "malloc failed");
1879     if (message && strlen(message) > 253)
1880         debugx(1, DBG_ERR, "ReplyMessage can be at most 253 bytes");
1881     realm->message = message;
1882     if (server)
1883         realm->serverno = i;
1884     if (regcomp(&realm->regex, regex ? regex : value + 1, REG_ICASE | REG_NOSUB))
1885         debugx(1, DBG_ERR, "addrealm: failed to compile regular expression %s", regex ? regex : value + 1);
1886     if (regex)
1887         free(regex);
1888     debug(DBG_DBG, "addrealm: added realm %s for server %s", value, server);
1889 }
1890
1891 char *parsehostport(char *s, struct peer *peer) {
1892     char *p, *field;
1893     int ipv6 = 0;
1894
1895     p = s;
1896     /* allow literal addresses and port, e.g. [2001:db8::1]:1812 */
1897     if (*p == '[') {
1898         p++;
1899         field = p;
1900         for (; *p && *p != ']' && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1901         if (*p != ']')
1902             debugx(1, DBG_ERR, "no ] matching initial [");
1903         ipv6 = 1;
1904     } else {
1905         field = p;
1906         for (; *p && *p != ':' && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1907     }
1908     if (field == p)
1909         debugx(1, DBG_ERR, "missing host/address");
1910
1911     peer->host = stringcopy(field, p - field);
1912     if (ipv6) {
1913         p++;
1914         if (*p && *p != ':' && *p != ' ' && *p != '\t' && *p != '\n')
1915             debugx(1, DBG_ERR, "unexpected character after ]");
1916     }
1917     if (*p == ':') {
1918             /* port number or service name is specified */;
1919             field = ++p;
1920             for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1921             if (field == p)
1922                 debugx(1, DBG_ERR, "syntax error, : but no following port");
1923             peer->port = stringcopy(field, p - field);
1924     } else
1925         peer->port = stringcopy(peer->type == 'U' ? DEFAULT_UDP_PORT : DEFAULT_TLS_PORT, 0);
1926     return p;
1927 }
1928
1929 FILE *openconfigfile(const char *filename) {
1930     FILE *f;
1931     char pathname[100], *base = NULL;
1932     
1933     f = fopen(filename, "r");
1934     if (f) {
1935         debug(DBG_DBG, "reading config file %s", filename);
1936         return f;
1937     }
1938
1939     if (strlen(filename) + 1 <= sizeof(pathname)) {
1940         /* basename() might modify the string */
1941         strcpy(pathname, filename);
1942         base = basename(pathname);
1943         f = fopen(base, "r");
1944     }
1945
1946     if (!f)
1947         debugx(1, DBG_ERR, "could not read config file %s nor %s\n%s", filename, base, strerror(errno));
1948     
1949     debug(DBG_DBG, "reading config file %s", base);
1950     return f;
1951 }
1952
1953 struct peer *server_create(char type) {
1954     struct peer *server;
1955     char *conf;
1956
1957     server = malloc(sizeof(struct peer));
1958     if (!server)
1959         debugx(1, DBG_ERR, "malloc failed");
1960     memset(server, 0, sizeof(struct peer));
1961     server->type = type;
1962     conf = (type == 'T' ? options.listentcp : options.listenudp);
1963     if (conf) {
1964         parsehostport(conf, server);
1965         if (!strcmp(server->host, "*")) {
1966             free(server->host);
1967             server->host = NULL;
1968         }
1969     } else
1970         server->port = stringcopy(type == 'T' ? DEFAULT_TLS_PORT : DEFAULT_UDP_PORT, 0);
1971     if (!resolvepeer(server, AI_PASSIVE))
1972         debugx(1, DBG_ERR, "failed to resolve host %s port %s, exiting", server->host, server->port);
1973     return server;
1974 }
1975
1976 /* returns NULL on error, where to continue parsing if token and ok. E.g. "" will return token with empty string */
1977 char *strtokenquote(char *s, char **token, char *del, char *quote, char *comment) {
1978     char *t = s, *q, *r;
1979
1980     if (!t || !token || !del)
1981         return NULL;
1982     while (*t && strchr(del, *t))
1983         t++;
1984     if (!*t || (comment && strchr(comment, *t))) {
1985         *token = NULL;
1986         return t + 1; /* needs to be non-NULL, but value doesn't matter */
1987     }
1988     if (quote && (q = strchr(quote, *t))) {
1989         t++;
1990         r = t;
1991         while (*t && *t != *q)
1992             t++;
1993         if (!*t || (t[1] && !strchr(del, t[1])))
1994             return NULL;
1995         *t = '\0';
1996         *token = r;
1997         return t + 1;
1998     }
1999     *token = t;
2000     t++;
2001     while (*t && !strchr(del, *t))
2002         t++;
2003     *t = '\0';
2004     return t + 1;
2005 }
2006
2007 /* Parses config with following syntax:
2008  * One of these:
2009  * option-name value
2010  * option-name = value
2011  * Or:
2012  * option-name value {
2013  *     option-name [=] value
2014  *     ...
2015  * }
2016  */
2017 void getgeneralconfig(FILE *f, char *block, ...) {
2018     va_list ap;
2019     char line[1024];
2020     /* initialise lots of stuff to avoid stupid compiler warnings */
2021     char *tokens[3], *s, *opt = NULL, *val = NULL, *word, *optval, **str = NULL;
2022     int type = 0, tcount, conftype = 0;
2023     void (*cbk)(FILE *, char *, char *, char *) = NULL;
2024         
2025     while (fgets(line, 1024, f)) {
2026         s = line;
2027         for (tcount = 0; tcount < 3; tcount++) {
2028             s = strtokenquote(s, &tokens[tcount], " \t\r\n", "\"'", tcount ? NULL : "#");
2029             if (!s)
2030                 debugx(1, DBG_ERR, "Syntax error in line starting with: %s", line);
2031             if (!tokens[tcount])
2032                 break;
2033         }
2034         if (!tcount || **tokens == '#')
2035             continue;
2036
2037         if (**tokens == '}') {
2038             if (block)
2039                 return;
2040             debugx(1, DBG_ERR, "configuration error, found } with no matching {");
2041         }
2042             
2043         switch (tcount) {
2044         case 2:
2045             opt = tokens[0];
2046             val = tokens[1];
2047             conftype = CONF_STR;
2048             break;
2049         case 3:
2050             if (tokens[1][0] == '=' && tokens[1][1] == '\0') {
2051                 opt = tokens[0];
2052                 val = tokens[2];
2053                 conftype = CONF_STR;
2054                 break;
2055             }
2056             if (tokens[2][0] == '{' && tokens[2][1] == '\0') {
2057                 opt = tokens[0];
2058                 val = tokens[1];
2059                 conftype = CONF_CBK;
2060                 break;
2061             }
2062             /* fall through */
2063         default:
2064             if (block)
2065                 debugx(1, DBG_ERR, "configuration error in block %s, line starting with %s", block, tokens[0]);
2066             debugx(1, DBG_ERR, "configuration error, syntax error in line starting with %s", tokens[0]);
2067         }
2068
2069         if (!*val)
2070             debugx(1, DBG_ERR, "configuration error, option %s needs a non-empty value", opt);
2071         
2072         va_start(ap, block);
2073         while ((word = va_arg(ap, char *))) {
2074             type = va_arg(ap, int);
2075             switch (type) {
2076             case CONF_STR:
2077                 str = va_arg(ap, char **);
2078                 if (!str)
2079                     debugx(1, DBG_ERR, "getgeneralconfig: internal parameter error");
2080                 break;
2081             case CONF_CBK:
2082                 cbk = va_arg(ap, void (*)(FILE *, char *, char *, char *));
2083                 break;
2084             default:
2085                 debugx(1, DBG_ERR, "getgeneralconfig: internal parameter error");
2086             }
2087             if (!strcasecmp(opt, word))
2088                 break;
2089         }
2090         va_end(ap);
2091         
2092         if (!word) {
2093             if (block)
2094                 debugx(1, DBG_ERR, "configuration error in block %s, unknown option %s", block, opt);
2095             debugx(1, DBG_ERR, "configuration error, unknown option %s", opt);
2096         }
2097
2098         if (type != conftype) {
2099             if (block)
2100                 debugx(1, DBG_ERR, "configuration error in block %s, wrong syntax for option %s", block, opt);
2101             debugx(1, DBG_ERR, "configuration error, wrong syntax for option %s", opt);
2102         }
2103         
2104         switch (type) {
2105         case CONF_STR:
2106             if (block)
2107                 debug(DBG_DBG, "getgeneralconfig: block %s: %s = %s", block, opt, val);
2108             else 
2109                 debug(DBG_DBG, "getgeneralconfig: %s = %s", opt, val);
2110             if (*str)
2111                 debugx(1, DBG_ERR, "configuration error, option %s already set to %s", opt, *str);
2112             *str = stringcopy(val, 0);
2113             break;
2114         case CONF_CBK:
2115             optval = malloc(strlen(opt) + strlen(val) + 2);
2116             if (!optval)
2117                 debugx(1, DBG_ERR, "malloc failed");
2118             sprintf(optval, "%s %s", opt, val);
2119             cbk(f, optval, opt, val);
2120             free(optval);
2121             break;
2122         default:
2123             debugx(1, DBG_ERR, "getgeneralconfig: internal parameter error");
2124         }
2125     }
2126 }
2127
2128 int addmatchcertattr(struct peer *conf, char *matchcertattr) {
2129     char *v;
2130     
2131     v = matchcertattr + 20;
2132     if (strncasecmp(matchcertattr, "SubjectAltName:URI:/", 20) || !*v)
2133         return 0;
2134     /* regexp, remove optional trailing / if present */
2135     if (v[strlen(v) - 1] == '/')
2136         v[strlen(v) - 1] = '\0';
2137     if (!*v)
2138         return 0;
2139
2140     conf->certuriregex = malloc(sizeof(regex_t));
2141     if (!conf->certuriregex) {
2142         debug(DBG_ERR, "malloc failed");
2143         return 0;
2144     }
2145     if (regcomp(conf->certuriregex, v, REG_ICASE | REG_NOSUB)) {
2146         free(conf->certuriregex);
2147         conf->certuriregex = NULL;
2148         debug(DBG_ERR, "failed to compile regular expression %s", v);
2149         return 0;
2150     }
2151     return 1;
2152 }
2153
2154 void confclsrv_cb(FILE *f, char *block, char *opt, char *val) {
2155     char *type = NULL, *secret = NULL, *port = NULL, *tls = NULL, *matchcertattr = NULL, *statusserver = NULL;
2156     struct client *client = NULL;
2157     struct server *server = NULL;
2158     struct peer *peer;
2159     
2160     debug(DBG_DBG, "confclsrv_cb called for %s", block);
2161     
2162     if (!strcasecmp(opt, "client")) {
2163         getgeneralconfig(f, block,
2164                          "type", CONF_STR, &type,
2165                          "secret", CONF_STR, &secret,
2166                          "tls", CONF_STR, &tls,
2167                          "matchcertificateattribute", CONF_STR, &matchcertattr,
2168                          NULL
2169                          );
2170         client_count++;
2171         clients = realloc(clients, client_count * sizeof(struct client));
2172         if (!clients)
2173             debugx(1, DBG_ERR, "malloc failed");
2174         client = clients + client_count - 1;
2175         memset(client, 0, sizeof(struct client));
2176         peer = &client->peer;
2177     } else {
2178         getgeneralconfig(f, block,
2179                          "type", CONF_STR, &type,
2180                          "secret", CONF_STR, &secret,
2181                          "port", CONF_STR, &port,
2182                          "tls", CONF_STR, &tls,
2183                          "matchcertificateattribute", CONF_STR, &matchcertattr,
2184                          "StatusServer", CONF_STR, &statusserver,
2185                          NULL
2186                          );
2187         server_count++;
2188         servers = realloc(servers, server_count * sizeof(struct server));
2189         if (!servers)
2190             debugx(1, DBG_ERR, "malloc failed");
2191         server = servers + server_count - 1;
2192         memset(server, 0, sizeof(struct server));
2193         peer = &server->peer;
2194         peer->port = port;
2195         if (statusserver) {
2196             if (!strcasecmp(statusserver, "on"))
2197                 server->statusserver = 1;
2198             else if (strcasecmp(statusserver, "off"))
2199                 debugx(1, DBG_ERR, "error in block %s, StatusServer is %s, must be on or off", block, statusserver);
2200             free(statusserver);
2201         }
2202     }
2203     
2204     peer->host = stringcopy(val, 0);
2205     
2206     if (type && !strcasecmp(type, "udp")) {
2207         peer->type = 'U';
2208         if (client)
2209             client_udp_count++;
2210         else {
2211             server_udp_count++;
2212             if (!port)
2213                 peer->port = stringcopy(DEFAULT_UDP_PORT, 0);
2214         }
2215     } else if (type && !strcasecmp(type, "tls")) {
2216         if (client) {
2217             peer->ssl_ctx = tls ? tlsgetctx(tls, NULL) : tlsgetctx("defaultclient", "default");
2218             client_tls_count++;
2219         } else {
2220             peer->ssl_ctx = tls ? tlsgetctx(tls, NULL) : tlsgetctx("defaultserver", "default");
2221             server_tls_count++;
2222             if (!port)
2223                 peer->port = stringcopy(DEFAULT_TLS_PORT, 0);
2224         }
2225         if (!peer->ssl_ctx)
2226             debugx(1, DBG_ERR, "error in block %s, no tls context defined", block);
2227         if (matchcertattr && !addmatchcertattr(peer, matchcertattr))
2228             debugx(1, DBG_ERR, "error in block %s, invalid MatchCertificateAttributeValue", block);
2229         peer->type = 'T';
2230     } else
2231         debugx(1, DBG_ERR, "error in block %s, type must be set to UDP or TLS", block);
2232     free(type);
2233     if (tls)
2234         free(tls);
2235     if (matchcertattr)
2236         free(matchcertattr);
2237     
2238     if (!resolvepeer(peer, 0))
2239         debugx(1, DBG_ERR, "failed to resolve host %s port %s, exiting", peer->host, peer->port);
2240     
2241     if (!secret) {
2242         if (peer->type == 'U')
2243             debugx(1, DBG_ERR, "error in block %s, secret must be specified for UDP", block);
2244         peer->secret = stringcopy(DEFAULT_TLS_SECRET, 0);
2245     } else {
2246         peer->secret = secret;
2247     }
2248
2249     if (client) {
2250         if (peer->type == 'U')
2251             client->replyq = &udp_server_replyq;
2252         else {
2253             client->replyq = malloc(sizeof(struct replyq));
2254             if (!client->replyq)
2255                 debugx(1, DBG_ERR, "malloc failed");
2256             client->replyq->replies = calloc(MAX_REQUESTS, sizeof(struct reply));
2257             if (!client->replyq->replies)
2258                 debugx(1, DBG_ERR, "malloc failed");
2259             client->replyq->size = MAX_REQUESTS;
2260             client->replyq->count = 0;
2261             pthread_mutex_init(&client->replyq->count_mutex, NULL);
2262             pthread_cond_init(&client->replyq->count_cond, NULL);
2263         }
2264     } else {
2265         pthread_mutex_init(&server->lock, NULL);
2266         server->sock = -1;
2267         server->requests = calloc(MAX_REQUESTS, sizeof(struct request));
2268         if (!server->requests)
2269             debugx(1, DBG_ERR, "malloc failed");
2270         server->newrq = 0;
2271         pthread_mutex_init(&server->newrq_mutex, NULL);
2272         pthread_cond_init(&server->newrq_cond, NULL);
2273     }
2274 }
2275
2276 void confrealm_cb(FILE *f, char *block, char *opt, char *val) {
2277     char *server = NULL, *msg = NULL;
2278     
2279     debug(DBG_DBG, "confrealm_cb called for %s", block);
2280     
2281     getgeneralconfig(f, block,
2282                      "server", CONF_STR, &server,
2283                      "ReplyMessage", CONF_STR, &msg,
2284                      NULL
2285                      );
2286
2287     addrealm(val, server, msg);
2288     free(server);
2289 }
2290
2291 void conftls_cb(FILE *f, char *block, char *opt, char *val) {
2292     char *cacertfile = NULL, *cacertpath = NULL, *certfile = NULL, *certkeyfile = NULL, *certkeypwd = NULL;
2293     
2294     debug(DBG_DBG, "conftls_cb called for %s", block);
2295     
2296     getgeneralconfig(f, block,
2297                      "CACertificateFile", CONF_STR, &cacertfile,
2298                      "CACertificatePath", CONF_STR, &cacertpath,
2299                      "CertificateFile", CONF_STR, &certfile,
2300                      "CertificateKeyFile", CONF_STR, &certkeyfile,
2301                      "CertificateKeyPassword", CONF_STR, &certkeypwd,
2302                      NULL
2303                      );
2304     
2305     tlsadd(val, cacertfile, cacertpath, certfile, certkeyfile, certkeypwd);
2306     free(cacertfile);
2307     free(cacertpath);
2308     free(certfile);
2309     free(certkeyfile);
2310     free(certkeypwd);
2311 }
2312
2313 void getmainconfig(const char *configfile) {
2314     FILE *f;
2315     char *loglevel = NULL;
2316
2317     f = openconfigfile(configfile);
2318     memset(&options, 0, sizeof(options));
2319
2320     getgeneralconfig(f, NULL,
2321                      "ListenUDP", CONF_STR, &options.listenudp,
2322                      "ListenTCP", CONF_STR, &options.listentcp,
2323                      "LogLevel", CONF_STR, &loglevel,
2324                      "LogDestination", CONF_STR, &options.logdestination,
2325                      "Client", CONF_CBK, confclsrv_cb,
2326                      "Server", CONF_CBK, confclsrv_cb,
2327                      "Realm", CONF_CBK, confrealm_cb,
2328                      "TLS", CONF_CBK, conftls_cb,
2329                      NULL
2330                      );
2331     fclose(f);
2332     tlsfree();
2333     
2334     if (loglevel) {
2335         if (strlen(loglevel) != 1 || *loglevel < '1' || *loglevel > '4')
2336             debugx(1, DBG_ERR, "error in %s, value of option LogLevel is %s, must be 1, 2, 3 or 4", configfile, loglevel);
2337         options.loglevel = *loglevel - '0';
2338         free(loglevel);
2339     }
2340
2341     if (client_udp_count) {
2342         udp_server_replyq.replies = malloc(client_udp_count * MAX_REQUESTS * sizeof(struct reply));
2343         if (!udp_server_replyq.replies)
2344             debugx(1, DBG_ERR, "malloc failed");
2345         udp_server_replyq.size = client_udp_count * MAX_REQUESTS;
2346         udp_server_replyq.count = 0;
2347         pthread_mutex_init(&udp_server_replyq.count_mutex, NULL);
2348         pthread_cond_init(&udp_server_replyq.count_cond, NULL);
2349     }    
2350 }
2351
2352 void getargs(int argc, char **argv, uint8_t *foreground, uint8_t *loglevel, char **configfile) {
2353     int c;
2354
2355     while ((c = getopt(argc, argv, "c:d:fv")) != -1) {
2356         switch (c) {
2357         case 'c':
2358             *configfile = optarg;
2359             break;
2360         case 'd':
2361             if (strlen(optarg) != 1 || *optarg < '1' || *optarg > '4')
2362                 debugx(1, DBG_ERR, "Debug level must be 1, 2, 3 or 4, not %s", optarg);
2363             *loglevel = *optarg - '0';
2364             break;
2365         case 'f':
2366             *foreground = 1;
2367             break;
2368         case 'v':
2369                 debugx(0, DBG_ERR, "radsecproxy 1.0p2");
2370         default:
2371             goto usage;
2372         }
2373     }
2374     if (!(argc - optind))
2375         return;
2376
2377  usage:
2378     debug(DBG_ERR, "Usage:\n%s [ -c configfile ] [ -d debuglevel ] [ -f ] [ -v ]", argv[0]);
2379     exit(1);
2380 }
2381
2382 void *sighandler(void *arg) {
2383     sigset_t sigset;
2384     int sig;
2385
2386     for(;;) {
2387         sigemptyset(&sigset);
2388         sigaddset(&sigset, SIGPIPE);
2389         sigwait(&sigset, &sig);
2390         /* only get SIGPIPE right now, so could simplify below code */
2391         switch (sig) {
2392         case 0:
2393             /* completely ignoring this */
2394             break;
2395         case SIGPIPE:
2396             debug(DBG_WARN, "sighandler: got SIGPIPE, TLS write error?");
2397             break;
2398         default:
2399             debug(DBG_WARN, "sighandler: ignoring signal %d", sig);
2400         }
2401     }
2402 }
2403
2404 int main(int argc, char **argv) {
2405     pthread_t sigth, udpserverth;
2406     sigset_t sigset;
2407     int i;
2408     uint8_t foreground = 0, loglevel = 0;
2409     char *configfile = NULL;
2410     
2411     debug_init("radsecproxy");
2412     debug_set_level(DEBUG_LEVEL);
2413     getargs(argc, argv, &foreground, &loglevel, &configfile);
2414     if (loglevel)
2415         debug_set_level(loglevel);
2416     getmainconfig(configfile ? configfile : CONFIG_MAIN);
2417     if (loglevel)
2418         options.loglevel = loglevel;
2419     else if (options.loglevel)
2420         debug_set_level(options.loglevel);
2421     if (foreground)
2422         options.logdestination = NULL;
2423     else {
2424         if (!options.logdestination)
2425             options.logdestination = "x-syslog:///";
2426         debug_set_destination(options.logdestination);
2427     }
2428
2429     if (!server_count)
2430         debugx(1, DBG_ERR, "No servers configured, nothing to do, exiting");
2431     if (!client_count)
2432         debugx(1, DBG_ERR, "No clients configured, nothing to do, exiting");
2433     if (!realm_count)
2434         debugx(1, DBG_ERR, "No realms configured, nothing to do, exiting");
2435
2436     if (!foreground && (daemon(0, 0) < 0))
2437         debugx(1, DBG_ERR, "daemon() failed: %s", strerror(errno));
2438         
2439     debug(DBG_INFO, "radsecproxy 1.0p2 starting");
2440
2441     sigemptyset(&sigset);
2442     /* exit on all but SIGPIPE, ignore more? */
2443     sigaddset(&sigset, SIGPIPE);
2444     pthread_sigmask(SIG_BLOCK, &sigset, NULL);
2445     pthread_create(&sigth, NULL, sighandler, NULL);
2446
2447     if (client_udp_count) {
2448         udp_server_listen = server_create('U');
2449         if (pthread_create(&udpserverth, NULL, udpserverrd, NULL))
2450             debugx(1, DBG_ERR, "pthread_create failed");
2451     }
2452     
2453     for (i = 0; i < server_count; i++)
2454         if (pthread_create(&servers[i].clientth, NULL, clientwr, (void *)&servers[i]))
2455             debugx(1, DBG_ERR, "pthread_create failed");
2456
2457     if (client_tls_count) {
2458         tcp_server_listen = server_create('T');
2459         return tlslistener();
2460     }
2461     
2462     /* just hang around doing nothing, anything to do here? */
2463     for (;;)
2464         sleep(1000);
2465 }