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