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