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