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