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