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