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