2 * Copyright (C) 2006, 2007 Stig Venaas <venaas@uninett.no>
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.
11 * radius keep alives (server status)
12 * setsockopt(keepalive...), check if openssl has some keepalive feature
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
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
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
38 #include <sys/socket.h>
39 #include <netinet/in.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>
52 #include "radsecproxy.h"
54 static struct options options;
55 static struct client *clients;
56 static struct server *servers;
58 static int client_udp_count = 0;
59 static int client_tls_count = 0;
60 static int client_count = 0;
61 static int server_udp_count = 0;
62 static int server_tls_count = 0;
63 static int server_count = 0;
65 static struct peer *tcp_server_listen;
66 static struct peer *udp_server_listen;
67 static struct replyq udp_server_replyq;
68 static int udp_server_sock = -1;
69 static pthread_mutex_t *ssl_locks;
70 static long *ssl_lock_count;
71 static SSL_CTX *ssl_ctx = NULL;
75 /* callbacks for making OpenSSL thread safe */
76 unsigned long ssl_thread_id() {
77 return (unsigned long)pthread_self();
80 void ssl_locking_callback(int mode, int type, const char *file, int line) {
81 if (mode & CRYPTO_LOCK) {
82 pthread_mutex_lock(&ssl_locks[type]);
83 ssl_lock_count[type]++;
85 pthread_mutex_unlock(&ssl_locks[type]);
88 static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) {
89 int pwdlen = strlen(userdata);
90 if (rwflag != 0 || pwdlen > size) /* not for decryption or too large */
92 memcpy(buf, userdata, pwdlen);
96 static int verify_cb(int ok, X509_STORE_CTX *ctx) {
101 err_cert = X509_STORE_CTX_get_current_cert(ctx);
102 err = X509_STORE_CTX_get_error(ctx);
103 depth = X509_STORE_CTX_get_error_depth(ctx);
105 if (depth > MAX_CERT_DEPTH) {
107 err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
108 X509_STORE_CTX_set_error(ctx, err);
112 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
113 printf("verify error: num=%d:%s:depth=%d:%s\n", err, X509_verify_cert_error_string(err), depth, buf);
116 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
117 X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
118 printf("issuer=%s\n", buf);
120 case X509_V_ERR_CERT_NOT_YET_VALID:
121 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
122 printf("Certificate not yet valid\n");
124 case X509_V_ERR_CERT_HAS_EXPIRED:
125 printf("Certificate has expired\n");
127 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
128 printf("Certificate no longer valid (after notAfter)\n");
132 /* printf("certificate verify returns %d\n", ok); */
136 SSL_CTX *ssl_init() {
141 if (!options.tlscertificatefile || !options.tlscertificatekeyfile) {
142 printf("TLSCertificateFile and TLSCertificateKeyFile must be specified for TLS\n");
145 if (!options.tlscacertificatefile && !options.tlscacertificatepath) {
146 printf("CA Certificate file/path need to be configured\n");
150 ssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
151 ssl_lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
152 for (i = 0; i < CRYPTO_num_locks(); i++) {
153 ssl_lock_count[i] = 0;
154 pthread_mutex_init(&ssl_locks[i], NULL);
156 CRYPTO_set_id_callback(ssl_thread_id);
157 CRYPTO_set_locking_callback(ssl_locking_callback);
159 SSL_load_error_strings();
162 while (!RAND_status()) {
163 time_t t = time(NULL);
164 pid_t pid = getpid();
165 RAND_seed((unsigned char *)&t, sizeof(time_t));
166 RAND_seed((unsigned char *)&pid, sizeof(pid));
169 ctx = SSL_CTX_new(TLSv1_method());
170 if (options.tlscertificatekeypassword) {
171 SSL_CTX_set_default_passwd_cb_userdata(ctx, options.tlscertificatekeypassword);
172 SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
174 if (SSL_CTX_use_certificate_chain_file(ctx, options.tlscertificatefile) &&
175 SSL_CTX_use_PrivateKey_file(ctx, options.tlscertificatekeyfile, SSL_FILETYPE_PEM) &&
176 SSL_CTX_check_private_key(ctx) &&
177 SSL_CTX_load_verify_locations(ctx, options.tlscacertificatefile, options.tlscacertificatepath)) {
178 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
179 SSL_CTX_set_verify_depth(ctx, MAX_CERT_DEPTH + 1);
183 while ((error = ERR_get_error()))
184 err("SSL: %s", ERR_error_string(error, NULL));
188 void printauth(char *s, unsigned char *t) {
191 for (i = 0; i < 16; i++)
192 printf("%02x ", t[i]);
196 int resolvepeer(struct peer *peer, int ai_flags) {
197 struct addrinfo hints, *addrinfo;
199 memset(&hints, 0, sizeof(hints));
200 hints.ai_socktype = (peer->type == 'T' ? SOCK_STREAM : SOCK_DGRAM);
201 hints.ai_family = AF_UNSPEC;
202 hints.ai_flags = ai_flags;
203 if (getaddrinfo(peer->host, peer->port, &hints, &addrinfo)) {
204 err("resolvepeer: can't resolve %s port %s", peer->host, peer->port);
209 freeaddrinfo(peer->addrinfo);
210 peer->addrinfo = addrinfo;
214 int connecttoserver(struct addrinfo *addrinfo) {
216 struct addrinfo *res;
218 for (res = addrinfo; res; res = res->ai_next) {
219 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
221 err("connecttoserver: socket failed");
224 if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
226 err("connecttoserver: connect failed");
233 int bindtoaddr(struct addrinfo *addrinfo) {
235 struct addrinfo *res;
237 for (res = addrinfo; res; res = res->ai_next) {
238 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
240 err("bindtoaddr: socket failed");
243 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
244 if (!bind(s, res->ai_addr, res->ai_addrlen))
246 err("bindtoaddr: bind failed");
252 /* returns the client with matching address, or NULL */
253 /* if client argument is not NULL, we only check that one client */
254 struct client *find_client(char type, struct sockaddr *addr, struct client *client) {
255 struct sockaddr_in6 *sa6;
256 struct in_addr *a4 = NULL;
259 struct addrinfo *res;
261 if (addr->sa_family == AF_INET6) {
262 sa6 = (struct sockaddr_in6 *)addr;
263 if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
264 a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12];
266 a4 = &((struct sockaddr_in *)addr)->sin_addr;
268 c = (client ? client : clients);
269 for (i = 0; i < client_count; i++) {
270 if (c->peer.type == type)
271 for (res = c->peer.addrinfo; res; res = res->ai_next)
272 if ((a4 && res->ai_family == AF_INET &&
273 !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) ||
274 (res->ai_family == AF_INET6 &&
275 !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16)))
284 /* returns the server with matching address, or NULL */
285 /* if server argument is not NULL, we only check that one server */
286 struct server *find_server(char type, struct sockaddr *addr, struct server *server) {
287 struct sockaddr_in6 *sa6;
288 struct in_addr *a4 = NULL;
291 struct addrinfo *res;
293 if (addr->sa_family == AF_INET6) {
294 sa6 = (struct sockaddr_in6 *)addr;
295 if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
296 a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12];
298 a4 = &((struct sockaddr_in *)addr)->sin_addr;
300 s = (server ? server : servers);
301 for (i = 0; i < server_count; i++) {
302 if (s->peer.type == type)
303 for (res = s->peer.addrinfo; res; res = res->ai_next)
304 if ((a4 && res->ai_family == AF_INET &&
305 !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) ||
306 (res->ai_family == AF_INET6 &&
307 !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16)))
316 /* exactly one of client and server must be non-NULL */
317 /* if *peer == NULL we return who we received from, else require it to be from peer */
318 /* return from in sa if not NULL */
319 unsigned char *radudpget(int s, struct client **client, struct server **server, struct sockaddr_storage *sa) {
322 unsigned char buf[65536], *rad;
323 struct sockaddr_storage from;
324 socklen_t fromlen = sizeof(from);
327 cnt = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen);
329 err("radudpget: recv failed");
332 printf("radudpget: got %d bytes from %s\n", cnt, addr2string((struct sockaddr *)&from, fromlen));
335 printf("radudpget: packet too small\n");
342 printf("radudpget: packet smaller than length field in radius header\n");
346 printf("radudpget: packet was padded with %d bytes\n", cnt - len);
349 ? (void *)find_client('U', (struct sockaddr *)&from, *client)
350 : (void *)find_server('U', (struct sockaddr *)&from, *server));
352 printf("radudpget: got packet from wrong or unknown UDP peer, ignoring\n");
359 err("radudpget: malloc failed");
361 memcpy(rad, buf, len);
363 *client = (struct client *)f; /* only need this if *client == NULL, but if not NULL *client == f here */
365 *server = (struct server *)f; /* only need this if *server == NULL, but if not NULL *server == f here */
371 int tlsverifycert(struct peer *peer) {
380 if (SSL_get_verify_result(peer->ssl) != X509_V_OK) {
381 printf("tlsverifycert: basic validation failed\n");
382 while ((error = ERR_get_error()))
383 err("clientwr: TLS: %s", ERR_error_string(error, NULL));
387 cert = SSL_get_peer_certificate(peer->ssl);
389 printf("tlsverifycert: failed to obtain certificate\n");
392 nm = X509_get_subject_name(cert);
395 loc = X509_NAME_get_index_by_NID(nm, NID_commonName, loc);
398 e = X509_NAME_get_entry(nm, loc);
399 l = ASN1_STRING_to_UTF8(&v, X509_NAME_ENTRY_get_data(e));
403 for (i = 0; i < l; i++)
406 if (l == strlen(peer->host) && !strncasecmp(peer->host, (char *)v, l)) {
407 printf("tlsverifycert: Found cn matching host %s, All OK\n", peer->host);
410 printf("tlsverifycert: cn not matching host %s\n", peer->host);
416 void tlsconnect(struct server *server, struct timeval *when, char *text) {
420 printf("tlsconnect called from %s\n", text);
421 pthread_mutex_lock(&server->lock);
422 if (when && memcmp(&server->lastconnecttry, when, sizeof(struct timeval))) {
423 /* already reconnected, nothing to do */
424 printf("tlsconnect(%s): seems already reconnected\n", text);
425 pthread_mutex_unlock(&server->lock);
429 printf("tlsconnect %s\n", text);
432 gettimeofday(&now, NULL);
433 elapsed = now.tv_sec - server->lastconnecttry.tv_sec;
434 if (server->connectionok) {
435 server->connectionok = 0;
437 } else if (elapsed < 5)
439 else if (elapsed < 600) {
440 printf("tlsconnect: sleeping %lds\n", elapsed);
442 } else if (elapsed < 1000) {
443 printf("tlsconnect: sleeping %ds\n", 900);
446 server->lastconnecttry.tv_sec = now.tv_sec; /* no sleep at startup */
447 printf("tlsconnect: trying to open TLS connection to %s port %s\n", server->peer.host, server->peer.port);
448 if (server->sock >= 0)
450 if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0)
452 SSL_free(server->peer.ssl);
453 server->peer.ssl = SSL_new(ssl_ctx);
454 SSL_set_fd(server->peer.ssl, server->sock);
455 if (SSL_connect(server->peer.ssl) > 0 && tlsverifycert(&server->peer))
458 printf("tlsconnect: TLS connection to %s port %s up\n", server->peer.host, server->peer.port);
459 gettimeofday(&server->lastconnecttry, NULL);
460 pthread_mutex_unlock(&server->lock);
463 unsigned char *radtlsget(SSL *ssl) {
465 unsigned char buf[4], *rad;
468 for (total = 0; total < 4; total += cnt) {
469 cnt = SSL_read(ssl, buf + total, 4 - total);
471 printf("radtlsget: connection lost\n");
472 if (SSL_get_error(ssl, cnt) == SSL_ERROR_ZERO_RETURN) {
473 /* remote end sent close_notify, send one back */
483 err("radtlsget: malloc failed");
488 for (; total < len; total += cnt) {
489 cnt = SSL_read(ssl, rad + total, len - total);
491 printf("radtlsget: connection lost\n");
492 if (SSL_get_error(ssl, cnt) == SSL_ERROR_ZERO_RETURN) {
493 /* remote end sent close_notify, send one back */
505 printf("radtlsget: packet smaller than minimum radius size\n");
508 printf("radtlsget: got %d bytes\n", total);
512 int clientradput(struct server *server, unsigned char *rad) {
516 struct timeval lastconnecttry;
519 if (server->peer.type == 'U') {
520 if (send(server->sock, rad, len, 0) >= 0) {
521 printf("clienradput: sent UDP of length %d to %s port %s\n", len, server->peer.host, server->peer.port);
524 err("clientradput: send failed");
528 lastconnecttry = server->lastconnecttry;
529 while ((cnt = SSL_write(server->peer.ssl, rad, len)) <= 0) {
530 while ((error = ERR_get_error()))
531 err("clientradput: TLS: %s", ERR_error_string(error, NULL));
532 tlsconnect(server, &lastconnecttry, "clientradput");
533 lastconnecttry = server->lastconnecttry;
536 server->connectionok = 1;
537 printf("clientradput: Sent %d bytes, Radius packet of length %d to TLS peer %s\n",
538 cnt, len, server->peer.host);
542 int radsign(unsigned char *rad, unsigned char *sec) {
543 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
544 static unsigned char first = 1;
545 static EVP_MD_CTX mdctx;
549 pthread_mutex_lock(&lock);
551 EVP_MD_CTX_init(&mdctx);
555 result = (EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) &&
556 EVP_DigestUpdate(&mdctx, rad, RADLEN(rad)) &&
557 EVP_DigestUpdate(&mdctx, sec, strlen((char *)sec)) &&
558 EVP_DigestFinal_ex(&mdctx, rad + 4, &md_len) &&
560 pthread_mutex_unlock(&lock);
564 int validauth(unsigned char *rad, unsigned char *reqauth, unsigned char *sec) {
565 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
566 static unsigned char first = 1;
567 static EVP_MD_CTX mdctx;
568 unsigned char hash[EVP_MAX_MD_SIZE];
572 pthread_mutex_lock(&lock);
574 EVP_MD_CTX_init(&mdctx);
580 result = (EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) &&
581 EVP_DigestUpdate(&mdctx, rad, 4) &&
582 EVP_DigestUpdate(&mdctx, reqauth, 16) &&
583 (len <= 20 || EVP_DigestUpdate(&mdctx, rad + 20, len - 20)) &&
584 EVP_DigestUpdate(&mdctx, sec, strlen((char *)sec)) &&
585 EVP_DigestFinal_ex(&mdctx, hash, &len) &&
587 !memcmp(hash, rad + 4, 16));
588 pthread_mutex_unlock(&lock);
592 int checkmessageauth(unsigned char *rad, uint8_t *authattr, char *secret) {
593 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
594 static unsigned char first = 1;
595 static HMAC_CTX hmacctx;
597 uint8_t auth[16], hash[EVP_MAX_MD_SIZE];
599 pthread_mutex_lock(&lock);
601 HMAC_CTX_init(&hmacctx);
605 memcpy(auth, authattr, 16);
606 memset(authattr, 0, 16);
608 HMAC_Init_ex(&hmacctx, secret, strlen(secret), EVP_md5(), NULL);
609 HMAC_Update(&hmacctx, rad, RADLEN(rad));
610 HMAC_Final(&hmacctx, hash, &md_len);
611 memcpy(authattr, auth, 16);
613 printf("message auth computation failed\n");
614 pthread_mutex_unlock(&lock);
618 if (memcmp(auth, hash, 16)) {
619 printf("message authenticator, wrong value\n");
620 pthread_mutex_unlock(&lock);
624 pthread_mutex_unlock(&lock);
628 int createmessageauth(unsigned char *rad, unsigned char *authattrval, char *secret) {
629 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
630 static unsigned char first = 1;
631 static HMAC_CTX hmacctx;
637 pthread_mutex_lock(&lock);
639 HMAC_CTX_init(&hmacctx);
643 memset(authattrval, 0, 16);
645 HMAC_Init_ex(&hmacctx, secret, strlen(secret), EVP_md5(), NULL);
646 HMAC_Update(&hmacctx, rad, RADLEN(rad));
647 HMAC_Final(&hmacctx, authattrval, &md_len);
649 printf("message auth computation failed\n");
650 pthread_mutex_unlock(&lock);
654 pthread_mutex_unlock(&lock);
658 void sendrq(struct server *to, struct client *from, struct request *rq) {
661 pthread_mutex_lock(&to->newrq_mutex);
662 /* might simplify if only try nextid, might be ok */
663 for (i = to->nextid; i < MAX_REQUESTS; i++)
664 if (!to->requests[i].buf)
666 if (i == MAX_REQUESTS) {
667 for (i = 0; i < to->nextid; i++)
668 if (!to->requests[i].buf)
670 if (i == to->nextid) {
671 printf("No room in queue, dropping request\n");
672 pthread_mutex_unlock(&to->newrq_mutex);
678 rq->buf[1] = (char)i;
679 printf("sendrq: inserting packet with id %d in queue for %s\n", i, to->peer.host);
681 if (!createmessageauth(rq->buf, rq->messageauthattrval, to->peer.secret))
684 to->requests[i] = *rq;
688 printf("signalling client writer\n");
689 pthread_cond_signal(&to->newrq_cond);
691 pthread_mutex_unlock(&to->newrq_mutex);
694 void sendreply(struct client *to, struct server *from, unsigned char *buf, struct sockaddr_storage *tosa) {
695 struct replyq *replyq = to->replyq;
697 pthread_mutex_lock(&replyq->count_mutex);
698 if (replyq->count == replyq->size) {
699 printf("No room in queue, dropping request\n");
700 pthread_mutex_unlock(&replyq->count_mutex);
704 replyq->replies[replyq->count].buf = buf;
706 replyq->replies[replyq->count].tosa = *tosa;
709 if (replyq->count == 1) {
710 printf("signalling client writer\n");
711 pthread_cond_signal(&replyq->count_cond);
713 pthread_mutex_unlock(&replyq->count_mutex);
716 int pwdencrypt(uint8_t *in, uint8_t len, char *shared, uint8_t sharedlen, uint8_t *auth) {
717 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
718 static unsigned char first = 1;
719 static EVP_MD_CTX mdctx;
720 unsigned char hash[EVP_MAX_MD_SIZE], *input;
722 uint8_t i, offset = 0, out[128];
724 pthread_mutex_lock(&lock);
726 EVP_MD_CTX_init(&mdctx);
732 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
733 !EVP_DigestUpdate(&mdctx, (uint8_t *)shared, sharedlen) ||
734 !EVP_DigestUpdate(&mdctx, input, 16) ||
735 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
737 pthread_mutex_unlock(&lock);
740 for (i = 0; i < 16; i++)
741 out[offset + i] = hash[i] ^ in[offset + i];
742 input = out + offset - 16;
747 memcpy(in, out, len);
748 pthread_mutex_unlock(&lock);
752 int pwddecrypt(uint8_t *in, uint8_t len, char *shared, uint8_t sharedlen, uint8_t *auth) {
753 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
754 static unsigned char first = 1;
755 static EVP_MD_CTX mdctx;
756 unsigned char hash[EVP_MAX_MD_SIZE], *input;
758 uint8_t i, offset = 0, out[128];
760 pthread_mutex_lock(&lock);
762 EVP_MD_CTX_init(&mdctx);
768 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
769 !EVP_DigestUpdate(&mdctx, (uint8_t *)shared, sharedlen) ||
770 !EVP_DigestUpdate(&mdctx, input, 16) ||
771 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
773 pthread_mutex_unlock(&lock);
776 for (i = 0; i < 16; i++)
777 out[offset + i] = hash[i] ^ in[offset + i];
783 memcpy(in, out, len);
784 pthread_mutex_unlock(&lock);
788 int msmppencrypt(uint8_t *text, uint8_t len, uint8_t *shared, uint8_t sharedlen, uint8_t *auth, uint8_t *salt) {
789 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
790 static unsigned char first = 1;
791 static EVP_MD_CTX mdctx;
792 unsigned char hash[EVP_MAX_MD_SIZE];
796 pthread_mutex_lock(&lock);
798 EVP_MD_CTX_init(&mdctx);
803 printf("msppencrypt auth in: ");
804 for (i = 0; i < 16; i++)
805 printf("%02x ", auth[i]);
808 printf("msppencrypt salt in: ");
809 for (i = 0; i < 2; i++)
810 printf("%02x ", salt[i]);
813 printf("msppencrypt in: ");
814 for (i = 0; i < len; i++)
815 printf("%02x ", text[i]);
819 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
820 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
821 !EVP_DigestUpdate(&mdctx, auth, 16) ||
822 !EVP_DigestUpdate(&mdctx, salt, 2) ||
823 !EVP_DigestFinal_ex(&mdctx, hash, &md_len)) {
824 pthread_mutex_unlock(&lock);
829 printf("msppencrypt hash: ");
830 for (i = 0; i < 16; i++)
831 printf("%02x ", hash[i]);
835 for (i = 0; i < 16; i++)
838 for (offset = 16; offset < len; offset += 16) {
840 printf("text + offset - 16 c(%d): ", offset / 16);
841 for (i = 0; i < 16; i++)
842 printf("%02x ", (text + offset - 16)[i]);
845 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
846 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
847 !EVP_DigestUpdate(&mdctx, text + offset - 16, 16) ||
848 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
850 pthread_mutex_unlock(&lock);
854 printf("msppencrypt hash: ");
855 for (i = 0; i < 16; i++)
856 printf("%02x ", hash[i]);
860 for (i = 0; i < 16; i++)
861 text[offset + i] ^= hash[i];
865 printf("msppencrypt out: ");
866 for (i = 0; i < len; i++)
867 printf("%02x ", text[i]);
871 pthread_mutex_unlock(&lock);
875 int msmppdecrypt(uint8_t *text, uint8_t len, uint8_t *shared, uint8_t sharedlen, uint8_t *auth, uint8_t *salt) {
876 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
877 static unsigned char first = 1;
878 static EVP_MD_CTX mdctx;
879 unsigned char hash[EVP_MAX_MD_SIZE];
884 pthread_mutex_lock(&lock);
886 EVP_MD_CTX_init(&mdctx);
891 printf("msppdecrypt auth in: ");
892 for (i = 0; i < 16; i++)
893 printf("%02x ", auth[i]);
896 printf("msppedecrypt salt in: ");
897 for (i = 0; i < 2; i++)
898 printf("%02x ", salt[i]);
901 printf("msppedecrypt in: ");
902 for (i = 0; i < len; i++)
903 printf("%02x ", text[i]);
907 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
908 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
909 !EVP_DigestUpdate(&mdctx, auth, 16) ||
910 !EVP_DigestUpdate(&mdctx, salt, 2) ||
911 !EVP_DigestFinal_ex(&mdctx, hash, &md_len)) {
912 pthread_mutex_unlock(&lock);
917 printf("msppedecrypt hash: ");
918 for (i = 0; i < 16; i++)
919 printf("%02x ", hash[i]);
923 for (i = 0; i < 16; i++)
924 plain[i] = text[i] ^ hash[i];
926 for (offset = 16; offset < len; offset += 16) {
928 printf("text + offset - 16 c(%d): ", offset / 16);
929 for (i = 0; i < 16; i++)
930 printf("%02x ", (text + offset - 16)[i]);
933 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
934 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
935 !EVP_DigestUpdate(&mdctx, text + offset - 16, 16) ||
936 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
938 pthread_mutex_unlock(&lock);
942 printf("msppedecrypt hash: ");
943 for (i = 0; i < 16; i++)
944 printf("%02x ", hash[i]);
948 for (i = 0; i < 16; i++)
949 plain[offset + i] = text[offset + i] ^ hash[i];
952 memcpy(text, plain, len);
954 printf("msppedecrypt out: ");
955 for (i = 0; i < len; i++)
956 printf("%02x ", text[i]);
960 pthread_mutex_unlock(&lock);
964 struct server *id2server(char *id, uint8_t len) {
966 char **realm, *idrealm;
968 idrealm = strchr(id, '@');
976 for (i = 0; i < server_count; i++) {
977 for (realm = servers[i].realms; *realm; realm++) {
978 if ((strlen(*realm) == 1 && **realm == '*') ||
979 (strlen(*realm) == len && !memcmp(idrealm, *realm, len))) {
980 printf("found matching realm: %s, host %s\n", *realm, servers[i].peer.host);
988 int rqinqueue(struct server *to, struct client *from, uint8_t id) {
991 pthread_mutex_lock(&to->newrq_mutex);
992 for (i = 0; i < MAX_REQUESTS; i++)
993 if (to->requests[i].buf && to->requests[i].origid == id && to->requests[i].from == from)
995 pthread_mutex_unlock(&to->newrq_mutex);
997 return i < MAX_REQUESTS;
1000 struct server *radsrv(struct request *rq, unsigned char *buf, struct client *from) {
1001 uint8_t code, id, *auth, *attr, attrvallen;
1002 uint8_t *usernameattr = NULL, *userpwdattr = NULL, *tunnelpwdattr = NULL, *messageauthattr = NULL;
1007 unsigned char newauth[16];
1009 code = *(uint8_t *)buf;
1010 id = *(uint8_t *)(buf + 1);
1012 auth = (uint8_t *)(buf + 4);
1014 printf("radsrv: code %d, id %d, length %d\n", code, id, len);
1016 if (code != RAD_Access_Request) {
1017 printf("radsrv: server currently accepts only access-requests, ignoring\n");
1025 left -= attr[RAD_Attr_Length];
1027 printf("radsrv: attribute length exceeds packet length, ignoring packet\n");
1030 switch (attr[RAD_Attr_Type]) {
1031 case RAD_Attr_User_Name:
1032 usernameattr = attr;
1034 case RAD_Attr_User_Password:
1037 case RAD_Attr_Tunnel_Password:
1038 tunnelpwdattr = attr;
1040 case RAD_Attr_Message_Authenticator:
1041 messageauthattr = attr;
1044 attr += attr[RAD_Attr_Length];
1047 printf("radsrv: malformed packet? remaining byte after last attribute\n");
1050 printf("radsrv: Username: ");
1051 for (i = 0; i < usernameattr[RAD_Attr_Length] - 2; i++)
1052 printf("%c", usernameattr[RAD_Attr_Value + i]);
1056 to = id2server((char *)&usernameattr[RAD_Attr_Value], usernameattr[RAD_Attr_Length] - 2);
1058 printf("radsrv: ignoring request, don't know where to send it\n");
1062 if (rqinqueue(to, from, id)) {
1063 printf("radsrv: ignoring request from host %s with id %d, already got one\n", from->peer.host, id);
1067 if (messageauthattr && (messageauthattr[RAD_Attr_Length] != 18 ||
1068 !checkmessageauth(buf, &messageauthattr[RAD_Attr_Value], from->peer.secret))) {
1069 printf("radsrv: message authentication failed\n");
1073 if (!RAND_bytes(newauth, 16)) {
1074 printf("radsrv: failed to generate random auth\n");
1078 printauth("auth", auth);
1079 printauth("newauth", newauth);
1082 printf("radsrv: found userpwdattr of length %d\n", userpwdattr[RAD_Attr_Length]);
1083 attrvallen = userpwdattr[RAD_Attr_Length] - 2;
1084 if (attrvallen < 16 || attrvallen > 128 || attrvallen % 16) {
1085 printf("radsrv: invalid user password length\n");
1089 if (!pwddecrypt(&userpwdattr[RAD_Attr_Value], attrvallen, from->peer.secret, strlen(from->peer.secret), auth)) {
1090 printf("radsrv: cannot decrypt password\n");
1093 printf("radsrv: password: ");
1094 for (i = 0; i < attrvallen; i++)
1095 printf("%02x ", userpwdattr[RAD_Attr_Value + i]);
1097 if (!pwdencrypt(&userpwdattr[RAD_Attr_Value], attrvallen, to->peer.secret, strlen(to->peer.secret), newauth)) {
1098 printf("radsrv: cannot encrypt password\n");
1103 if (tunnelpwdattr) {
1104 printf("radsrv: found tunnelpwdattr of length %d\n", tunnelpwdattr[RAD_Attr_Length]);
1105 attrvallen = tunnelpwdattr[RAD_Attr_Length] - 2;
1106 if (attrvallen < 16 || attrvallen > 128 || attrvallen % 16) {
1107 printf("radsrv: invalid user password length\n");
1111 if (!pwddecrypt(&tunnelpwdattr[RAD_Attr_Value], attrvallen, from->peer.secret, strlen(from->peer.secret), auth)) {
1112 printf("radsrv: cannot decrypt password\n");
1115 printf("radsrv: password: ");
1116 for (i = 0; i < attrvallen; i++)
1117 printf("%02x ", tunnelpwdattr[RAD_Attr_Value + i]);
1119 if (!pwdencrypt(&tunnelpwdattr[RAD_Attr_Value], attrvallen, to->peer.secret, strlen(to->peer.secret), newauth)) {
1120 printf("radsrv: cannot encrypt password\n");
1128 rq->messageauthattrval = (messageauthattr ? &messageauthattr[RAD_Attr_Value] : NULL);
1129 memcpy(rq->origauth, auth, 16);
1130 memcpy(auth, newauth, 16);
1131 printauth("rq->origauth", (unsigned char *)rq->origauth);
1132 printauth("auth", auth);
1136 void *clientrd(void *arg) {
1137 struct server *server = (struct server *)arg;
1138 struct client *from;
1139 int i, left, subleft;
1140 unsigned char *buf, *messageauthattr, *subattr, *attr;
1141 struct sockaddr_storage fromsa;
1142 struct timeval lastconnecttry;
1147 lastconnecttry = server->lastconnecttry;
1148 buf = (server->peer.type == 'U' ? radudpget(server->sock, NULL, &server, NULL) : radtlsget(server->peer.ssl));
1149 if (!buf && server->peer.type == 'T') {
1150 tlsconnect(server, &lastconnecttry, "clientrd");
1154 server->connectionok = 1;
1156 if (*buf != RAD_Access_Accept && *buf != RAD_Access_Reject && *buf != RAD_Access_Challenge) {
1157 printf("clientrd: discarding, only accept access accept, access reject and access challenge messages\n");
1161 printf("got message type: %d, id: %d\n", buf[0], buf[1]);
1163 i = buf[1]; /* i is the id */
1165 pthread_mutex_lock(&server->newrq_mutex);
1166 if (!server->requests[i].buf || !server->requests[i].tries) {
1167 pthread_mutex_unlock(&server->newrq_mutex);
1168 printf("clientrd: no matching request sent with this id, ignoring\n");
1172 if (server->requests[i].received) {
1173 pthread_mutex_unlock(&server->newrq_mutex);
1174 printf("clientrd: already received, ignoring\n");
1178 if (!validauth(buf, server->requests[i].buf + 4, (unsigned char *)server->peer.secret)) {
1179 pthread_mutex_unlock(&server->newrq_mutex);
1180 printf("clientrd: invalid auth, ignoring\n");
1184 from = server->requests[i].from;
1186 /* messageauthattr present? */
1187 messageauthattr = NULL;
1188 left = RADLEN(buf) - 20;
1191 left -= attr[RAD_Attr_Length];
1193 printf("clientrd: attribute length exceeds packet length, ignoring packet\n");
1196 if (attr[RAD_Attr_Type] == RAD_Attr_Message_Authenticator) {
1197 if (attr[RAD_Attr_Length] != 18) {
1198 printf("clientrd: illegal message auth attribute length, ignoring packet\n");
1201 memcpy(tmp, buf + 4, 16);
1202 memcpy(buf + 4, server->requests[i].buf + 4, 16);
1203 if (!checkmessageauth(buf, &attr[RAD_Attr_Value], server->peer.secret)) {
1204 printf("clientrd: message authentication failed\n");
1207 memcpy(buf + 4, tmp, 16);
1208 printf("clientrd: message auth ok\n");
1209 messageauthattr = attr;
1212 attr += attr[RAD_Attr_Length];
1215 /* handle MS MPPE */
1216 left = RADLEN(buf) - 20;
1219 left -= attr[RAD_Attr_Length];
1221 printf("clientrd: attribute length exceeds packet length, ignoring packet\n");
1224 if (attr[RAD_Attr_Type] == RAD_Attr_Vendor_Specific &&
1225 ((uint16_t *)attr)[1] == 0 && ntohs(((uint16_t *)attr)[2]) == 311) { /* 311 == MS */
1226 subleft = attr[RAD_Attr_Length] - 6;
1228 while (subleft > 1) {
1229 subleft -= subattr[RAD_Attr_Length];
1232 if (subattr[RAD_Attr_Type] != RAD_VS_ATTR_MS_MPPE_Send_Key &&
1233 subattr[RAD_Attr_Type] != RAD_VS_ATTR_MS_MPPE_Recv_Key)
1235 printf("clientrd: Got MS MPPE\n");
1236 if (subattr[RAD_Attr_Length] < 20)
1239 if (!msmppdecrypt(subattr + 4, subattr[RAD_Attr_Length] - 4, (unsigned char *)server->peer.secret,
1240 strlen(server->peer.secret), server->requests[i].buf + 4, subattr + 2)) {
1241 printf("clientrd: failed to decrypt msppe key\n");
1245 if (!msmppencrypt(subattr + 4, subattr[RAD_Attr_Length] - 4, (unsigned char *)from->peer.secret,
1246 strlen(from->peer.secret), (unsigned char *)server->requests[i].origauth, subattr + 2)) {
1247 printf("clientrd: failed to encrypt msppe key\n");
1252 printf("clientrd: bad vendor specific attr or subattr length, ignoring packet\n");
1256 attr += attr[RAD_Attr_Length];
1259 /* once we set received = 1, requests[i] may be reused */
1260 buf[1] = (char)server->requests[i].origid;
1261 memcpy(buf + 4, server->requests[i].origauth, 16);
1262 printauth("origauth/buf+4", buf + 4);
1263 if (messageauthattr) {
1264 if (!createmessageauth(buf, &messageauthattr[RAD_Attr_Value], from->peer.secret))
1266 printf("clientrd: computed messageauthattr\n");
1269 if (from->peer.type == 'U')
1270 fromsa = server->requests[i].fromsa;
1271 server->requests[i].received = 1;
1272 pthread_mutex_unlock(&server->newrq_mutex);
1274 if (!radsign(buf, (unsigned char *)from->peer.secret)) {
1275 printf("clientrd: failed to sign message\n");
1278 printauth("signedorigauth/buf+4", buf + 4);
1279 printf("clientrd: giving packet back to where it came from\n");
1280 sendreply(from, server, buf, from->peer.type == 'U' ? &fromsa : NULL);
1284 void *clientwr(void *arg) {
1285 struct server *server = (struct server *)arg;
1287 pthread_t clientrdth;
1290 struct timeval now, lastsend;
1291 struct timespec timeout;
1293 memset(&lastsend, 0, sizeof(struct timeval));
1294 memset(&timeout, 0, sizeof(struct timespec));
1296 if (server->peer.type == 'U') {
1297 if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0) {
1298 printf("clientwr: connecttoserver failed\n");
1302 tlsconnect(server, NULL, "new client");
1304 if (pthread_create(&clientrdth, NULL, clientrd, (void *)server))
1305 errx("clientwr: pthread_create failed");
1308 pthread_mutex_lock(&server->newrq_mutex);
1309 if (!server->newrq) {
1310 gettimeofday(&now, NULL);
1311 if (timeout.tv_sec) {
1312 printf("clientwr: waiting up to %ld secs for new request\n", timeout.tv_sec - now.tv_sec);
1313 pthread_cond_timedwait(&server->newrq_cond, &server->newrq_mutex, &timeout);
1315 } else if (options.statusserver) {
1316 timeout.tv_sec = now.tv_sec + STATUS_SERVER_PERIOD;
1317 /* add random 0-7 seconds to timeout */
1318 RAND_bytes(&rnd, 1);
1319 timeout.tv_sec += rnd / 32;
1320 pthread_cond_timedwait(&server->newrq_cond, &server->newrq_mutex, &timeout);
1323 printf("clientwr: waiting for new request\n");
1324 pthread_cond_wait(&server->newrq_cond, &server->newrq_mutex);
1327 if (server->newrq) {
1328 printf("clientwr: got new request\n");
1331 printf("clientwr: request timer expired, processing request queue\n");
1332 pthread_mutex_unlock(&server->newrq_mutex);
1334 for (i = 0; i < MAX_REQUESTS; i++) {
1335 pthread_mutex_lock(&server->newrq_mutex);
1336 while (!server->requests[i].buf && i < MAX_REQUESTS)
1338 if (i == MAX_REQUESTS) {
1339 pthread_mutex_unlock(&server->newrq_mutex);
1342 rq = server->requests + i;
1345 printf("clientwr: removing received packet from queue\n");
1347 /* setting this to NULL means that it can be reused */
1349 pthread_mutex_unlock(&server->newrq_mutex);
1353 gettimeofday(&now, NULL);
1354 if (now.tv_sec <= rq->expiry.tv_sec) {
1355 if (!timeout.tv_sec || rq->expiry.tv_sec < timeout.tv_sec)
1356 timeout.tv_sec = rq->expiry.tv_sec;
1357 pthread_mutex_unlock(&server->newrq_mutex);
1361 if (rq->tries == (server->peer.type == 'T' ? 1 : REQUEST_RETRIES)) {
1362 printf("clientwr: removing expired packet from queue\n");
1364 /* setting this to NULL means that it can be reused */
1366 pthread_mutex_unlock(&server->newrq_mutex);
1369 pthread_mutex_unlock(&server->newrq_mutex);
1371 rq->expiry.tv_sec = now.tv_sec +
1372 (server->peer.type == 'T' ? REQUEST_EXPIRY : REQUEST_EXPIRY / REQUEST_RETRIES);
1373 if (!timeout.tv_sec || rq->expiry.tv_sec < timeout.tv_sec)
1374 timeout.tv_sec = rq->expiry.tv_sec;
1376 clientradput(server, server->requests[i].buf);
1377 gettimeofday(&lastsend, NULL);
1380 if (options.statusserver) {
1381 gettimeofday(&now, NULL);
1382 if (now.tv_sec - lastsend.tv_sec >= STATUS_SERVER_PERIOD) {
1383 lastsend.tv_sec = now.tv_sec;
1384 printf("clientwr: should send status to %s here\n", server->peer.host);
1390 void *udpserverwr(void *arg) {
1391 struct replyq *replyq = &udp_server_replyq;
1392 struct reply *reply = replyq->replies;
1394 pthread_mutex_lock(&replyq->count_mutex);
1396 while (!replyq->count) {
1397 printf("udp server writer, waiting for signal\n");
1398 pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex);
1399 printf("udp server writer, got signal\n");
1401 pthread_mutex_unlock(&replyq->count_mutex);
1403 if (sendto(udp_server_sock, reply->buf, RADLEN(reply->buf), 0,
1404 (struct sockaddr *)&reply->tosa, SOCKADDR_SIZE(reply->tosa)) < 0)
1405 err("sendudp: send failed");
1408 pthread_mutex_lock(&replyq->count_mutex);
1410 memmove(replyq->replies, replyq->replies + 1,
1411 replyq->count * sizeof(struct reply));
1415 void *udpserverrd(void *arg) {
1420 pthread_t udpserverwrth;
1422 if ((udp_server_sock = bindtoaddr(udp_server_listen->addrinfo)) < 0) {
1423 printf("udpserverrd: socket/bind failed\n");
1426 printf("udpserverrd: listening for UDP on %s:%s\n",
1427 udp_server_listen->host ? udp_server_listen->host : "*", udp_server_listen->port);
1429 if (pthread_create(&udpserverwrth, NULL, udpserverwr, NULL))
1430 errx("pthread_create failed");
1434 memset(&rq, 0, sizeof(struct request));
1435 buf = radudpget(udp_server_sock, &fr, NULL, &rq.fromsa);
1436 to = radsrv(&rq, buf, fr);
1438 printf("udpserverrd: ignoring request, no place to send it\n");
1441 sendrq(to, fr, &rq);
1445 void *tlsserverwr(void *arg) {
1447 unsigned long error;
1448 struct client *client = (struct client *)arg;
1449 struct replyq *replyq;
1451 printf("tlsserverwr starting for %s\n", client->peer.host);
1452 replyq = client->replyq;
1453 pthread_mutex_lock(&replyq->count_mutex);
1455 while (!replyq->count) {
1456 if (client->peer.ssl) {
1457 printf("tls server writer, waiting for signal\n");
1458 pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex);
1459 printf("tls server writer, got signal\n");
1461 if (!client->peer.ssl) {
1462 /* ssl might have changed while waiting */
1463 pthread_mutex_unlock(&replyq->count_mutex);
1464 printf("tlsserverwr: exiting as requested\n");
1468 pthread_mutex_unlock(&replyq->count_mutex);
1469 cnt = SSL_write(client->peer.ssl, replyq->replies->buf, RADLEN(replyq->replies->buf));
1471 printf("tlsserverwr: Sent %d bytes, Radius packet of length %d\n",
1472 cnt, RADLEN(replyq->replies->buf));
1474 while ((error = ERR_get_error()))
1475 err("tlsserverwr: SSL: %s", ERR_error_string(error, NULL));
1476 free(replyq->replies->buf);
1478 pthread_mutex_lock(&replyq->count_mutex);
1480 memmove(replyq->replies, replyq->replies + 1, replyq->count * sizeof(struct reply));
1484 void *tlsserverrd(void *arg) {
1487 unsigned long error;
1490 struct client *client = (struct client *)arg;
1491 pthread_t tlsserverwrth;
1494 printf("tlsserverrd starting for %s\n", client->peer.host);
1495 ssl = client->peer.ssl;
1497 if (SSL_accept(ssl) <= 0) {
1498 while ((error = ERR_get_error()))
1499 err("tlsserverrd: SSL: %s", ERR_error_string(error, NULL));
1500 printf("SSL_accept failed\n");
1503 if (tlsverifycert(&client->peer)) {
1504 if (pthread_create(&tlsserverwrth, NULL, tlsserverwr, (void *)client)) {
1505 err("pthread_create failed");
1509 buf = radtlsget(client->peer.ssl);
1512 printf("tlsserverrd: got Radius message from %s\n", client->peer.host);
1513 memset(&rq, 0, sizeof(struct request));
1514 to = radsrv(&rq, buf, client);
1516 printf("ignoring request, no place to send it\n");
1519 sendrq(to, client, &rq);
1521 printf("tlsserverrd: connection lost\n");
1522 /* stop writer by setting peer.ssl to NULL and give signal in case waiting for data */
1523 client->peer.ssl = NULL;
1524 pthread_mutex_lock(&client->replyq->count_mutex);
1525 pthread_cond_signal(&client->replyq->count_cond);
1526 pthread_mutex_unlock(&client->replyq->count_mutex);
1527 printf("tlsserverrd: waiting for writer to end\n");
1528 pthread_join(tlsserverwrth, NULL);
1532 s = SSL_get_fd(ssl);
1534 shutdown(s, SHUT_RDWR);
1536 printf("tlsserverrd thread for %s exiting\n", client->peer.host);
1537 client->peer.ssl = NULL;
1542 pthread_t tlsserverth;
1544 struct sockaddr_storage from;
1545 size_t fromlen = sizeof(from);
1546 struct client *client;
1548 if ((s = bindtoaddr(tcp_server_listen->addrinfo)) < 0) {
1549 printf("tlslistener: socket/bind failed\n");
1554 printf("listening for incoming TCP on %s:%s\n",
1555 tcp_server_listen->host ? tcp_server_listen->host : "*", tcp_server_listen->port);
1558 snew = accept(s, (struct sockaddr *)&from, &fromlen);
1560 err("accept failed");
1563 printf("incoming TLS connection from %s\n", addr2string((struct sockaddr *)&from, fromlen));
1565 client = find_client('T', (struct sockaddr *)&from, NULL);
1567 printf("ignoring request, not a known TLS client\n");
1568 shutdown(snew, SHUT_RDWR);
1573 if (client->peer.ssl) {
1574 printf("Ignoring incoming connection, already have one from this client\n");
1575 shutdown(snew, SHUT_RDWR);
1579 client->peer.ssl = SSL_new(ssl_ctx);
1580 SSL_set_fd(client->peer.ssl, snew);
1581 if (pthread_create(&tlsserverth, NULL, tlsserverrd, (void *)client)) {
1582 err("pthread_create failed");
1583 SSL_free(client->peer.ssl);
1584 shutdown(snew, SHUT_RDWR);
1586 client->peer.ssl = NULL;
1589 pthread_detach(tlsserverth);
1594 char *parsehostport(char *s, struct peer *peer) {
1599 /* allow literal addresses and port, e.g. [2001:db8::1]:1812 */
1603 for (; *p && *p != ']' && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1605 printf("no ] matching initial [\n");
1611 for (; *p && *p != ':' && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1614 printf("missing host/address\n");
1617 peer->host = stringcopy(field, p - field);
1620 if (*p && *p != ':' && *p != ' ' && *p != '\t' && *p != '\n') {
1621 printf("unexpected character after ]\n");
1626 /* port number or service name is specified */;
1628 for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1630 printf("syntax error, : but no following port\n");
1633 peer->port = stringcopy(field, p - field);
1635 peer->port = stringcopy(peer->type == 'U' ? DEFAULT_UDP_PORT : DEFAULT_TLS_PORT, 0);
1639 /* * is default, else longest match ... ";" used for separator */
1640 char *parserealmlist(char *s, struct server *server) {
1644 for (p = s, n = 1; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++)
1649 printf("realm list must be specified\n");
1652 server->realmdata = stringcopy(s, l);
1653 server->realms = malloc((1+n) * sizeof(char *));
1654 if (!server->realms)
1655 errx("malloc failed");
1656 server->realms[0] = server->realmdata;
1657 for (n = 1, i = 0; i < l; i++)
1658 if (server->realmdata[i] == ';') {
1659 server->realmdata[i] = '\0';
1660 server->realms[n++] = server->realmdata + i + 1;
1662 server->realms[n] = NULL;
1666 FILE *openconfigfile(const char *filename) {
1668 char pathname[100], *base;
1670 f = fopen(filename, "r");
1672 printf("reading config file %s\n", filename);
1676 if (strlen(filename) + 1 <= sizeof(pathname)) {
1677 /* basename() might modify the string */
1678 strcpy(pathname, filename);
1679 base = basename(pathname);
1680 f = fopen(base, "r");
1684 debug(DBG_ERR, "could not read config file %s nor %s\n%s", filename, base, strerror(errno));
1686 debug(DBG_INFO, "reading config file %s", base);
1690 /* exactly one argument must be non-NULL */
1691 void getconfig(const char *serverfile, const char *clientfile) {
1694 char *p, *field, **r;
1695 struct client *client;
1696 struct server *server;
1698 int i, count, *ucount, *tcount;
1700 f = openconfigfile(serverfile ? serverfile : clientfile);
1702 ucount = &server_udp_count;
1703 tcount = &server_tls_count;
1705 ucount = &client_udp_count;
1706 tcount = &client_tls_count;
1708 while (fgets(line, 1024, f)) {
1709 for (p = line; *p == ' ' || *p == '\t'; p++);
1721 debug(DBG_ERR, "type must be U or T, got %c", *p);
1726 count = server_count = server_udp_count + server_tls_count;
1727 servers = calloc(count, sizeof(struct server));
1729 debug(DBG_ERR, "malloc failed");
1731 count = client_count = client_udp_count + client_tls_count;
1732 clients = calloc(count, sizeof(struct client));
1734 debug(DBG_ERR, "malloc failed");
1737 if (client_udp_count) {
1738 udp_server_replyq.replies = malloc(client_udp_count * MAX_REQUESTS * sizeof(struct reply));
1739 if (!udp_server_replyq.replies)
1740 debug(DBG_ERR, "malloc failed");
1741 udp_server_replyq.size = client_udp_count * MAX_REQUESTS;
1742 udp_server_replyq.count = 0;
1743 pthread_mutex_init(&udp_server_replyq.count_mutex, NULL);
1744 pthread_cond_init(&udp_server_replyq.count_cond, NULL);
1748 for (i = 0; i < count && fgets(line, 1024, f);) {
1750 server = &servers[i];
1751 peer = &server->peer;
1753 client = &clients[i];
1754 peer = &client->peer;
1756 for (p = line; *p == ' ' || *p == '\t'; p++);
1757 if (*p == '#' || *p == '\n')
1759 peer->type = *p; /* we already know it must be U or T */
1760 for (p++; *p == ' ' || *p == '\t'; p++);
1761 p = parsehostport(p, peer);
1762 for (; *p == ' ' || *p == '\t'; p++);
1764 p = parserealmlist(p, server);
1765 for (; *p == ' ' || *p == '\t'; p++);
1768 for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1770 /* no secret set and end of line, line is complete if TLS */
1771 if (peer->type == 'U')
1772 debug(DBG_ERR, "secret must be specified for UDP");
1773 peer->secret = stringcopy(DEFAULT_TLS_SECRET, 0);
1775 peer->secret = stringcopy(field, p - field);
1776 /* check that rest of line only white space */
1777 for (; *p == ' ' || *p == '\t'; p++);
1778 if (*p && *p != '\n')
1779 debug(DBG_ERR, "max 4 fields per line, found a 5th");
1782 if ((serverfile && !resolvepeer(&server->peer, 0)) ||
1783 (clientfile && !resolvepeer(&client->peer, 0)))
1784 debug(DBG_ERR, "failed to resolve host %s port %s, exiting", peer->host, peer->port);
1787 pthread_mutex_init(&server->lock, NULL);
1789 server->requests = calloc(MAX_REQUESTS, sizeof(struct request));
1790 if (!server->requests)
1791 debug(DBG_ERR, "malloc failed");
1793 pthread_mutex_init(&server->newrq_mutex, NULL);
1794 pthread_cond_init(&server->newrq_cond, NULL);
1796 if (peer->type == 'U')
1797 client->replyq = &udp_server_replyq;
1799 client->replyq = malloc(sizeof(struct replyq));
1800 if (!client->replyq)
1801 debug(DBG_ERR, "malloc failed");
1802 client->replyq->replies = calloc(MAX_REQUESTS, sizeof(struct reply));
1803 if (!client->replyq->replies)
1804 debug(DBG_ERR, "malloc failed");
1805 client->replyq->size = MAX_REQUESTS;
1806 client->replyq->count = 0;
1807 pthread_mutex_init(&client->replyq->count_mutex, NULL);
1808 pthread_cond_init(&client->replyq->count_cond, NULL);
1811 debug(DBG_INFO, "got type %c, host %s, port %s, secret %s", peer->type, peer->host, peer->port, peer->secret);
1813 debug(DBG_INFO, " with realms:");
1814 for (r = server->realms; *r; r++)
1815 debug(DBG_INFO, "\t%s", *r);
1822 struct peer *server_create(char type) {
1823 struct peer *server;
1826 server = malloc(sizeof(struct peer));
1828 errx("malloc failed");
1829 memset(server, 0, sizeof(struct peer));
1830 server->type = type;
1831 conf = (type == 'T' ? options.listentcp : options.listenudp);
1833 parsehostport(conf, server);
1834 if (!strcmp(server->host, "*")) {
1836 server->host = NULL;
1839 server->port = stringcopy(type == 'T' ? DEFAULT_TLS_PORT : DEFAULT_UDP_PORT, 0);
1840 if (!resolvepeer(server, AI_PASSIVE)) {
1841 printf("failed to resolve host %s port %s, exiting\n", server->host, server->port);
1847 void getmainconfig(const char *configfile) {
1850 char *p, *opt, *endopt, *val, *endval;
1852 f = openconfigfile(configfile);
1853 memset(&options, 0, sizeof(options));
1855 while (fgets(line, 1024, f)) {
1856 for (p = line; *p == ' ' || *p == '\t'; p++);
1857 if (!*p || *p == '#' || *p == '\n')
1860 for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1862 for (; *p == ' ' || *p == '\t'; p++);
1863 if (!*p || *p == '\n') {
1865 debug(DBG_ERR, "error in %s, option %s has no value", configfile, opt);
1868 for (; *p && *p != '\n'; p++)
1869 if (*p != ' ' && *p != '\t')
1873 debug(DBG_INFO, "getmainconfig: %s = %s", opt, val);
1875 if (!strcasecmp(opt, "TLSCACertificateFile")) {
1876 options.tlscacertificatefile = stringcopy(val, 0);
1879 if (!strcasecmp(opt, "TLSCACertificatePath")) {
1880 options.tlscacertificatepath = stringcopy(val, 0);
1883 if (!strcasecmp(opt, "TLSCertificateFile")) {
1884 options.tlscertificatefile = stringcopy(val, 0);
1887 if (!strcasecmp(opt, "TLSCertificateKeyFile")) {
1888 options.tlscertificatekeyfile = stringcopy(val, 0);
1891 if (!strcasecmp(opt, "TLSCertificateKeyPassword")) {
1892 options.tlscertificatekeypassword = stringcopy(val, 0);
1895 if (!strcasecmp(opt, "ListenUDP")) {
1896 options.listenudp = stringcopy(val, 0);
1899 if (!strcasecmp(opt, "ListenTCP")) {
1900 options.listentcp = stringcopy(val, 0);
1903 if (!strcasecmp(opt, "StatusServer")) {
1904 if (!strcasecmp(val, "on"))
1905 options.statusserver = 1;
1906 else if (strcasecmp(val, "off")) {
1907 debug(DBG_ERR, "error in %s, value of option %s is %s, must be on or off", configfile, opt, val);
1911 debug(DBG_ERR, "error in %s, unknown option %s", configfile, opt);
1916 int main(int argc, char **argv) {
1917 pthread_t udpserverth;
1920 debug_set_level(DEBUG_LEVEL);
1921 getmainconfig(CONFIG_MAIN);
1922 getconfig(CONFIG_SERVERS, NULL);
1923 getconfig(NULL, CONFIG_CLIENTS);
1925 if (client_udp_count) {
1926 udp_server_listen = server_create('U');
1927 if (pthread_create(&udpserverth, NULL, udpserverrd, NULL))
1928 debug(DBG_ERR, "pthread_create failed");
1931 if (client_tls_count || server_tls_count)
1932 ssl_ctx = ssl_init();
1934 for (i = 0; i < server_count; i++)
1935 if (pthread_create(&servers[i].clientth, NULL, clientwr, (void *)&servers[i]))
1936 debug(DBG_ERR, "pthread_create failed");
1938 if (client_tls_count) {
1939 tcp_server_listen = server_create('T');
1940 return tlslistener();
1943 /* just hang around doing nothing, anything to do here? */