fixed clientwr bug when receiving new request while not waiting for one
[libradsec.git] / radsecproxy.c
1 /*
2  * Copyright (C) 2006 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 /* TODO:
10  * accounting
11  * radius keep alives (server status)
12  * setsockopt(keepalive...), check if openssl has some keepalive feature
13 */
14
15 /* For UDP there is one server instance consisting of udpserverrd and udpserverth
16  *              rd is responsible for init and launching wr
17  * For TLS there is a server instance that launches tlsserverrd for each TLS peer
18  *          each tlsserverrd launches tlsserverwr
19  * For each UDP/TLS peer there is clientrd and clientwr, clientwr is responsible
20  *          for init and launching rd
21  *
22  * serverrd will receive a request, processes it and puts it in the requestq of
23  *          the appropriate clientwr
24  * clientwr monitors its requestq and sends requests
25  * clientrd looks for responses, processes them and puts them in the replyq of
26  *          the peer the request came from
27  * serverwr monitors its reply and sends replies
28  *
29  * In addition to the main thread, we have:
30  * If UDP peers are configured, there will be 2 + 2 * #peers UDP threads
31  * If TLS peers are configured, there will initially be 2 * #peers TLS threads
32  * For each TLS peer connecting to us there will be 2 more TLS threads
33  *       This is only for connected peers
34  * Example: With 3 UDP peer and 30 TLS peers, there will be a max of
35  *          1 + (2 + 2 * 3) + (2 * 30) + (2 * 30) = 129 threads
36 */
37
38 #include <sys/socket.h>
39 #include <netinet/in.h>
40 #include <netdb.h>
41 #include <string.h>
42 #include <unistd.h>
43 #include <sys/time.h>
44 #include <libgen.h>
45 #include <pthread.h>
46 #include <openssl/ssl.h>
47 #include <openssl/rand.h>
48 #include <openssl/err.h>
49 #include <openssl/md5.h>
50 #include <openssl/hmac.h>
51 #include "radsecproxy.h"
52
53 static struct options options;
54 static struct client *clients;
55 static struct server *servers;
56
57 static int client_udp_count = 0;
58 static int client_tls_count = 0;
59 static int client_count = 0;
60 static int server_udp_count = 0;
61 static int server_tls_count = 0;
62 static int server_count = 0;
63
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       printf("verify error: num=%d:%s:depth=%d:%s\n", 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           printf("issuer=%s\n", buf);
116           break;
117       case X509_V_ERR_CERT_NOT_YET_VALID:
118       case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
119           printf("Certificate not yet valid\n");
120           break;
121       case X509_V_ERR_CERT_HAS_EXPIRED:
122           printf("Certificate has expired\n");
123           break;
124       case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
125           printf("Certificate no longer valid (after notAfter)\n");
126           break;
127       }
128   }
129   /* printf("certificate verify returns %d\n", ok); */
130   return ok;
131 }
132
133 SSL_CTX *ssl_init() {
134     SSL_CTX *ctx;
135     int i;
136     unsigned long error;
137     
138     if (!options.tlscertificatefile || !options.tlscertificatekeyfile) {
139         printf("TLSCertificateFile and TLSCertificateKeyFile must be specified for TLS\n");
140         exit(1);
141     }
142     if (!options.tlscacertificatefile && !options.tlscacertificatepath) {
143         printf("CA Certificate file/path need to be configured\n");
144         exit(1);
145     }
146
147     ssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
148     ssl_lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
149     for (i = 0; i < CRYPTO_num_locks(); i++) {
150         ssl_lock_count[i] = 0;
151         pthread_mutex_init(&ssl_locks[i], NULL);
152     }
153     CRYPTO_set_id_callback(ssl_thread_id);
154     CRYPTO_set_locking_callback(ssl_locking_callback);
155
156     SSL_load_error_strings();
157     SSL_library_init();
158
159     while (!RAND_status()) {
160         time_t t = time(NULL);
161         pid_t pid = getpid();
162         RAND_seed((unsigned char *)&t, sizeof(time_t));
163         RAND_seed((unsigned char *)&pid, sizeof(pid));
164     }
165
166     ctx = SSL_CTX_new(TLSv1_method());
167     if (options.tlscertificatekeypassword) {
168         SSL_CTX_set_default_passwd_cb_userdata(ctx, options.tlscertificatekeypassword);
169         SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
170     }
171     if (SSL_CTX_use_certificate_chain_file(ctx, options.tlscertificatefile) &&
172         SSL_CTX_use_PrivateKey_file(ctx, options.tlscertificatekeyfile, SSL_FILETYPE_PEM) &&
173         SSL_CTX_check_private_key(ctx) &&
174         SSL_CTX_load_verify_locations(ctx, options.tlscacertificatefile, options.tlscacertificatepath)) {
175         SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
176         SSL_CTX_set_verify_depth(ctx, MAX_CERT_DEPTH + 1);
177         return ctx;
178     }
179
180     while ((error = ERR_get_error()))
181         err("SSL: %s", ERR_error_string(error, NULL));
182     exit(1);
183 }    
184
185 void printauth(char *s, unsigned char *t) {
186     int i;
187     printf("%s:", s);
188     for (i = 0; i < 16; i++)
189             printf("%02x ", t[i]);
190     printf("\n");
191 }
192
193 int resolvepeer(struct peer *peer) {
194     struct addrinfo hints, *addrinfo;
195     
196     memset(&hints, 0, sizeof(hints));
197     hints.ai_socktype = (peer->type == 'T' ? SOCK_STREAM : SOCK_DGRAM);
198     hints.ai_family = AF_UNSPEC;
199     if (getaddrinfo(peer->host, peer->port, &hints, &addrinfo)) {
200         err("resolvepeer: can't resolve %s port %s", peer->host, peer->port);
201         return 0;
202     }
203
204     if (peer->addrinfo)
205         freeaddrinfo(peer->addrinfo);
206     peer->addrinfo = addrinfo;
207     return 1;
208 }         
209
210 int connecttoserver(struct addrinfo *addrinfo) {
211     int s;
212     struct addrinfo *res;
213     
214     for (res = addrinfo; res; res = res->ai_next) {
215         s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
216         if (s < 0) {
217             err("connecttoserver: socket failed");
218             continue;
219         }
220         if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
221             break;
222         err("connecttoserver: connect failed");
223         close(s);
224         s = -1;
225     }
226     return s;
227 }         
228
229 /* returns the client with matching address, or NULL */
230 /* if client argument is not NULL, we only check that one client */
231 struct client *find_client(char type, struct sockaddr *addr, struct client *client) {
232     struct sockaddr_in6 *sa6;
233     struct in_addr *a4 = NULL;
234     struct client *c;
235     int i;
236     struct addrinfo *res;
237
238     if (addr->sa_family == AF_INET6) {
239         sa6 = (struct sockaddr_in6 *)addr;
240         if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
241             a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12];
242     } else
243         a4 = &((struct sockaddr_in *)addr)->sin_addr;
244
245     c = (client ? client : clients);
246     for (i = 0; i < client_count; i++) {
247         if (c->peer.type == type)
248             for (res = c->peer.addrinfo; res; res = res->ai_next)
249                 if ((a4 && res->ai_family == AF_INET &&
250                      !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) ||
251                     (res->ai_family == AF_INET6 &&
252                      !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16)))
253                     return c;
254         if (client)
255             break;
256         c++;
257     }
258     return NULL;
259 }
260
261 /* returns the server with matching address, or NULL */
262 /* if server argument is not NULL, we only check that one server */
263 struct server *find_server(char type, struct sockaddr *addr, struct server *server) {
264     struct sockaddr_in6 *sa6;
265     struct in_addr *a4 = NULL;
266     struct server *s;
267     int i;
268     struct addrinfo *res;
269
270     if (addr->sa_family == AF_INET6) {
271         sa6 = (struct sockaddr_in6 *)addr;
272         if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
273             a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12];
274     } else
275         a4 = &((struct sockaddr_in *)addr)->sin_addr;
276
277     s = (server ? server : servers);
278     for (i = 0; i < server_count; i++) {
279         if (s->peer.type == type)
280             for (res = s->peer.addrinfo; res; res = res->ai_next)
281                 if ((a4 && res->ai_family == AF_INET &&
282                      !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) ||
283                     (res->ai_family == AF_INET6 &&
284                      !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16)))
285                     return s;
286         if (server)
287             break;
288         s++;
289     }
290     return NULL;
291 }
292
293 /* exactly one of client and server must be non-NULL */
294 /* if *peer == NULL we return who we received from, else require it to be from peer */
295 /* return from in sa if not NULL */
296 unsigned char *radudpget(int s, struct client **client, struct server **server, struct sockaddr_storage *sa) {
297     int cnt, len;
298     void *f;
299     unsigned char buf[65536], *rad;
300     struct sockaddr_storage from;
301     socklen_t fromlen = sizeof(from);
302
303     for (;;) {
304         cnt = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen);
305         if (cnt == -1) {
306             err("radudpget: recv failed");
307             continue;
308         }
309         printf("radudpget: got %d bytes from %s\n", cnt, addr2string((struct sockaddr *)&from, fromlen));
310
311         if (cnt < 20) {
312             printf("radudpget: packet too small\n");
313             continue;
314         }
315     
316         len = RADLEN(buf);
317
318         if (cnt < len) {
319             printf("radudpget: packet smaller than length field in radius header\n");
320             continue;
321         }
322         if (cnt > len)
323             printf("radudpget: packet was padded with %d bytes\n", cnt - len);
324
325         f = (client
326              ? (void *)find_client('U', (struct sockaddr *)&from, *client)
327              : (void *)find_server('U', (struct sockaddr *)&from, *server));
328         if (!f) {
329             printf("radudpget: got packet from wrong or unknown UDP peer, ignoring\n");
330             continue;
331         }
332
333         rad = malloc(len);
334         if (rad)
335             break;
336         err("radudpget: malloc failed");
337     }
338     memcpy(rad, buf, len);
339     if (client)
340         *client = (struct client *)f; /* only need this if *client == NULL, but if not NULL *client == f here */
341     else
342         *server = (struct server *)f; /* only need this if *server == NULL, but if not NULL *server == f here */
343     if (sa)
344         *sa = from;
345     return rad;
346 }
347
348 int tlsverifycert(struct peer *peer) {
349     int i, l, loc;
350     X509 *cert;
351     X509_NAME *nm;
352     X509_NAME_ENTRY *e;
353     unsigned char *v;
354     unsigned long error;
355
356 #if 1
357     if (SSL_get_verify_result(peer->ssl) != X509_V_OK) {
358         printf("tlsverifycert: basic validation failed\n");
359         while ((error = ERR_get_error()))
360             err("clientwr: TLS: %s", ERR_error_string(error, NULL));
361         return 0;
362     }
363 #endif    
364     cert = SSL_get_peer_certificate(peer->ssl);
365     if (!cert) {
366         printf("tlsverifycert: failed to obtain certificate\n");
367         return 0;
368     }
369     nm = X509_get_subject_name(cert);
370     loc = -1;
371     for (;;) {
372         loc = X509_NAME_get_index_by_NID(nm, NID_commonName, loc);
373         if (loc == -1)
374             break;
375         e = X509_NAME_get_entry(nm, loc);
376         l = ASN1_STRING_to_UTF8(&v, X509_NAME_ENTRY_get_data(e));
377         if (l < 0)
378             continue;
379         printf("cn: ");
380         for (i = 0; i < l; i++)
381             printf("%c", v[i]);
382         printf("\n");
383         if (l == strlen(peer->host) && !strncasecmp(peer->host, (char *)v, l)) {
384             printf("tlsverifycert: Found cn matching host %s, All OK\n", peer->host);
385             return 1;
386         }
387         printf("tlsverifycert: cn not matching host %s\n", peer->host);
388     }
389     X509_free(cert);
390     return 0;
391 }
392
393 void tlsconnect(struct server *server, struct timeval *when, char *text) {
394     struct timeval now;
395     time_t elapsed;
396
397     printf("tlsconnect called from %s\n", text);
398     pthread_mutex_lock(&server->lock);
399     if (when && memcmp(&server->lastconnecttry, when, sizeof(struct timeval))) {
400         /* already reconnected, nothing to do */
401         printf("tlsconnect(%s): seems already reconnected\n", text);
402         pthread_mutex_unlock(&server->lock);
403         return;
404     }
405
406     printf("tlsconnect %s\n", text);
407
408     for (;;) {
409         gettimeofday(&now, NULL);
410         elapsed = now.tv_sec - server->lastconnecttry.tv_sec;
411         if (server->connectionok) {
412             server->connectionok = 0;
413             sleep(10);
414         } else if (elapsed < 5)
415             sleep(10);
416         else if (elapsed < 600) {
417             printf("tlsconnect: sleeping %lds\n", elapsed);
418             sleep(elapsed);
419         } else if (elapsed < 1000) {
420             printf("tlsconnect: sleeping %ds\n", 900);
421             sleep(900);
422         } else
423             server->lastconnecttry.tv_sec = now.tv_sec;  /* no sleep at startup */
424         printf("tlsconnect: trying to open TLS connection to %s port %s\n", server->peer.host, server->peer.port);
425         if (server->sock >= 0)
426             close(server->sock);
427         if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0)
428             continue;
429         SSL_free(server->peer.ssl);
430         server->peer.ssl = SSL_new(ssl_ctx);
431         SSL_set_fd(server->peer.ssl, server->sock);
432         if (SSL_connect(server->peer.ssl) > 0 && tlsverifycert(&server->peer))
433             break;
434     }
435     printf("tlsconnect: TLS connection to %s port %s up\n", server->peer.host, server->peer.port);
436     gettimeofday(&server->lastconnecttry, NULL);
437     pthread_mutex_unlock(&server->lock);
438 }
439
440 unsigned char *radtlsget(SSL *ssl) {
441     int cnt, total, len;
442     unsigned char buf[4], *rad;
443
444     for (;;) {
445         for (total = 0; total < 4; total += cnt) {
446             cnt = SSL_read(ssl, buf + total, 4 - total);
447             if (cnt <= 0) {
448                 printf("radtlsget: connection lost\n");
449                 if (SSL_get_error(ssl, cnt) == SSL_ERROR_ZERO_RETURN) {
450                     /* remote end sent close_notify, send one back */
451                     SSL_shutdown(ssl);
452                 }
453                 return NULL;
454             }
455         }
456
457         len = RADLEN(buf);
458         rad = malloc(len);
459         if (!rad) {
460             err("radtlsget: malloc failed");
461             continue;
462         }
463         memcpy(rad, buf, 4);
464
465         for (; total < len; total += cnt) {
466             cnt = SSL_read(ssl, rad + total, len - total);
467             if (cnt <= 0) {
468                 printf("radtlsget: connection lost\n");
469                 if (SSL_get_error(ssl, cnt) == SSL_ERROR_ZERO_RETURN) {
470                     /* remote end sent close_notify, send one back */
471                     SSL_shutdown(ssl);
472                 }
473                 free(rad);
474                 return NULL;
475             }
476         }
477     
478         if (total >= 20)
479             break;
480         
481         free(rad);
482         printf("radtlsget: packet smaller than minimum radius size\n");
483     }
484     
485     printf("radtlsget: got %d bytes\n", total);
486     return rad;
487 }
488
489 int clientradput(struct server *server, unsigned char *rad) {
490     int cnt;
491     size_t len;
492     unsigned long error;
493     struct timeval lastconnecttry;
494     
495     len = RADLEN(rad);
496     if (server->peer.type == 'U') {
497         if (send(server->sock, rad, len, 0) >= 0) {
498             printf("clienradput: sent UDP of length %d to %s port %s\n", len, server->peer.host, server->peer.port);
499             return 1;
500         }
501         err("clientradput: send failed");
502         return 0;
503     }
504
505     lastconnecttry = server->lastconnecttry;
506     while ((cnt = SSL_write(server->peer.ssl, rad, len)) <= 0) {
507         while ((error = ERR_get_error()))
508             err("clientwr: TLS: %s", ERR_error_string(error, NULL));
509         tlsconnect(server, &lastconnecttry, "clientradput");
510         lastconnecttry = server->lastconnecttry;
511     }
512
513     server->connectionok = 1;
514     printf("clientradput: Sent %d bytes, Radius packet of length %d to TLS peer %s\n",
515            cnt, len, server->peer.host);
516     return 1;
517 }
518
519 int radsign(unsigned char *rad, unsigned char *sec) {
520     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
521     static unsigned char first = 1;
522     static EVP_MD_CTX mdctx;
523     unsigned int md_len;
524     int result;
525     
526     pthread_mutex_lock(&lock);
527     if (first) {
528         EVP_MD_CTX_init(&mdctx);
529         first = 0;
530     }
531
532     result = (EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) &&
533         EVP_DigestUpdate(&mdctx, rad, RADLEN(rad)) &&
534         EVP_DigestUpdate(&mdctx, sec, strlen((char *)sec)) &&
535         EVP_DigestFinal_ex(&mdctx, rad + 4, &md_len) &&
536         md_len == 16);
537     pthread_mutex_unlock(&lock);
538     return result;
539 }
540
541 int validauth(unsigned char *rad, unsigned char *reqauth, unsigned char *sec) {
542     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
543     static unsigned char first = 1;
544     static EVP_MD_CTX mdctx;
545     unsigned char hash[EVP_MAX_MD_SIZE];
546     unsigned int len;
547     int result;
548     
549     pthread_mutex_lock(&lock);
550     if (first) {
551         EVP_MD_CTX_init(&mdctx);
552         first = 0;
553     }
554
555     len = RADLEN(rad);
556     
557     result = (EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) &&
558               EVP_DigestUpdate(&mdctx, rad, 4) &&
559               EVP_DigestUpdate(&mdctx, reqauth, 16) &&
560               (len <= 20 || EVP_DigestUpdate(&mdctx, rad + 20, len - 20)) &&
561               EVP_DigestUpdate(&mdctx, sec, strlen((char *)sec)) &&
562               EVP_DigestFinal_ex(&mdctx, hash, &len) &&
563               len == 16 &&
564               !memcmp(hash, rad + 4, 16));
565     pthread_mutex_unlock(&lock);
566     return result;
567 }
568               
569 int checkmessageauth(unsigned char *rad, uint8_t *authattr, char *secret) {
570     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
571     static unsigned char first = 1;
572     static HMAC_CTX hmacctx;
573     unsigned int md_len;
574     uint8_t auth[16], hash[EVP_MAX_MD_SIZE];
575     
576     pthread_mutex_lock(&lock);
577     if (first) {
578         HMAC_CTX_init(&hmacctx);
579         first = 0;
580     }
581
582     memcpy(auth, authattr, 16);
583     memset(authattr, 0, 16);
584     md_len = 0;
585     HMAC_Init_ex(&hmacctx, secret, strlen(secret), EVP_md5(), NULL);
586     HMAC_Update(&hmacctx, rad, RADLEN(rad));
587     HMAC_Final(&hmacctx, hash, &md_len);
588     memcpy(authattr, auth, 16);
589     if (md_len != 16) {
590         printf("message auth computation failed\n");
591         pthread_mutex_unlock(&lock);
592         return 0;
593     }
594
595     if (memcmp(auth, hash, 16)) {
596         printf("message authenticator, wrong value\n");
597         pthread_mutex_unlock(&lock);
598         return 0;
599     }   
600         
601     pthread_mutex_unlock(&lock);
602     return 1;
603 }
604
605 int createmessageauth(unsigned char *rad, unsigned char *authattrval, char *secret) {
606     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
607     static unsigned char first = 1;
608     static HMAC_CTX hmacctx;
609     unsigned int md_len;
610
611     if (!authattrval)
612         return 1;
613     
614     pthread_mutex_lock(&lock);
615     if (first) {
616         HMAC_CTX_init(&hmacctx);
617         first = 0;
618     }
619
620     memset(authattrval, 0, 16);
621     md_len = 0;
622     HMAC_Init_ex(&hmacctx, secret, strlen(secret), EVP_md5(), NULL);
623     HMAC_Update(&hmacctx, rad, RADLEN(rad));
624     HMAC_Final(&hmacctx, authattrval, &md_len);
625     if (md_len != 16) {
626         printf("message auth computation failed\n");
627         pthread_mutex_unlock(&lock);
628         return 0;
629     }
630
631     pthread_mutex_unlock(&lock);
632     return 1;
633 }
634
635 void sendrq(struct server *to, struct client *from, struct request *rq) {
636     int i;
637     
638     pthread_mutex_lock(&to->newrq_mutex);
639     /* might simplify if only try nextid, might be ok */
640     for (i = to->nextid; i < MAX_REQUESTS; i++)
641         if (!to->requests[i].buf)
642             break;
643     if (i == MAX_REQUESTS) {
644         for (i = 0; i < to->nextid; i++)
645             if (!to->requests[i].buf)
646                 break;
647         if (i == to->nextid) {
648             printf("No room in queue, dropping request\n");
649             pthread_mutex_unlock(&to->newrq_mutex);
650             return;
651         }
652     }
653     
654     to->nextid = i + 1;
655     rq->buf[1] = (char)i;
656     printf("sendrq: inserting packet with id %d in queue for %s\n", i, to->peer.host);
657     
658     if (!createmessageauth(rq->buf, rq->messageauthattrval, to->peer.secret))
659         return;
660
661     to->requests[i] = *rq;
662
663     if (!to->newrq) {
664         to->newrq = 1;
665         printf("signalling client writer\n");
666         pthread_cond_signal(&to->newrq_cond);
667     }
668     pthread_mutex_unlock(&to->newrq_mutex);
669 }
670
671 void sendreply(struct client *to, struct server *from, unsigned char *buf, struct sockaddr_storage *tosa) {
672     struct replyq *replyq = to->replyq;
673     
674     pthread_mutex_lock(&replyq->count_mutex);
675     if (replyq->count == replyq->size) {
676         printf("No room in queue, dropping request\n");
677         pthread_mutex_unlock(&replyq->count_mutex);
678         return;
679     }
680
681     replyq->replies[replyq->count].buf = buf;
682     if (tosa)
683         replyq->replies[replyq->count].tosa = *tosa;
684     replyq->count++;
685
686     if (replyq->count == 1) {
687         printf("signalling client writer\n");
688         pthread_cond_signal(&replyq->count_cond);
689     }
690     pthread_mutex_unlock(&replyq->count_mutex);
691 }
692
693 int pwdencrypt(uint8_t *in, uint8_t len, char *shared, uint8_t sharedlen, uint8_t *auth) {
694     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
695     static unsigned char first = 1;
696     static EVP_MD_CTX mdctx;
697     unsigned char hash[EVP_MAX_MD_SIZE], *input;
698     unsigned int md_len;
699     uint8_t i, offset = 0, out[128];
700     
701     pthread_mutex_lock(&lock);
702     if (first) {
703         EVP_MD_CTX_init(&mdctx);
704         first = 0;
705     }
706
707     input = auth;
708     for (;;) {
709         if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
710             !EVP_DigestUpdate(&mdctx, (uint8_t *)shared, sharedlen) ||
711             !EVP_DigestUpdate(&mdctx, input, 16) ||
712             !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
713             md_len != 16) {
714             pthread_mutex_unlock(&lock);
715             return 0;
716         }
717         for (i = 0; i < 16; i++)
718             out[offset + i] = hash[i] ^ in[offset + i];
719         input = out + offset - 16;
720         offset += 16;
721         if (offset == len)
722             break;
723     }
724     memcpy(in, out, len);
725     pthread_mutex_unlock(&lock);
726     return 1;
727 }
728
729 int pwddecrypt(uint8_t *in, uint8_t len, char *shared, uint8_t sharedlen, uint8_t *auth) {
730     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
731     static unsigned char first = 1;
732     static EVP_MD_CTX mdctx;
733     unsigned char hash[EVP_MAX_MD_SIZE], *input;
734     unsigned int md_len;
735     uint8_t i, offset = 0, out[128];
736     
737     pthread_mutex_lock(&lock);
738     if (first) {
739         EVP_MD_CTX_init(&mdctx);
740         first = 0;
741     }
742
743     input = auth;
744     for (;;) {
745         if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
746             !EVP_DigestUpdate(&mdctx, (uint8_t *)shared, sharedlen) ||
747             !EVP_DigestUpdate(&mdctx, input, 16) ||
748             !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
749             md_len != 16) {
750             pthread_mutex_unlock(&lock);
751             return 0;
752         }
753         for (i = 0; i < 16; i++)
754             out[offset + i] = hash[i] ^ in[offset + i];
755         input = in + offset;
756         offset += 16;
757         if (offset == len)
758             break;
759     }
760     memcpy(in, out, len);
761     pthread_mutex_unlock(&lock);
762     return 1;
763 }
764
765 int msmppencrypt(uint8_t *text, uint8_t len, uint8_t *shared, uint8_t sharedlen, uint8_t *auth, uint8_t *salt) {
766     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
767     static unsigned char first = 1;
768     static EVP_MD_CTX mdctx;
769     unsigned char hash[EVP_MAX_MD_SIZE];
770     unsigned int md_len;
771     uint8_t i, offset;
772     
773     pthread_mutex_lock(&lock);
774     if (first) {
775         EVP_MD_CTX_init(&mdctx);
776         first = 0;
777     }
778
779 #if 0    
780     printf("msppencrypt auth in: ");
781     for (i = 0; i < 16; i++)
782         printf("%02x ", auth[i]);
783     printf("\n");
784     
785     printf("msppencrypt salt in: ");
786     for (i = 0; i < 2; i++)
787         printf("%02x ", salt[i]);
788     printf("\n");
789     
790     printf("msppencrypt in: ");
791     for (i = 0; i < len; i++)
792         printf("%02x ", text[i]);
793     printf("\n");
794 #endif
795     
796     if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
797         !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
798         !EVP_DigestUpdate(&mdctx, auth, 16) ||
799         !EVP_DigestUpdate(&mdctx, salt, 2) ||
800         !EVP_DigestFinal_ex(&mdctx, hash, &md_len)) {
801         pthread_mutex_unlock(&lock);
802         return 0;
803     }
804
805 #if 0    
806     printf("msppencrypt hash: ");
807     for (i = 0; i < 16; i++)
808         printf("%02x ", hash[i]);
809     printf("\n");
810 #endif
811     
812     for (i = 0; i < 16; i++)
813         text[i] ^= hash[i];
814     
815     for (offset = 16; offset < len; offset += 16) {
816 #if 0   
817         printf("text + offset - 16 c(%d): ", offset / 16);
818         for (i = 0; i < 16; i++)
819             printf("%02x ", (text + offset - 16)[i]);
820         printf("\n");
821 #endif
822         if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
823             !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
824             !EVP_DigestUpdate(&mdctx, text + offset - 16, 16) ||
825             !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
826             md_len != 16) {
827             pthread_mutex_unlock(&lock);
828             return 0;
829         }
830 #if 0   
831         printf("msppencrypt hash: ");
832         for (i = 0; i < 16; i++)
833             printf("%02x ", hash[i]);
834         printf("\n");
835 #endif    
836         
837         for (i = 0; i < 16; i++)
838             text[offset + i] ^= hash[i];
839     }
840     
841 #if 0
842     printf("msppencrypt out: ");
843     for (i = 0; i < len; i++)
844         printf("%02x ", text[i]);
845     printf("\n");
846 #endif
847
848     pthread_mutex_unlock(&lock);
849     return 1;
850 }
851
852 int msmppdecrypt(uint8_t *text, uint8_t len, uint8_t *shared, uint8_t sharedlen, uint8_t *auth, uint8_t *salt) {
853     static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
854     static unsigned char first = 1;
855     static EVP_MD_CTX mdctx;
856     unsigned char hash[EVP_MAX_MD_SIZE];
857     unsigned int md_len;
858     uint8_t i, offset;
859     char plain[255];
860     
861     pthread_mutex_lock(&lock);
862     if (first) {
863         EVP_MD_CTX_init(&mdctx);
864         first = 0;
865     }
866
867 #if 0    
868     printf("msppdecrypt auth in: ");
869     for (i = 0; i < 16; i++)
870         printf("%02x ", auth[i]);
871     printf("\n");
872     
873     printf("msppedecrypt salt in: ");
874     for (i = 0; i < 2; i++)
875         printf("%02x ", salt[i]);
876     printf("\n");
877     
878     printf("msppedecrypt in: ");
879     for (i = 0; i < len; i++)
880         printf("%02x ", text[i]);
881     printf("\n");
882 #endif
883     
884     if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
885         !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
886         !EVP_DigestUpdate(&mdctx, auth, 16) ||
887         !EVP_DigestUpdate(&mdctx, salt, 2) ||
888         !EVP_DigestFinal_ex(&mdctx, hash, &md_len)) {
889         pthread_mutex_unlock(&lock);
890         return 0;
891     }
892
893 #if 0    
894     printf("msppedecrypt hash: ");
895     for (i = 0; i < 16; i++)
896         printf("%02x ", hash[i]);
897     printf("\n");
898 #endif
899     
900     for (i = 0; i < 16; i++)
901         plain[i] = text[i] ^ hash[i];
902     
903     for (offset = 16; offset < len; offset += 16) {
904 #if 0   
905         printf("text + offset - 16 c(%d): ", offset / 16);
906         for (i = 0; i < 16; i++)
907             printf("%02x ", (text + offset - 16)[i]);
908         printf("\n");
909 #endif
910         if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
911             !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
912             !EVP_DigestUpdate(&mdctx, text + offset - 16, 16) ||
913             !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
914             md_len != 16) {
915             pthread_mutex_unlock(&lock);
916             return 0;
917         }
918 #if 0   
919     printf("msppedecrypt hash: ");
920     for (i = 0; i < 16; i++)
921         printf("%02x ", hash[i]);
922     printf("\n");
923 #endif    
924
925     for (i = 0; i < 16; i++)
926         plain[offset + i] = text[offset + i] ^ hash[i];
927     }
928
929     memcpy(text, plain, len);
930 #if 0
931     printf("msppedecrypt out: ");
932     for (i = 0; i < len; i++)
933         printf("%02x ", text[i]);
934     printf("\n");
935 #endif
936
937     pthread_mutex_unlock(&lock);
938     return 1;
939 }
940
941 struct server *id2server(char *id, uint8_t len) {
942     int i;
943     char **realm, *idrealm;
944
945     idrealm = strchr(id, '@');
946     if (idrealm) {
947         idrealm++;
948         len -= idrealm - id;
949     } else {
950         idrealm = "-";
951         len = 1;
952     }
953     for (i = 0; i < server_count; i++) {
954         for (realm = servers[i].realms; *realm; realm++) {
955             if ((strlen(*realm) == 1 && **realm == '*') ||
956                 (strlen(*realm) == len && !memcmp(idrealm, *realm, len))) {
957                 printf("found matching realm: %s, host %s\n", *realm, servers[i].peer.host);
958                 return servers + i;
959             }
960         }
961     }
962     return NULL;
963 }
964
965 int rqinqueue(struct server *to, struct client *from, uint8_t id) {
966     int i;
967     
968     pthread_mutex_lock(&to->newrq_mutex);
969     for (i = 0; i < MAX_REQUESTS; i++)
970         if (to->requests[i].buf && to->requests[i].origid == id && to->requests[i].from == from)
971             break;
972     pthread_mutex_unlock(&to->newrq_mutex);
973     
974     return i < MAX_REQUESTS;
975 }
976         
977 struct server *radsrv(struct request *rq, unsigned char *buf, struct client *from) {
978     uint8_t code, id, *auth, *attr, attrvallen;
979     uint8_t *usernameattr = NULL, *userpwdattr = NULL, *tunnelpwdattr = NULL, *messageauthattr = NULL;
980     int i;
981     uint16_t len;
982     int left;
983     struct server *to;
984     unsigned char newauth[16];
985     
986     code = *(uint8_t *)buf;
987     id = *(uint8_t *)(buf + 1);
988     len = RADLEN(buf);
989     auth = (uint8_t *)(buf + 4);
990
991     printf("radsrv: code %d, id %d, length %d\n", code, id, len);
992     
993     if (code != RAD_Access_Request) {
994         printf("radsrv: server currently accepts only access-requests, ignoring\n");
995         return NULL;
996     }
997
998     left = len - 20;
999     attr = buf + 20;
1000     
1001     while (left > 1) {
1002         left -= attr[RAD_Attr_Length];
1003         if (left < 0) {
1004             printf("radsrv: attribute length exceeds packet length, ignoring packet\n");
1005             return NULL;
1006         }
1007         switch (attr[RAD_Attr_Type]) {
1008         case RAD_Attr_User_Name:
1009             usernameattr = attr;
1010             break;
1011         case RAD_Attr_User_Password:
1012             userpwdattr = attr;
1013             break;
1014         case RAD_Attr_Tunnel_Password:
1015             tunnelpwdattr = attr;
1016             break;
1017         case RAD_Attr_Message_Authenticator:
1018             messageauthattr = attr;
1019             break;
1020         }
1021         attr += attr[RAD_Attr_Length];
1022     }
1023     if (left)
1024         printf("radsrv: malformed packet? remaining byte after last attribute\n");
1025
1026     if (usernameattr) {
1027         printf("radsrv: Username: ");
1028         for (i = 0; i < usernameattr[RAD_Attr_Length] - 2; i++)
1029             printf("%c", usernameattr[RAD_Attr_Value + i]);
1030         printf("\n");
1031     }
1032
1033     to = id2server((char *)&usernameattr[RAD_Attr_Value], usernameattr[RAD_Attr_Length] - 2);
1034     if (!to) {
1035         printf("radsrv: ignoring request, don't know where to send it\n");
1036         return NULL;
1037     }
1038
1039     if (rqinqueue(to, from, id)) {
1040         printf("radsrv: ignoring request from host %s with id %d, already got one\n", from->peer.host, id);
1041         return NULL;
1042     }
1043     
1044     if (messageauthattr && (messageauthattr[RAD_Attr_Length] != 18 ||
1045                             !checkmessageauth(buf, &messageauthattr[RAD_Attr_Value], from->peer.secret))) {
1046         printf("radsrv: message authentication failed\n");
1047         return NULL;
1048     }
1049
1050     if (!RAND_bytes(newauth, 16)) {
1051         printf("radsrv: failed to generate random auth\n");
1052         return NULL;
1053     }
1054
1055     printauth("auth", auth);
1056     printauth("newauth", newauth);
1057     
1058     if (userpwdattr) {
1059         printf("radsrv: found userpwdattr of length %d\n", userpwdattr[RAD_Attr_Length]);
1060         attrvallen = userpwdattr[RAD_Attr_Length] - 2;
1061         if (attrvallen < 16 || attrvallen > 128 || attrvallen % 16) {
1062             printf("radsrv: invalid user password length\n");
1063             return NULL;
1064         }
1065         
1066         if (!pwddecrypt(&userpwdattr[RAD_Attr_Value], attrvallen, from->peer.secret, strlen(from->peer.secret), auth)) {
1067             printf("radsrv: cannot decrypt password\n");
1068             return NULL;
1069         }
1070         printf("radsrv: password: ");
1071         for (i = 0; i < attrvallen; i++)
1072             printf("%02x ", userpwdattr[RAD_Attr_Value + i]);
1073         printf("\n");
1074         if (!pwdencrypt(&userpwdattr[RAD_Attr_Value], attrvallen, to->peer.secret, strlen(to->peer.secret), newauth)) {
1075             printf("radsrv: cannot encrypt password\n");
1076             return NULL;
1077         }
1078     }
1079
1080     if (tunnelpwdattr) {
1081         printf("radsrv: found tunnelpwdattr of length %d\n", tunnelpwdattr[RAD_Attr_Length]);
1082         attrvallen = tunnelpwdattr[RAD_Attr_Length] - 2;
1083         if (attrvallen < 16 || attrvallen > 128 || attrvallen % 16) {
1084             printf("radsrv: invalid user password length\n");
1085             return NULL;
1086         }
1087         
1088         if (!pwddecrypt(&tunnelpwdattr[RAD_Attr_Value], attrvallen, from->peer.secret, strlen(from->peer.secret), auth)) {
1089             printf("radsrv: cannot decrypt password\n");
1090             return NULL;
1091         }
1092         printf("radsrv: password: ");
1093         for (i = 0; i < attrvallen; i++)
1094             printf("%02x ", tunnelpwdattr[RAD_Attr_Value + i]);
1095         printf("\n");
1096         if (!pwdencrypt(&tunnelpwdattr[RAD_Attr_Value], attrvallen, to->peer.secret, strlen(to->peer.secret), newauth)) {
1097             printf("radsrv: cannot encrypt password\n");
1098             return NULL;
1099         }
1100     }
1101
1102     rq->buf = buf;
1103     rq->from = from;
1104     rq->origid = id;
1105     rq->messageauthattrval = (messageauthattr ? &messageauthattr[RAD_Attr_Value] : NULL);
1106     memcpy(rq->origauth, auth, 16);
1107     memcpy(auth, newauth, 16);
1108     printauth("rq->origauth", (unsigned char *)rq->origauth);
1109     printauth("auth", auth);
1110     return to;
1111 }
1112
1113 void *clientrd(void *arg) {
1114     struct server *server = (struct server *)arg;
1115     struct client *from;
1116     int i, left, subleft;
1117     unsigned char *buf, *messageauthattr, *subattr, *attr;
1118     struct sockaddr_storage fromsa;
1119     struct timeval lastconnecttry;
1120     char tmp[255];
1121     
1122     for (;;) {
1123     getnext:
1124         lastconnecttry = server->lastconnecttry;
1125         buf = (server->peer.type == 'U' ? radudpget(server->sock, NULL, &server, NULL) : radtlsget(server->peer.ssl));
1126         if (!buf && server->peer.type == 'T') {
1127             tlsconnect(server, &lastconnecttry, "clientrd");
1128             continue;
1129         }
1130     
1131         server->connectionok = 1;
1132
1133         if (*buf != RAD_Access_Accept && *buf != RAD_Access_Reject && *buf != RAD_Access_Challenge) {
1134             printf("clientrd: discarding, only accept access accept, access reject and access challenge messages\n");
1135             continue;
1136         }
1137
1138         printf("got message type: %d, id: %d\n", buf[0], buf[1]);
1139         
1140         i = buf[1]; /* i is the id */
1141
1142         pthread_mutex_lock(&server->newrq_mutex);
1143         if (!server->requests[i].buf || !server->requests[i].tries) {
1144             pthread_mutex_unlock(&server->newrq_mutex);
1145             printf("clientrd: no matching request sent with this id, ignoring\n");
1146             continue;
1147         }
1148
1149         if (server->requests[i].received) {
1150             pthread_mutex_unlock(&server->newrq_mutex);
1151             printf("clientrd: already received, ignoring\n");
1152             continue;
1153         }
1154         
1155         if (!validauth(buf, server->requests[i].buf + 4, (unsigned char *)server->peer.secret)) {
1156             pthread_mutex_unlock(&server->newrq_mutex);
1157             printf("clientrd: invalid auth, ignoring\n");
1158             continue;
1159         }
1160         
1161         from = server->requests[i].from;
1162
1163         /* messageauthattr present? */
1164         messageauthattr = NULL;
1165         left = RADLEN(buf) - 20;
1166         attr = buf + 20;
1167         while (left > 1) {
1168             left -= attr[RAD_Attr_Length];
1169             if (left < 0) {
1170                 printf("clientrd: attribute length exceeds packet length, ignoring packet\n");
1171                 goto getnext;
1172             }
1173             if (attr[RAD_Attr_Type] == RAD_Attr_Message_Authenticator) {
1174                 if (attr[RAD_Attr_Length] != 18) {
1175                     printf("clientrd: illegal message auth attribute length, ignoring packet\n");
1176                     goto getnext;
1177                 }
1178                 memcpy(tmp, buf + 4, 16);
1179                 memcpy(buf + 4, server->requests[i].buf + 4, 16);
1180                 if (!checkmessageauth(buf, &attr[RAD_Attr_Value], server->peer.secret)) {
1181                     printf("clientrd: message authentication failed\n");
1182                     goto getnext;
1183                 }
1184                 memcpy(buf + 4, tmp, 16);
1185                 printf("clientrd: message auth ok\n");
1186                 messageauthattr = attr;
1187                 break;
1188             }
1189             attr += attr[RAD_Attr_Length];
1190         }
1191
1192         /* handle MS MPPE */
1193         left = RADLEN(buf) - 20;
1194         attr = buf + 20;
1195         while (left > 1) {
1196             left -= attr[RAD_Attr_Length];
1197             if (left < 0) {
1198                 printf("clientrd: attribute length exceeds packet length, ignoring packet\n");
1199                 goto getnext;
1200             }
1201             if (attr[RAD_Attr_Type] == RAD_Attr_Vendor_Specific &&
1202                 ((uint16_t *)attr)[1] == 0 && ntohs(((uint16_t *)attr)[2]) == 311) { /* 311 == MS */
1203                 subleft = attr[RAD_Attr_Length] - 6;
1204                 subattr = attr + 6;
1205                 while (subleft > 1) {
1206                     subleft -= subattr[RAD_Attr_Length];
1207                     if (subleft < 0)
1208                         break;
1209                     if (subattr[RAD_Attr_Type] != RAD_VS_ATTR_MS_MPPE_Send_Key &&
1210                         subattr[RAD_Attr_Type] != RAD_VS_ATTR_MS_MPPE_Recv_Key)
1211                         continue;
1212                     printf("clientrd: Got MS MPPE\n");
1213                     if (subattr[RAD_Attr_Length] < 20)
1214                         continue;
1215
1216                     if (!msmppdecrypt(subattr + 4, subattr[RAD_Attr_Length] - 4, (unsigned char *)server->peer.secret,
1217                                       strlen(server->peer.secret), server->requests[i].buf + 4, subattr + 2)) {
1218                         printf("clientrd: failed to decrypt msppe key\n");
1219                         continue;
1220                     }
1221
1222                     if (!msmppencrypt(subattr + 4, subattr[RAD_Attr_Length] - 4, (unsigned char *)from->peer.secret,
1223                                       strlen(from->peer.secret), (unsigned char *)server->requests[i].origauth, subattr + 2)) {
1224                         printf("clientrd: failed to encrypt msppe key\n");
1225                         continue;
1226                     }
1227                 }
1228                 if (subleft < 0) {
1229                     printf("clientrd: bad vendor specific attr or subattr length, ignoring packet\n");
1230                     goto getnext;
1231                 }
1232             }
1233             attr += attr[RAD_Attr_Length];
1234         }
1235
1236         /* once we set received = 1, requests[i] may be reused */
1237         buf[1] = (char)server->requests[i].origid;
1238         memcpy(buf + 4, server->requests[i].origauth, 16);
1239         printauth("origauth/buf+4", buf + 4);
1240         if (messageauthattr) {
1241             if (!createmessageauth(buf, &messageauthattr[RAD_Attr_Value], from->peer.secret))
1242                 continue;
1243             printf("clientrd: computed messageauthattr\n");
1244         }
1245
1246         if (from->peer.type == 'U')
1247             fromsa = server->requests[i].fromsa;
1248         server->requests[i].received = 1;
1249         pthread_mutex_unlock(&server->newrq_mutex);
1250
1251         if (!radsign(buf, (unsigned char *)from->peer.secret)) {
1252             printf("clientrd: failed to sign message\n");
1253             continue;
1254         }
1255         printauth("signedorigauth/buf+4", buf + 4);             
1256         printf("clientrd: giving packet back to where it came from\n");
1257         sendreply(from, server, buf, from->peer.type == 'U' ? &fromsa : NULL);
1258     }
1259 }
1260
1261 void *clientwr(void *arg) {
1262     struct server *server = (struct server *)arg;
1263     struct request *rq;
1264     pthread_t clientrdth;
1265     int i;
1266     struct timeval now;
1267     struct timespec timeout;
1268
1269     memset(&timeout, 0, sizeof(struct timespec));
1270     
1271     if (server->peer.type == 'U') {
1272         if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0) {
1273             printf("clientwr: connecttoserver failed\n");
1274             exit(1);
1275         }
1276     } else
1277         tlsconnect(server, NULL, "new client");
1278     
1279     if (pthread_create(&clientrdth, NULL, clientrd, (void *)server))
1280         errx("clientwr: pthread_create failed");
1281
1282     for (;;) {
1283         pthread_mutex_lock(&server->newrq_mutex);
1284         if (!server->newrq) {
1285             if (timeout.tv_nsec) {
1286                 printf("clientwr: waiting up to %ld secs for new request\n", timeout.tv_nsec);
1287                 pthread_cond_timedwait(&server->newrq_cond, &server->newrq_mutex, &timeout);
1288                 timeout.tv_nsec = 0;
1289             } else {
1290                 printf("clientwr: waiting for new request\n");
1291                 pthread_cond_wait(&server->newrq_cond, &server->newrq_mutex);
1292             }
1293         }
1294         if (server->newrq) {
1295             printf("clientwr: got new request\n");
1296             server->newrq = 0;
1297         } else
1298             printf("clientwr: request timer expired, processing request queue\n");
1299         pthread_mutex_unlock(&server->newrq_mutex);
1300
1301         for (i = 0; i < MAX_REQUESTS; i++) {
1302             pthread_mutex_lock(&server->newrq_mutex);
1303             while (!server->requests[i].buf && i < MAX_REQUESTS)
1304                 i++;
1305             if (i == MAX_REQUESTS) {
1306                 pthread_mutex_unlock(&server->newrq_mutex);
1307                 break;
1308             }
1309             rq = server->requests + i;
1310
1311             if (rq->received) {
1312                 printf("clientwr: removing received packet from queue\n");
1313                 free(rq->buf);
1314                 /* setting this to NULL means that it can be reused */
1315                 rq->buf = NULL;
1316                 pthread_mutex_unlock(&server->newrq_mutex);
1317                 continue;
1318             }
1319             
1320             gettimeofday(&now, NULL);
1321             if (now.tv_sec <= rq->expiry.tv_sec) {
1322                 if (!timeout.tv_sec || rq->expiry.tv_sec < timeout.tv_sec)
1323                     timeout.tv_sec = rq->expiry.tv_sec;
1324                 pthread_mutex_unlock(&server->newrq_mutex);
1325                 continue;
1326             }
1327
1328             if (rq->tries == (server->peer.type == 'T' ? 1 : REQUEST_RETRIES)) {
1329                 printf("clientwr: removing expired packet from queue\n");
1330                 free(rq->buf);
1331                 /* setting this to NULL means that it can be reused */
1332                 rq->buf = NULL;
1333                 pthread_mutex_unlock(&server->newrq_mutex);
1334                 continue;
1335             }
1336             pthread_mutex_unlock(&server->newrq_mutex);
1337
1338             rq->expiry.tv_sec = now.tv_sec +
1339                 (server->peer.type == 'T' ? REQUEST_EXPIRY : REQUEST_EXPIRY / REQUEST_RETRIES);
1340             if (!timeout.tv_sec || rq->expiry.tv_sec < timeout.tv_sec)
1341                 timeout.tv_sec = rq->expiry.tv_sec;
1342             rq->tries++;
1343             clientradput(server, server->requests[i].buf);
1344             usleep(200000);
1345         }
1346     }
1347     /* should do more work to maintain TLS connections, keepalives etc */
1348 }
1349
1350 void *udpserverwr(void *arg) {
1351     struct replyq *replyq = &udp_server_replyq;
1352     struct reply *reply = replyq->replies;
1353     
1354     pthread_mutex_lock(&replyq->count_mutex);
1355     for (;;) {
1356         while (!replyq->count) {
1357             printf("udp server writer, waiting for signal\n");
1358             pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex);
1359             printf("udp server writer, got signal\n");
1360         }
1361         pthread_mutex_unlock(&replyq->count_mutex);
1362         
1363         if (sendto(udp_server_sock, reply->buf, RADLEN(reply->buf), 0,
1364                    (struct sockaddr *)&reply->tosa, SOCKADDR_SIZE(reply->tosa)) < 0)
1365             err("sendudp: send failed");
1366         free(reply->buf);
1367         
1368         pthread_mutex_lock(&replyq->count_mutex);
1369         replyq->count--;
1370         memmove(replyq->replies, replyq->replies + 1,
1371                 replyq->count * sizeof(struct reply));
1372     }
1373 }
1374
1375 void *udpserverrd(void *arg) {
1376     struct request rq;
1377     unsigned char *buf;
1378     struct server *to;
1379     struct client *fr;
1380     pthread_t udpserverwrth;
1381     
1382     if ((udp_server_sock = bindport(SOCK_DGRAM, options.udpserverport)) < 0) {
1383         printf("udpserverrd: socket/bind failed\n");
1384         exit(1);
1385     }
1386     printf("udpserverrd: listening on UDP port %s\n", options.udpserverport);
1387
1388     if (pthread_create(&udpserverwrth, NULL, udpserverwr, NULL))
1389         errx("pthread_create failed");
1390     
1391     for (;;) {
1392         fr = NULL;
1393         memset(&rq, 0, sizeof(struct request));
1394         buf = radudpget(udp_server_sock, &fr, NULL, &rq.fromsa);
1395         to = radsrv(&rq, buf, fr);
1396         if (!to) {
1397             printf("udpserverrd: ignoring request, no place to send it\n");
1398             continue;
1399         }
1400         sendrq(to, fr, &rq);
1401     }
1402 }
1403
1404 void *tlsserverwr(void *arg) {
1405     int cnt;
1406     unsigned long error;
1407     struct client *client = (struct client *)arg;
1408     struct replyq *replyq;
1409     
1410     printf("tlsserverwr starting for %s\n", client->peer.host);
1411     replyq = client->replyq;
1412     pthread_mutex_lock(&replyq->count_mutex);
1413     for (;;) {
1414         while (!replyq->count) {
1415             if (client->peer.ssl) {         
1416                 printf("tls server writer, waiting for signal\n");
1417                 pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex);
1418                 printf("tls server writer, got signal\n");
1419             }
1420             if (!client->peer.ssl) {
1421                 /* ssl might have changed while waiting */
1422                 pthread_mutex_unlock(&replyq->count_mutex);
1423                 printf("tlsserverwr: exiting as requested\n");
1424                 pthread_exit(NULL);
1425             }
1426         }
1427         pthread_mutex_unlock(&replyq->count_mutex);
1428         cnt = SSL_write(client->peer.ssl, replyq->replies->buf, RADLEN(replyq->replies->buf));
1429         if (cnt > 0)
1430             printf("tlsserverwr: Sent %d bytes, Radius packet of length %d\n",
1431                    cnt, RADLEN(replyq->replies->buf));
1432         else
1433             while ((error = ERR_get_error()))
1434                 err("tlsserverwr: SSL: %s", ERR_error_string(error, NULL));
1435         free(replyq->replies->buf);
1436
1437         pthread_mutex_lock(&replyq->count_mutex);
1438         replyq->count--;
1439         memmove(replyq->replies, replyq->replies + 1, replyq->count * sizeof(struct reply));
1440     }
1441 }
1442
1443 void *tlsserverrd(void *arg) {
1444     struct request rq;
1445     char unsigned *buf;
1446     unsigned long error;
1447     struct server *to;
1448     int s;
1449     struct client *client = (struct client *)arg;
1450     pthread_t tlsserverwrth;
1451     SSL *ssl;
1452     
1453     printf("tlsserverrd starting for %s\n", client->peer.host);
1454     ssl = client->peer.ssl;
1455
1456     if (SSL_accept(ssl) <= 0) {
1457         while ((error = ERR_get_error()))
1458             err("tlsserverrd: SSL: %s", ERR_error_string(error, NULL));
1459         errx("accept failed, child exiting");
1460     }
1461
1462     if (tlsverifycert(&client->peer)) {
1463         if (pthread_create(&tlsserverwrth, NULL, tlsserverwr, (void *)client))
1464             errx("pthread_create failed");
1465     
1466         for (;;) {
1467             buf = radtlsget(client->peer.ssl);
1468             if (!buf)
1469                 break;
1470             printf("tlsserverrd: got Radius message from %s\n", client->peer.host);
1471             memset(&rq, 0, sizeof(struct request));
1472             to = radsrv(&rq, buf, client);
1473             if (!to) {
1474                 printf("ignoring request, no place to send it\n");
1475                 continue;
1476             }
1477             sendrq(to, client, &rq);
1478         }
1479         printf("tlsserverrd: connection lost\n");
1480         /* stop writer by setting peer.ssl to NULL and give signal in case waiting for data */
1481         client->peer.ssl = NULL;
1482         pthread_mutex_lock(&client->replyq->count_mutex);
1483         pthread_cond_signal(&client->replyq->count_cond);
1484         pthread_mutex_unlock(&client->replyq->count_mutex);
1485         printf("tlsserverrd: waiting for writer to end\n");
1486         pthread_join(tlsserverwrth, NULL);
1487     }
1488     s = SSL_get_fd(ssl);
1489     SSL_free(ssl);
1490     close(s);
1491     printf("tlsserverrd thread for %s exiting\n", client->peer.host);
1492     client->peer.ssl = NULL;
1493     pthread_exit(NULL);
1494 }
1495
1496 int tlslistener() {
1497     pthread_t tlsserverth;
1498     int s, snew;
1499     struct sockaddr_storage from;
1500     size_t fromlen = sizeof(from);
1501     struct client *client;
1502
1503     if ((s = bindport(SOCK_STREAM, DEFAULT_TLS_PORT)) < 0) {
1504         printf("tlslistener: socket/bind failed\n");
1505         exit(1);
1506     }
1507     
1508     listen(s, 0);
1509     printf("listening for incoming TLS on port %s\n", DEFAULT_TLS_PORT);
1510
1511     for (;;) {
1512         snew = accept(s, (struct sockaddr *)&from, &fromlen);
1513         if (snew < 0)
1514             errx("accept failed");
1515         printf("incoming TLS connection from %s\n", addr2string((struct sockaddr *)&from, fromlen));
1516
1517         client = find_client('T', (struct sockaddr *)&from, NULL);
1518         if (!client) {
1519             printf("ignoring request, not a known TLS client\n");
1520             shutdown(snew, SHUT_RDWR);
1521             close(snew);
1522             continue;
1523         }
1524
1525         if (client->peer.ssl) {
1526             printf("Ignoring incoming connection, already have one from this client\n");
1527             shutdown(snew, SHUT_RDWR);
1528             close(snew);
1529             continue;
1530         }
1531         client->peer.ssl = SSL_new(ssl_ctx);
1532         SSL_set_fd(client->peer.ssl, snew);
1533         if (pthread_create(&tlsserverth, NULL, tlsserverrd, (void *)client))
1534             errx("pthread_create failed");
1535         pthread_detach(tlsserverth);
1536     }
1537     return 0;
1538 }
1539
1540 char *parsehostport(char *s, struct peer *peer) {
1541     char *p, *field;
1542     int ipv6 = 0;
1543
1544     p = s;
1545     /* allow literal addresses and port, e.g. [2001:db8::1]:1812 */
1546     if (*p == '[') {
1547         p++;
1548         field = p;
1549         for (; *p && *p != ']' && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1550         if (*p != ']') {
1551             printf("no ] matching initial [\n");
1552             exit(1);
1553         }
1554         ipv6 = 1;
1555     } else {
1556         field = p;
1557         for (; *p && *p != ':' && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1558     }
1559     if (field == p) {
1560         printf("missing host/address\n");
1561         exit(1);
1562     }
1563     peer->host = stringcopy(field, p - field);
1564     if (ipv6) {
1565         p++;
1566         if (*p && *p != ':' && *p != ' ' && *p != '\t' && *p != '\n') {
1567             printf("unexpected character after ]\n");
1568             exit(1);
1569         }
1570     }
1571     if (*p == ':') {
1572             /* port number or service name is specified */;
1573             field = ++p;
1574             for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1575             if (field == p) {
1576                 printf("syntax error, : but no following port\n");
1577                 exit(1);
1578             }
1579             peer->port = stringcopy(field, p - field);
1580     } else
1581         peer->port = stringcopy(peer->type == 'U' ? DEFAULT_UDP_PORT : DEFAULT_TLS_PORT, 0);
1582     return p;
1583 }
1584
1585 /* * is default, else longest match ... ";" used for separator */
1586 char *parserealmlist(char *s, struct server *server) {
1587     char *p;
1588     int i, n, l;
1589
1590     for (p = s, n = 1; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++)
1591         if (*p == ';')
1592             n++;
1593     l = p - s;
1594     if (!l) {
1595         printf("realm list must be specified\n");
1596         exit(1);
1597     }
1598     server->realmdata = stringcopy(s, l);
1599     server->realms = malloc((1+n) * sizeof(char *));
1600     if (!server->realms)
1601         errx("malloc failed");
1602     server->realms[0] = server->realmdata;
1603     for (n = 1, i = 0; i < l; i++)
1604         if (server->realmdata[i] == ';') {
1605             server->realmdata[i] = '\0';
1606             server->realms[n++] = server->realmdata + i + 1;
1607         }       
1608     server->realms[n] = NULL;
1609     return p;
1610 }
1611
1612 FILE *openconfigfile(const char *filename) {
1613     FILE *f;
1614     char pathname[100], *base;
1615     
1616     f = fopen(filename, "r");
1617     if (f) {
1618         printf("reading config file %s\n", filename);
1619         return f;
1620     }
1621
1622     if (strlen(filename) + 1 <= sizeof(pathname)) {
1623         /* basename() might modify the string */
1624         strcpy(pathname, filename);
1625         base = basename(pathname);
1626         f = fopen(base, "r");
1627     }
1628
1629     if (!f)
1630         err("could not read config file %s nor %s\n", filename, base);
1631
1632     printf("reading config file %s\n", base);
1633     return f;
1634 }
1635
1636 /* exactly one argument must be non-NULL */
1637 void getconfig(const char *serverfile, const char *clientfile) {
1638     FILE *f;
1639     char line[1024];
1640     char *p, *field, **r;
1641     struct client *client;
1642     struct server *server;
1643     struct peer *peer;
1644     int i, count, *ucount, *tcount;
1645  
1646     f = openconfigfile(serverfile ? serverfile : clientfile);
1647     if (serverfile) {
1648         ucount = &server_udp_count;
1649         tcount = &server_tls_count;
1650     } else {
1651         ucount = &client_udp_count;
1652         tcount = &client_tls_count;
1653     }
1654     while (fgets(line, 1024, f)) {
1655         for (p = line; *p == ' ' || *p == '\t'; p++);
1656         switch (*p) {
1657         case '#':
1658         case '\n':
1659             break;
1660         case 'T':
1661             (*tcount)++;
1662             break;
1663         case 'U':
1664             (*ucount)++;
1665             break;
1666         default:
1667             printf("type must be U or T, got %c\n", *p);
1668             exit(1);
1669         }
1670     }
1671
1672     if (serverfile) {
1673         count = server_count = server_udp_count + server_tls_count;
1674         servers = calloc(count, sizeof(struct server));
1675         if (!servers)
1676             errx("malloc failed");
1677     } else {
1678         count = client_count = client_udp_count + client_tls_count;
1679         clients = calloc(count, sizeof(struct client));
1680         if (!clients)
1681             errx("malloc failed");
1682     }
1683     
1684     if (client_udp_count) {
1685         udp_server_replyq.replies = malloc(client_udp_count * MAX_REQUESTS * sizeof(struct reply));
1686         if (!udp_server_replyq.replies)
1687             errx("malloc failed");
1688         udp_server_replyq.size = client_udp_count * MAX_REQUESTS;
1689         udp_server_replyq.count = 0;
1690         pthread_mutex_init(&udp_server_replyq.count_mutex, NULL);
1691         pthread_cond_init(&udp_server_replyq.count_cond, NULL);
1692     }    
1693     
1694     rewind(f);
1695     for (i = 0; i < count && fgets(line, 1024, f);) {
1696         if (serverfile) {
1697             server = &servers[i];
1698             peer = &server->peer;
1699         } else {
1700             client = &clients[i];
1701             peer = &client->peer;
1702         }
1703         for (p = line; *p == ' ' || *p == '\t'; p++);
1704         if (*p == '#' || *p == '\n')
1705             continue;
1706         peer->type = *p;        /* we already know it must be U or T */
1707         for (p++; *p == ' ' || *p == '\t'; p++);
1708         p = parsehostport(p, peer);
1709         for (; *p == ' ' || *p == '\t'; p++);
1710         if (serverfile) {
1711             p = parserealmlist(p, server);
1712             for (; *p == ' ' || *p == '\t'; p++);
1713         }
1714         field = p;
1715         for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1716         if (field == p) {
1717             /* no secret set and end of line, line is complete if TLS */
1718             if (peer->type == 'U') {
1719                 printf("secret must be specified for UDP\n");
1720                 exit(1);
1721             }
1722             peer->secret = stringcopy(DEFAULT_TLS_SECRET, 0);
1723         } else {
1724             peer->secret = stringcopy(field, p - field);
1725             /* check that rest of line only white space */
1726             for (; *p == ' ' || *p == '\t'; p++);
1727             if (*p && *p != '\n') {
1728                 printf("max 4 fields per line, found a 5th\n");
1729                 exit(1);
1730             }
1731         }
1732
1733         if ((serverfile && !resolvepeer(&server->peer)) ||
1734             (clientfile && !resolvepeer(&client->peer))) {
1735             printf("failed to resolve host %s port %s, exiting\n", peer->host, peer->port);
1736             exit(1);
1737         }
1738
1739         if (serverfile) {
1740             pthread_mutex_init(&server->lock, NULL);
1741             server->sock = -1;
1742             server->requests = calloc(MAX_REQUESTS, sizeof(struct request));
1743             if (!server->requests)
1744                 errx("malloc failed");
1745             server->newrq = 0;
1746             pthread_mutex_init(&server->newrq_mutex, NULL);
1747             pthread_cond_init(&server->newrq_cond, NULL);
1748         } else {
1749             if (peer->type == 'U')
1750                 client->replyq = &udp_server_replyq;
1751             else {
1752                 client->replyq = malloc(sizeof(struct replyq));
1753                 if (!client->replyq)
1754                     errx("malloc failed");
1755                 client->replyq->replies = calloc(MAX_REQUESTS, sizeof(struct reply));
1756                 if (!client->replyq->replies)
1757                     errx("malloc failed");
1758                 client->replyq->size = MAX_REQUESTS;
1759                 client->replyq->count = 0;
1760                 pthread_mutex_init(&client->replyq->count_mutex, NULL);
1761                 pthread_cond_init(&client->replyq->count_cond, NULL);
1762             }
1763         }
1764         printf("got type %c, host %s, port %s, secret %s\n", peer->type, peer->host, peer->port, peer->secret);
1765         if (serverfile) {
1766             printf("    with realms:");
1767             for (r = server->realms; *r; r++)
1768                 printf(" %s", *r);
1769             printf("\n");
1770         }
1771         i++;
1772     }
1773     fclose(f);
1774 }
1775
1776 void getmainconfig(const char *configfile) {
1777     FILE *f;
1778     char line[1024];
1779     char *p, *opt, *endopt, *val, *endval;
1780     
1781     f = openconfigfile(configfile);
1782     memset(&options, 0, sizeof(options));
1783
1784     while (fgets(line, 1024, f)) {
1785         for (p = line; *p == ' ' || *p == '\t'; p++);
1786         if (!*p || *p == '#' || *p == '\n')
1787             continue;
1788         opt = p++;
1789         for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1790         endopt = p - 1;
1791         for (; *p == ' ' || *p == '\t'; p++);
1792         if (!*p || *p == '\n') {
1793             endopt[1] = '\0';
1794             printf("error in %s, option %s has no value\n", configfile, opt);
1795             exit(1);
1796         }
1797         val = p;
1798         for (; *p && *p != '\n'; p++)
1799             if (*p != ' ' && *p != '\t')
1800                 endval = p;
1801         endopt[1] = '\0';
1802         endval[1] = '\0';
1803         printf("getmainconfig: %s = %s\n", opt, val);
1804         
1805         if (!strcasecmp(opt, "TLSCACertificateFile")) {
1806             options.tlscacertificatefile = stringcopy(val, 0);
1807             continue;
1808         }
1809         if (!strcasecmp(opt, "TLSCACertificatePath")) {
1810             options.tlscacertificatepath = stringcopy(val, 0);
1811             continue;
1812         }
1813         if (!strcasecmp(opt, "TLSCertificateFile")) {
1814             options.tlscertificatefile = stringcopy(val, 0);
1815             continue;
1816         }
1817         if (!strcasecmp(opt, "TLSCertificateKeyFile")) {
1818             options.tlscertificatekeyfile = stringcopy(val, 0);
1819             continue;
1820         }
1821         if (!strcasecmp(opt, "TLSCertificateKeyPassword")) {
1822             options.tlscertificatekeypassword = stringcopy(val, 0);
1823             continue;
1824         }
1825         if (!strcasecmp(opt, "UDPServerPort")) {
1826             options.udpserverport = stringcopy(val, 0);
1827             continue;
1828         }
1829
1830         printf("error in %s, unknown option %s\n", configfile, opt);
1831         exit(1);
1832     }
1833     fclose(f);
1834
1835     if (!options.udpserverport)
1836         options.udpserverport = stringcopy(DEFAULT_UDP_PORT, 0);
1837 }
1838
1839 #if 0
1840 void parseargs(int argc, char **argv) {
1841     int c;
1842
1843     while ((c = getopt(argc, argv, "p:")) != -1) {
1844         switch (c) {
1845         case 'p':
1846             udp_server_port = optarg;
1847             break;
1848         default:
1849             goto usage;
1850         }
1851     }
1852
1853     return;
1854
1855  usage:
1856     printf("radsecproxy [ -p UDP-port ]\n");
1857     exit(1);
1858 }
1859 #endif
1860
1861 int main(int argc, char **argv) {
1862     pthread_t udpserverth;
1863     /*    pthread_attr_t joinable; */
1864     int i;
1865     
1866     /*    parseargs(argc, argv); */
1867     getmainconfig(CONFIG_MAIN);
1868     getconfig(CONFIG_SERVERS, NULL);
1869     getconfig(NULL, CONFIG_CLIENTS);
1870
1871     /*    pthread_attr_init(&joinable); */
1872     /*    pthread_attr_setdetachstate(&joinable, PTHREAD_CREATE_JOINABLE); */
1873    
1874     if (client_udp_count)
1875         if (pthread_create(&udpserverth, NULL /*&joinable*/, udpserverrd, NULL))
1876             errx("pthread_create failed");
1877
1878     if (client_tls_count || server_tls_count)
1879         ssl_ctx = ssl_init();
1880     
1881     for (i = 0; i < server_count; i++)
1882         if (pthread_create(&servers[i].clientth, NULL, clientwr, (void *)&servers[i]))
1883             errx("pthread_create failed");
1884
1885     if (client_tls_count)
1886         return tlslistener();
1887
1888     /* just hang around doing nothing, anything to do here? */
1889     for (;;)
1890         sleep(1000);
1891 }