2 * Copyright (C) 2006 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>
51 #include "radsecproxy.h"
53 static struct options options;
54 static struct client *clients;
55 static struct server *servers;
57 static int client_udp_count = 0;
58 static int client_tls_count = 0;
59 static int client_count = 0;
60 static int server_udp_count = 0;
61 static int server_tls_count = 0;
62 static int server_count = 0;
64 static struct peer *tcp_server_listen;
65 static struct peer *udp_server_listen;
66 static struct replyq udp_server_replyq;
67 static int udp_server_sock = -1;
68 static pthread_mutex_t *ssl_locks;
69 static long *ssl_lock_count;
70 static SSL_CTX *ssl_ctx = NULL;
74 /* callbacks for making OpenSSL thread safe */
75 unsigned long ssl_thread_id() {
76 return (unsigned long)pthread_self();
79 void ssl_locking_callback(int mode, int type, const char *file, int line) {
80 if (mode & CRYPTO_LOCK) {
81 pthread_mutex_lock(&ssl_locks[type]);
82 ssl_lock_count[type]++;
84 pthread_mutex_unlock(&ssl_locks[type]);
87 static int pem_passwd_cb(char *buf, int size, int rwflag, void *userdata) {
88 int pwdlen = strlen(userdata);
89 if (rwflag != 0 || pwdlen > size) /* not for decryption or too large */
91 memcpy(buf, userdata, pwdlen);
95 static int verify_cb(int ok, X509_STORE_CTX *ctx) {
100 err_cert = X509_STORE_CTX_get_current_cert(ctx);
101 err = X509_STORE_CTX_get_error(ctx);
102 depth = X509_STORE_CTX_get_error_depth(ctx);
104 if (depth > MAX_CERT_DEPTH) {
106 err = X509_V_ERR_CERT_CHAIN_TOO_LONG;
107 X509_STORE_CTX_set_error(ctx, err);
111 X509_NAME_oneline(X509_get_subject_name(err_cert), buf, 256);
112 printf("verify error: num=%d:%s:depth=%d:%s\n", err, X509_verify_cert_error_string(err), depth, buf);
115 case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT:
116 X509_NAME_oneline(X509_get_issuer_name(ctx->current_cert), buf, 256);
117 printf("issuer=%s\n", buf);
119 case X509_V_ERR_CERT_NOT_YET_VALID:
120 case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD:
121 printf("Certificate not yet valid\n");
123 case X509_V_ERR_CERT_HAS_EXPIRED:
124 printf("Certificate has expired\n");
126 case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD:
127 printf("Certificate no longer valid (after notAfter)\n");
131 /* printf("certificate verify returns %d\n", ok); */
135 SSL_CTX *ssl_init() {
140 if (!options.tlscertificatefile || !options.tlscertificatekeyfile) {
141 printf("TLSCertificateFile and TLSCertificateKeyFile must be specified for TLS\n");
144 if (!options.tlscacertificatefile && !options.tlscacertificatepath) {
145 printf("CA Certificate file/path need to be configured\n");
149 ssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
150 ssl_lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
151 for (i = 0; i < CRYPTO_num_locks(); i++) {
152 ssl_lock_count[i] = 0;
153 pthread_mutex_init(&ssl_locks[i], NULL);
155 CRYPTO_set_id_callback(ssl_thread_id);
156 CRYPTO_set_locking_callback(ssl_locking_callback);
158 SSL_load_error_strings();
161 while (!RAND_status()) {
162 time_t t = time(NULL);
163 pid_t pid = getpid();
164 RAND_seed((unsigned char *)&t, sizeof(time_t));
165 RAND_seed((unsigned char *)&pid, sizeof(pid));
168 ctx = SSL_CTX_new(TLSv1_method());
169 if (options.tlscertificatekeypassword) {
170 SSL_CTX_set_default_passwd_cb_userdata(ctx, options.tlscertificatekeypassword);
171 SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb);
173 if (SSL_CTX_use_certificate_chain_file(ctx, options.tlscertificatefile) &&
174 SSL_CTX_use_PrivateKey_file(ctx, options.tlscertificatekeyfile, SSL_FILETYPE_PEM) &&
175 SSL_CTX_check_private_key(ctx) &&
176 SSL_CTX_load_verify_locations(ctx, options.tlscacertificatefile, options.tlscacertificatepath)) {
177 SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, verify_cb);
178 SSL_CTX_set_verify_depth(ctx, MAX_CERT_DEPTH + 1);
182 while ((error = ERR_get_error()))
183 err("SSL: %s", ERR_error_string(error, NULL));
187 void printauth(char *s, unsigned char *t) {
190 for (i = 0; i < 16; i++)
191 printf("%02x ", t[i]);
195 int resolvepeer(struct peer *peer, int ai_flags) {
196 struct addrinfo hints, *addrinfo;
198 memset(&hints, 0, sizeof(hints));
199 hints.ai_socktype = (peer->type == 'T' ? SOCK_STREAM : SOCK_DGRAM);
200 hints.ai_family = AF_UNSPEC;
201 hints.ai_flags = ai_flags;
202 if (getaddrinfo(peer->host, peer->port, &hints, &addrinfo)) {
203 err("resolvepeer: can't resolve %s port %s", peer->host, peer->port);
208 freeaddrinfo(peer->addrinfo);
209 peer->addrinfo = addrinfo;
213 int connecttoserver(struct addrinfo *addrinfo) {
215 struct addrinfo *res;
217 for (res = addrinfo; res; res = res->ai_next) {
218 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
220 err("connecttoserver: socket failed");
223 if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
225 err("connecttoserver: connect failed");
232 int bindtoaddr(struct addrinfo *addrinfo) {
234 struct addrinfo *res;
236 for (res = addrinfo; res; res = res->ai_next) {
237 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
239 err("bindtoaddr: socket failed");
242 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
243 if (!bind(s, res->ai_addr, res->ai_addrlen))
245 err("bindtoaddr: bind failed");
251 /* returns the client with matching address, or NULL */
252 /* if client argument is not NULL, we only check that one client */
253 struct client *find_client(char type, struct sockaddr *addr, struct client *client) {
254 struct sockaddr_in6 *sa6;
255 struct in_addr *a4 = NULL;
258 struct addrinfo *res;
260 if (addr->sa_family == AF_INET6) {
261 sa6 = (struct sockaddr_in6 *)addr;
262 if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
263 a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12];
265 a4 = &((struct sockaddr_in *)addr)->sin_addr;
267 c = (client ? client : clients);
268 for (i = 0; i < client_count; i++) {
269 if (c->peer.type == type)
270 for (res = c->peer.addrinfo; res; res = res->ai_next)
271 if ((a4 && res->ai_family == AF_INET &&
272 !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) ||
273 (res->ai_family == AF_INET6 &&
274 !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16)))
283 /* returns the server with matching address, or NULL */
284 /* if server argument is not NULL, we only check that one server */
285 struct server *find_server(char type, struct sockaddr *addr, struct server *server) {
286 struct sockaddr_in6 *sa6;
287 struct in_addr *a4 = NULL;
290 struct addrinfo *res;
292 if (addr->sa_family == AF_INET6) {
293 sa6 = (struct sockaddr_in6 *)addr;
294 if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
295 a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12];
297 a4 = &((struct sockaddr_in *)addr)->sin_addr;
299 s = (server ? server : servers);
300 for (i = 0; i < server_count; i++) {
301 if (s->peer.type == type)
302 for (res = s->peer.addrinfo; res; res = res->ai_next)
303 if ((a4 && res->ai_family == AF_INET &&
304 !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) ||
305 (res->ai_family == AF_INET6 &&
306 !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16)))
315 /* exactly one of client and server must be non-NULL */
316 /* if *peer == NULL we return who we received from, else require it to be from peer */
317 /* return from in sa if not NULL */
318 unsigned char *radudpget(int s, struct client **client, struct server **server, struct sockaddr_storage *sa) {
321 unsigned char buf[65536], *rad;
322 struct sockaddr_storage from;
323 socklen_t fromlen = sizeof(from);
326 cnt = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen);
328 err("radudpget: recv failed");
331 printf("radudpget: got %d bytes from %s\n", cnt, addr2string((struct sockaddr *)&from, fromlen));
334 printf("radudpget: packet too small\n");
341 printf("radudpget: packet smaller than length field in radius header\n");
345 printf("radudpget: packet was padded with %d bytes\n", cnt - len);
348 ? (void *)find_client('U', (struct sockaddr *)&from, *client)
349 : (void *)find_server('U', (struct sockaddr *)&from, *server));
351 printf("radudpget: got packet from wrong or unknown UDP peer, ignoring\n");
358 err("radudpget: malloc failed");
360 memcpy(rad, buf, len);
362 *client = (struct client *)f; /* only need this if *client == NULL, but if not NULL *client == f here */
364 *server = (struct server *)f; /* only need this if *server == NULL, but if not NULL *server == f here */
370 int tlsverifycert(struct peer *peer) {
379 if (SSL_get_verify_result(peer->ssl) != X509_V_OK) {
380 printf("tlsverifycert: basic validation failed\n");
381 while ((error = ERR_get_error()))
382 err("clientwr: TLS: %s", ERR_error_string(error, NULL));
386 cert = SSL_get_peer_certificate(peer->ssl);
388 printf("tlsverifycert: failed to obtain certificate\n");
391 nm = X509_get_subject_name(cert);
394 loc = X509_NAME_get_index_by_NID(nm, NID_commonName, loc);
397 e = X509_NAME_get_entry(nm, loc);
398 l = ASN1_STRING_to_UTF8(&v, X509_NAME_ENTRY_get_data(e));
402 for (i = 0; i < l; i++)
405 if (l == strlen(peer->host) && !strncasecmp(peer->host, (char *)v, l)) {
406 printf("tlsverifycert: Found cn matching host %s, All OK\n", peer->host);
409 printf("tlsverifycert: cn not matching host %s\n", peer->host);
415 void tlsconnect(struct server *server, struct timeval *when, char *text) {
419 printf("tlsconnect called from %s\n", text);
420 pthread_mutex_lock(&server->lock);
421 if (when && memcmp(&server->lastconnecttry, when, sizeof(struct timeval))) {
422 /* already reconnected, nothing to do */
423 printf("tlsconnect(%s): seems already reconnected\n", text);
424 pthread_mutex_unlock(&server->lock);
428 printf("tlsconnect %s\n", text);
431 gettimeofday(&now, NULL);
432 elapsed = now.tv_sec - server->lastconnecttry.tv_sec;
433 if (server->connectionok) {
434 server->connectionok = 0;
436 } else if (elapsed < 5)
438 else if (elapsed < 600) {
439 printf("tlsconnect: sleeping %lds\n", elapsed);
441 } else if (elapsed < 1000) {
442 printf("tlsconnect: sleeping %ds\n", 900);
445 server->lastconnecttry.tv_sec = now.tv_sec; /* no sleep at startup */
446 printf("tlsconnect: trying to open TLS connection to %s port %s\n", server->peer.host, server->peer.port);
447 if (server->sock >= 0)
449 if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0)
451 SSL_free(server->peer.ssl);
452 server->peer.ssl = SSL_new(ssl_ctx);
453 SSL_set_fd(server->peer.ssl, server->sock);
454 if (SSL_connect(server->peer.ssl) > 0 && tlsverifycert(&server->peer))
457 printf("tlsconnect: TLS connection to %s port %s up\n", server->peer.host, server->peer.port);
458 gettimeofday(&server->lastconnecttry, NULL);
459 pthread_mutex_unlock(&server->lock);
462 unsigned char *radtlsget(SSL *ssl) {
464 unsigned char buf[4], *rad;
467 for (total = 0; total < 4; total += cnt) {
468 cnt = SSL_read(ssl, buf + total, 4 - total);
470 printf("radtlsget: connection lost\n");
471 if (SSL_get_error(ssl, cnt) == SSL_ERROR_ZERO_RETURN) {
472 /* remote end sent close_notify, send one back */
482 err("radtlsget: malloc failed");
487 for (; total < len; total += cnt) {
488 cnt = SSL_read(ssl, rad + total, len - total);
490 printf("radtlsget: connection lost\n");
491 if (SSL_get_error(ssl, cnt) == SSL_ERROR_ZERO_RETURN) {
492 /* remote end sent close_notify, send one back */
504 printf("radtlsget: packet smaller than minimum radius size\n");
507 printf("radtlsget: got %d bytes\n", total);
511 int clientradput(struct server *server, unsigned char *rad) {
515 struct timeval lastconnecttry;
518 if (server->peer.type == 'U') {
519 if (send(server->sock, rad, len, 0) >= 0) {
520 printf("clienradput: sent UDP of length %d to %s port %s\n", len, server->peer.host, server->peer.port);
523 err("clientradput: send failed");
527 lastconnecttry = server->lastconnecttry;
528 while ((cnt = SSL_write(server->peer.ssl, rad, len)) <= 0) {
529 while ((error = ERR_get_error()))
530 err("clientwr: TLS: %s", ERR_error_string(error, NULL));
531 tlsconnect(server, &lastconnecttry, "clientradput");
532 lastconnecttry = server->lastconnecttry;
535 server->connectionok = 1;
536 printf("clientradput: Sent %d bytes, Radius packet of length %d to TLS peer %s\n",
537 cnt, len, server->peer.host);
541 int radsign(unsigned char *rad, unsigned char *sec) {
542 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
543 static unsigned char first = 1;
544 static EVP_MD_CTX mdctx;
548 pthread_mutex_lock(&lock);
550 EVP_MD_CTX_init(&mdctx);
554 result = (EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) &&
555 EVP_DigestUpdate(&mdctx, rad, RADLEN(rad)) &&
556 EVP_DigestUpdate(&mdctx, sec, strlen((char *)sec)) &&
557 EVP_DigestFinal_ex(&mdctx, rad + 4, &md_len) &&
559 pthread_mutex_unlock(&lock);
563 int validauth(unsigned char *rad, unsigned char *reqauth, unsigned char *sec) {
564 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
565 static unsigned char first = 1;
566 static EVP_MD_CTX mdctx;
567 unsigned char hash[EVP_MAX_MD_SIZE];
571 pthread_mutex_lock(&lock);
573 EVP_MD_CTX_init(&mdctx);
579 result = (EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) &&
580 EVP_DigestUpdate(&mdctx, rad, 4) &&
581 EVP_DigestUpdate(&mdctx, reqauth, 16) &&
582 (len <= 20 || EVP_DigestUpdate(&mdctx, rad + 20, len - 20)) &&
583 EVP_DigestUpdate(&mdctx, sec, strlen((char *)sec)) &&
584 EVP_DigestFinal_ex(&mdctx, hash, &len) &&
586 !memcmp(hash, rad + 4, 16));
587 pthread_mutex_unlock(&lock);
591 int checkmessageauth(unsigned char *rad, uint8_t *authattr, char *secret) {
592 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
593 static unsigned char first = 1;
594 static HMAC_CTX hmacctx;
596 uint8_t auth[16], hash[EVP_MAX_MD_SIZE];
598 pthread_mutex_lock(&lock);
600 HMAC_CTX_init(&hmacctx);
604 memcpy(auth, authattr, 16);
605 memset(authattr, 0, 16);
607 HMAC_Init_ex(&hmacctx, secret, strlen(secret), EVP_md5(), NULL);
608 HMAC_Update(&hmacctx, rad, RADLEN(rad));
609 HMAC_Final(&hmacctx, hash, &md_len);
610 memcpy(authattr, auth, 16);
612 printf("message auth computation failed\n");
613 pthread_mutex_unlock(&lock);
617 if (memcmp(auth, hash, 16)) {
618 printf("message authenticator, wrong value\n");
619 pthread_mutex_unlock(&lock);
623 pthread_mutex_unlock(&lock);
627 int createmessageauth(unsigned char *rad, unsigned char *authattrval, char *secret) {
628 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
629 static unsigned char first = 1;
630 static HMAC_CTX hmacctx;
636 pthread_mutex_lock(&lock);
638 HMAC_CTX_init(&hmacctx);
642 memset(authattrval, 0, 16);
644 HMAC_Init_ex(&hmacctx, secret, strlen(secret), EVP_md5(), NULL);
645 HMAC_Update(&hmacctx, rad, RADLEN(rad));
646 HMAC_Final(&hmacctx, authattrval, &md_len);
648 printf("message auth computation failed\n");
649 pthread_mutex_unlock(&lock);
653 pthread_mutex_unlock(&lock);
657 void sendrq(struct server *to, struct client *from, struct request *rq) {
660 pthread_mutex_lock(&to->newrq_mutex);
661 /* might simplify if only try nextid, might be ok */
662 for (i = to->nextid; i < MAX_REQUESTS; i++)
663 if (!to->requests[i].buf)
665 if (i == MAX_REQUESTS) {
666 for (i = 0; i < to->nextid; i++)
667 if (!to->requests[i].buf)
669 if (i == to->nextid) {
670 printf("No room in queue, dropping request\n");
671 pthread_mutex_unlock(&to->newrq_mutex);
677 rq->buf[1] = (char)i;
678 printf("sendrq: inserting packet with id %d in queue for %s\n", i, to->peer.host);
680 if (!createmessageauth(rq->buf, rq->messageauthattrval, to->peer.secret))
683 to->requests[i] = *rq;
687 printf("signalling client writer\n");
688 pthread_cond_signal(&to->newrq_cond);
690 pthread_mutex_unlock(&to->newrq_mutex);
693 void sendreply(struct client *to, struct server *from, unsigned char *buf, struct sockaddr_storage *tosa) {
694 struct replyq *replyq = to->replyq;
696 pthread_mutex_lock(&replyq->count_mutex);
697 if (replyq->count == replyq->size) {
698 printf("No room in queue, dropping request\n");
699 pthread_mutex_unlock(&replyq->count_mutex);
703 replyq->replies[replyq->count].buf = buf;
705 replyq->replies[replyq->count].tosa = *tosa;
708 if (replyq->count == 1) {
709 printf("signalling client writer\n");
710 pthread_cond_signal(&replyq->count_cond);
712 pthread_mutex_unlock(&replyq->count_mutex);
715 int pwdencrypt(uint8_t *in, uint8_t len, char *shared, uint8_t sharedlen, uint8_t *auth) {
716 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
717 static unsigned char first = 1;
718 static EVP_MD_CTX mdctx;
719 unsigned char hash[EVP_MAX_MD_SIZE], *input;
721 uint8_t i, offset = 0, out[128];
723 pthread_mutex_lock(&lock);
725 EVP_MD_CTX_init(&mdctx);
731 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
732 !EVP_DigestUpdate(&mdctx, (uint8_t *)shared, sharedlen) ||
733 !EVP_DigestUpdate(&mdctx, input, 16) ||
734 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
736 pthread_mutex_unlock(&lock);
739 for (i = 0; i < 16; i++)
740 out[offset + i] = hash[i] ^ in[offset + i];
741 input = out + offset - 16;
746 memcpy(in, out, len);
747 pthread_mutex_unlock(&lock);
751 int pwddecrypt(uint8_t *in, uint8_t len, char *shared, uint8_t sharedlen, uint8_t *auth) {
752 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
753 static unsigned char first = 1;
754 static EVP_MD_CTX mdctx;
755 unsigned char hash[EVP_MAX_MD_SIZE], *input;
757 uint8_t i, offset = 0, out[128];
759 pthread_mutex_lock(&lock);
761 EVP_MD_CTX_init(&mdctx);
767 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
768 !EVP_DigestUpdate(&mdctx, (uint8_t *)shared, sharedlen) ||
769 !EVP_DigestUpdate(&mdctx, input, 16) ||
770 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
772 pthread_mutex_unlock(&lock);
775 for (i = 0; i < 16; i++)
776 out[offset + i] = hash[i] ^ in[offset + i];
782 memcpy(in, out, len);
783 pthread_mutex_unlock(&lock);
787 int msmppencrypt(uint8_t *text, uint8_t len, uint8_t *shared, uint8_t sharedlen, uint8_t *auth, uint8_t *salt) {
788 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
789 static unsigned char first = 1;
790 static EVP_MD_CTX mdctx;
791 unsigned char hash[EVP_MAX_MD_SIZE];
795 pthread_mutex_lock(&lock);
797 EVP_MD_CTX_init(&mdctx);
802 printf("msppencrypt auth in: ");
803 for (i = 0; i < 16; i++)
804 printf("%02x ", auth[i]);
807 printf("msppencrypt salt in: ");
808 for (i = 0; i < 2; i++)
809 printf("%02x ", salt[i]);
812 printf("msppencrypt in: ");
813 for (i = 0; i < len; i++)
814 printf("%02x ", text[i]);
818 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
819 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
820 !EVP_DigestUpdate(&mdctx, auth, 16) ||
821 !EVP_DigestUpdate(&mdctx, salt, 2) ||
822 !EVP_DigestFinal_ex(&mdctx, hash, &md_len)) {
823 pthread_mutex_unlock(&lock);
828 printf("msppencrypt hash: ");
829 for (i = 0; i < 16; i++)
830 printf("%02x ", hash[i]);
834 for (i = 0; i < 16; i++)
837 for (offset = 16; offset < len; offset += 16) {
839 printf("text + offset - 16 c(%d): ", offset / 16);
840 for (i = 0; i < 16; i++)
841 printf("%02x ", (text + offset - 16)[i]);
844 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
845 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
846 !EVP_DigestUpdate(&mdctx, text + offset - 16, 16) ||
847 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
849 pthread_mutex_unlock(&lock);
853 printf("msppencrypt hash: ");
854 for (i = 0; i < 16; i++)
855 printf("%02x ", hash[i]);
859 for (i = 0; i < 16; i++)
860 text[offset + i] ^= hash[i];
864 printf("msppencrypt out: ");
865 for (i = 0; i < len; i++)
866 printf("%02x ", text[i]);
870 pthread_mutex_unlock(&lock);
874 int msmppdecrypt(uint8_t *text, uint8_t len, uint8_t *shared, uint8_t sharedlen, uint8_t *auth, uint8_t *salt) {
875 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
876 static unsigned char first = 1;
877 static EVP_MD_CTX mdctx;
878 unsigned char hash[EVP_MAX_MD_SIZE];
883 pthread_mutex_lock(&lock);
885 EVP_MD_CTX_init(&mdctx);
890 printf("msppdecrypt auth in: ");
891 for (i = 0; i < 16; i++)
892 printf("%02x ", auth[i]);
895 printf("msppedecrypt salt in: ");
896 for (i = 0; i < 2; i++)
897 printf("%02x ", salt[i]);
900 printf("msppedecrypt in: ");
901 for (i = 0; i < len; i++)
902 printf("%02x ", text[i]);
906 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
907 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
908 !EVP_DigestUpdate(&mdctx, auth, 16) ||
909 !EVP_DigestUpdate(&mdctx, salt, 2) ||
910 !EVP_DigestFinal_ex(&mdctx, hash, &md_len)) {
911 pthread_mutex_unlock(&lock);
916 printf("msppedecrypt hash: ");
917 for (i = 0; i < 16; i++)
918 printf("%02x ", hash[i]);
922 for (i = 0; i < 16; i++)
923 plain[i] = text[i] ^ hash[i];
925 for (offset = 16; offset < len; offset += 16) {
927 printf("text + offset - 16 c(%d): ", offset / 16);
928 for (i = 0; i < 16; i++)
929 printf("%02x ", (text + offset - 16)[i]);
932 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
933 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
934 !EVP_DigestUpdate(&mdctx, text + offset - 16, 16) ||
935 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
937 pthread_mutex_unlock(&lock);
941 printf("msppedecrypt hash: ");
942 for (i = 0; i < 16; i++)
943 printf("%02x ", hash[i]);
947 for (i = 0; i < 16; i++)
948 plain[offset + i] = text[offset + i] ^ hash[i];
951 memcpy(text, plain, len);
953 printf("msppedecrypt out: ");
954 for (i = 0; i < len; i++)
955 printf("%02x ", text[i]);
959 pthread_mutex_unlock(&lock);
963 struct server *id2server(char *id, uint8_t len) {
965 char **realm, *idrealm;
967 idrealm = strchr(id, '@');
975 for (i = 0; i < server_count; i++) {
976 for (realm = servers[i].realms; *realm; realm++) {
977 if ((strlen(*realm) == 1 && **realm == '*') ||
978 (strlen(*realm) == len && !memcmp(idrealm, *realm, len))) {
979 printf("found matching realm: %s, host %s\n", *realm, servers[i].peer.host);
987 int rqinqueue(struct server *to, struct client *from, uint8_t id) {
990 pthread_mutex_lock(&to->newrq_mutex);
991 for (i = 0; i < MAX_REQUESTS; i++)
992 if (to->requests[i].buf && to->requests[i].origid == id && to->requests[i].from == from)
994 pthread_mutex_unlock(&to->newrq_mutex);
996 return i < MAX_REQUESTS;
999 struct server *radsrv(struct request *rq, unsigned char *buf, struct client *from) {
1000 uint8_t code, id, *auth, *attr, attrvallen;
1001 uint8_t *usernameattr = NULL, *userpwdattr = NULL, *tunnelpwdattr = NULL, *messageauthattr = NULL;
1006 unsigned char newauth[16];
1008 code = *(uint8_t *)buf;
1009 id = *(uint8_t *)(buf + 1);
1011 auth = (uint8_t *)(buf + 4);
1013 printf("radsrv: code %d, id %d, length %d\n", code, id, len);
1015 if (code != RAD_Access_Request) {
1016 printf("radsrv: server currently accepts only access-requests, ignoring\n");
1024 left -= attr[RAD_Attr_Length];
1026 printf("radsrv: attribute length exceeds packet length, ignoring packet\n");
1029 switch (attr[RAD_Attr_Type]) {
1030 case RAD_Attr_User_Name:
1031 usernameattr = attr;
1033 case RAD_Attr_User_Password:
1036 case RAD_Attr_Tunnel_Password:
1037 tunnelpwdattr = attr;
1039 case RAD_Attr_Message_Authenticator:
1040 messageauthattr = attr;
1043 attr += attr[RAD_Attr_Length];
1046 printf("radsrv: malformed packet? remaining byte after last attribute\n");
1049 printf("radsrv: Username: ");
1050 for (i = 0; i < usernameattr[RAD_Attr_Length] - 2; i++)
1051 printf("%c", usernameattr[RAD_Attr_Value + i]);
1055 to = id2server((char *)&usernameattr[RAD_Attr_Value], usernameattr[RAD_Attr_Length] - 2);
1057 printf("radsrv: ignoring request, don't know where to send it\n");
1061 if (rqinqueue(to, from, id)) {
1062 printf("radsrv: ignoring request from host %s with id %d, already got one\n", from->peer.host, id);
1066 if (messageauthattr && (messageauthattr[RAD_Attr_Length] != 18 ||
1067 !checkmessageauth(buf, &messageauthattr[RAD_Attr_Value], from->peer.secret))) {
1068 printf("radsrv: message authentication failed\n");
1072 if (!RAND_bytes(newauth, 16)) {
1073 printf("radsrv: failed to generate random auth\n");
1077 printauth("auth", auth);
1078 printauth("newauth", newauth);
1081 printf("radsrv: found userpwdattr of length %d\n", userpwdattr[RAD_Attr_Length]);
1082 attrvallen = userpwdattr[RAD_Attr_Length] - 2;
1083 if (attrvallen < 16 || attrvallen > 128 || attrvallen % 16) {
1084 printf("radsrv: invalid user password length\n");
1088 if (!pwddecrypt(&userpwdattr[RAD_Attr_Value], attrvallen, from->peer.secret, strlen(from->peer.secret), auth)) {
1089 printf("radsrv: cannot decrypt password\n");
1092 printf("radsrv: password: ");
1093 for (i = 0; i < attrvallen; i++)
1094 printf("%02x ", userpwdattr[RAD_Attr_Value + i]);
1096 if (!pwdencrypt(&userpwdattr[RAD_Attr_Value], attrvallen, to->peer.secret, strlen(to->peer.secret), newauth)) {
1097 printf("radsrv: cannot encrypt password\n");
1102 if (tunnelpwdattr) {
1103 printf("radsrv: found tunnelpwdattr of length %d\n", tunnelpwdattr[RAD_Attr_Length]);
1104 attrvallen = tunnelpwdattr[RAD_Attr_Length] - 2;
1105 if (attrvallen < 16 || attrvallen > 128 || attrvallen % 16) {
1106 printf("radsrv: invalid user password length\n");
1110 if (!pwddecrypt(&tunnelpwdattr[RAD_Attr_Value], attrvallen, from->peer.secret, strlen(from->peer.secret), auth)) {
1111 printf("radsrv: cannot decrypt password\n");
1114 printf("radsrv: password: ");
1115 for (i = 0; i < attrvallen; i++)
1116 printf("%02x ", tunnelpwdattr[RAD_Attr_Value + i]);
1118 if (!pwdencrypt(&tunnelpwdattr[RAD_Attr_Value], attrvallen, to->peer.secret, strlen(to->peer.secret), newauth)) {
1119 printf("radsrv: cannot encrypt password\n");
1127 rq->messageauthattrval = (messageauthattr ? &messageauthattr[RAD_Attr_Value] : NULL);
1128 memcpy(rq->origauth, auth, 16);
1129 memcpy(auth, newauth, 16);
1130 printauth("rq->origauth", (unsigned char *)rq->origauth);
1131 printauth("auth", auth);
1135 void *clientrd(void *arg) {
1136 struct server *server = (struct server *)arg;
1137 struct client *from;
1138 int i, left, subleft;
1139 unsigned char *buf, *messageauthattr, *subattr, *attr;
1140 struct sockaddr_storage fromsa;
1141 struct timeval lastconnecttry;
1146 lastconnecttry = server->lastconnecttry;
1147 buf = (server->peer.type == 'U' ? radudpget(server->sock, NULL, &server, NULL) : radtlsget(server->peer.ssl));
1148 if (!buf && server->peer.type == 'T') {
1149 tlsconnect(server, &lastconnecttry, "clientrd");
1153 server->connectionok = 1;
1155 if (*buf != RAD_Access_Accept && *buf != RAD_Access_Reject && *buf != RAD_Access_Challenge) {
1156 printf("clientrd: discarding, only accept access accept, access reject and access challenge messages\n");
1160 printf("got message type: %d, id: %d\n", buf[0], buf[1]);
1162 i = buf[1]; /* i is the id */
1164 pthread_mutex_lock(&server->newrq_mutex);
1165 if (!server->requests[i].buf || !server->requests[i].tries) {
1166 pthread_mutex_unlock(&server->newrq_mutex);
1167 printf("clientrd: no matching request sent with this id, ignoring\n");
1171 if (server->requests[i].received) {
1172 pthread_mutex_unlock(&server->newrq_mutex);
1173 printf("clientrd: already received, ignoring\n");
1177 if (!validauth(buf, server->requests[i].buf + 4, (unsigned char *)server->peer.secret)) {
1178 pthread_mutex_unlock(&server->newrq_mutex);
1179 printf("clientrd: invalid auth, ignoring\n");
1183 from = server->requests[i].from;
1185 /* messageauthattr present? */
1186 messageauthattr = NULL;
1187 left = RADLEN(buf) - 20;
1190 left -= attr[RAD_Attr_Length];
1192 printf("clientrd: attribute length exceeds packet length, ignoring packet\n");
1195 if (attr[RAD_Attr_Type] == RAD_Attr_Message_Authenticator) {
1196 if (attr[RAD_Attr_Length] != 18) {
1197 printf("clientrd: illegal message auth attribute length, ignoring packet\n");
1200 memcpy(tmp, buf + 4, 16);
1201 memcpy(buf + 4, server->requests[i].buf + 4, 16);
1202 if (!checkmessageauth(buf, &attr[RAD_Attr_Value], server->peer.secret)) {
1203 printf("clientrd: message authentication failed\n");
1206 memcpy(buf + 4, tmp, 16);
1207 printf("clientrd: message auth ok\n");
1208 messageauthattr = attr;
1211 attr += attr[RAD_Attr_Length];
1214 /* handle MS MPPE */
1215 left = RADLEN(buf) - 20;
1218 left -= attr[RAD_Attr_Length];
1220 printf("clientrd: attribute length exceeds packet length, ignoring packet\n");
1223 if (attr[RAD_Attr_Type] == RAD_Attr_Vendor_Specific &&
1224 ((uint16_t *)attr)[1] == 0 && ntohs(((uint16_t *)attr)[2]) == 311) { /* 311 == MS */
1225 subleft = attr[RAD_Attr_Length] - 6;
1227 while (subleft > 1) {
1228 subleft -= subattr[RAD_Attr_Length];
1231 if (subattr[RAD_Attr_Type] != RAD_VS_ATTR_MS_MPPE_Send_Key &&
1232 subattr[RAD_Attr_Type] != RAD_VS_ATTR_MS_MPPE_Recv_Key)
1234 printf("clientrd: Got MS MPPE\n");
1235 if (subattr[RAD_Attr_Length] < 20)
1238 if (!msmppdecrypt(subattr + 4, subattr[RAD_Attr_Length] - 4, (unsigned char *)server->peer.secret,
1239 strlen(server->peer.secret), server->requests[i].buf + 4, subattr + 2)) {
1240 printf("clientrd: failed to decrypt msppe key\n");
1244 if (!msmppencrypt(subattr + 4, subattr[RAD_Attr_Length] - 4, (unsigned char *)from->peer.secret,
1245 strlen(from->peer.secret), (unsigned char *)server->requests[i].origauth, subattr + 2)) {
1246 printf("clientrd: failed to encrypt msppe key\n");
1251 printf("clientrd: bad vendor specific attr or subattr length, ignoring packet\n");
1255 attr += attr[RAD_Attr_Length];
1258 /* once we set received = 1, requests[i] may be reused */
1259 buf[1] = (char)server->requests[i].origid;
1260 memcpy(buf + 4, server->requests[i].origauth, 16);
1261 printauth("origauth/buf+4", buf + 4);
1262 if (messageauthattr) {
1263 if (!createmessageauth(buf, &messageauthattr[RAD_Attr_Value], from->peer.secret))
1265 printf("clientrd: computed messageauthattr\n");
1268 if (from->peer.type == 'U')
1269 fromsa = server->requests[i].fromsa;
1270 server->requests[i].received = 1;
1271 pthread_mutex_unlock(&server->newrq_mutex);
1273 if (!radsign(buf, (unsigned char *)from->peer.secret)) {
1274 printf("clientrd: failed to sign message\n");
1277 printauth("signedorigauth/buf+4", buf + 4);
1278 printf("clientrd: giving packet back to where it came from\n");
1279 sendreply(from, server, buf, from->peer.type == 'U' ? &fromsa : NULL);
1283 void *clientwr(void *arg) {
1284 struct server *server = (struct server *)arg;
1286 pthread_t clientrdth;
1289 struct timespec timeout;
1291 memset(&timeout, 0, sizeof(struct timespec));
1293 if (server->peer.type == 'U') {
1294 if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0) {
1295 printf("clientwr: connecttoserver failed\n");
1299 tlsconnect(server, NULL, "new client");
1301 if (pthread_create(&clientrdth, NULL, clientrd, (void *)server))
1302 errx("clientwr: pthread_create failed");
1305 pthread_mutex_lock(&server->newrq_mutex);
1306 if (!server->newrq) {
1307 if (timeout.tv_nsec) {
1308 printf("clientwr: waiting up to %ld secs for new request\n", timeout.tv_nsec);
1309 pthread_cond_timedwait(&server->newrq_cond, &server->newrq_mutex, &timeout);
1310 timeout.tv_nsec = 0;
1312 printf("clientwr: waiting for new request\n");
1313 pthread_cond_wait(&server->newrq_cond, &server->newrq_mutex);
1316 if (server->newrq) {
1317 printf("clientwr: got new request\n");
1320 printf("clientwr: request timer expired, processing request queue\n");
1321 pthread_mutex_unlock(&server->newrq_mutex);
1323 for (i = 0; i < MAX_REQUESTS; i++) {
1324 pthread_mutex_lock(&server->newrq_mutex);
1325 while (!server->requests[i].buf && i < MAX_REQUESTS)
1327 if (i == MAX_REQUESTS) {
1328 pthread_mutex_unlock(&server->newrq_mutex);
1331 rq = server->requests + i;
1334 printf("clientwr: removing received packet from queue\n");
1336 /* setting this to NULL means that it can be reused */
1338 pthread_mutex_unlock(&server->newrq_mutex);
1342 gettimeofday(&now, NULL);
1343 if (now.tv_sec <= rq->expiry.tv_sec) {
1344 if (!timeout.tv_sec || rq->expiry.tv_sec < timeout.tv_sec)
1345 timeout.tv_sec = rq->expiry.tv_sec;
1346 pthread_mutex_unlock(&server->newrq_mutex);
1350 if (rq->tries == (server->peer.type == 'T' ? 1 : REQUEST_RETRIES)) {
1351 printf("clientwr: removing expired packet from queue\n");
1353 /* setting this to NULL means that it can be reused */
1355 pthread_mutex_unlock(&server->newrq_mutex);
1358 pthread_mutex_unlock(&server->newrq_mutex);
1360 rq->expiry.tv_sec = now.tv_sec +
1361 (server->peer.type == 'T' ? REQUEST_EXPIRY : REQUEST_EXPIRY / REQUEST_RETRIES);
1362 if (!timeout.tv_sec || rq->expiry.tv_sec < timeout.tv_sec)
1363 timeout.tv_sec = rq->expiry.tv_sec;
1365 clientradput(server, server->requests[i].buf);
1369 /* should do more work to maintain TLS connections, keepalives etc */
1372 void *udpserverwr(void *arg) {
1373 struct replyq *replyq = &udp_server_replyq;
1374 struct reply *reply = replyq->replies;
1376 pthread_mutex_lock(&replyq->count_mutex);
1378 while (!replyq->count) {
1379 printf("udp server writer, waiting for signal\n");
1380 pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex);
1381 printf("udp server writer, got signal\n");
1383 pthread_mutex_unlock(&replyq->count_mutex);
1385 if (sendto(udp_server_sock, reply->buf, RADLEN(reply->buf), 0,
1386 (struct sockaddr *)&reply->tosa, SOCKADDR_SIZE(reply->tosa)) < 0)
1387 err("sendudp: send failed");
1390 pthread_mutex_lock(&replyq->count_mutex);
1392 memmove(replyq->replies, replyq->replies + 1,
1393 replyq->count * sizeof(struct reply));
1397 void *udpserverrd(void *arg) {
1402 pthread_t udpserverwrth;
1404 if ((udp_server_sock = bindtoaddr(udp_server_listen->addrinfo)) < 0) {
1405 printf("udpserverrd: socket/bind failed\n");
1408 printf("udpserverrd: listening for UDP on host %s port %s\n", udp_server_listen->host, udp_server_listen->port);
1410 if (pthread_create(&udpserverwrth, NULL, udpserverwr, NULL))
1411 errx("pthread_create failed");
1415 memset(&rq, 0, sizeof(struct request));
1416 buf = radudpget(udp_server_sock, &fr, NULL, &rq.fromsa);
1417 to = radsrv(&rq, buf, fr);
1419 printf("udpserverrd: ignoring request, no place to send it\n");
1422 sendrq(to, fr, &rq);
1426 void *tlsserverwr(void *arg) {
1428 unsigned long error;
1429 struct client *client = (struct client *)arg;
1430 struct replyq *replyq;
1432 printf("tlsserverwr starting for %s\n", client->peer.host);
1433 replyq = client->replyq;
1434 pthread_mutex_lock(&replyq->count_mutex);
1436 while (!replyq->count) {
1437 if (client->peer.ssl) {
1438 printf("tls server writer, waiting for signal\n");
1439 pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex);
1440 printf("tls server writer, got signal\n");
1442 if (!client->peer.ssl) {
1443 /* ssl might have changed while waiting */
1444 pthread_mutex_unlock(&replyq->count_mutex);
1445 printf("tlsserverwr: exiting as requested\n");
1449 pthread_mutex_unlock(&replyq->count_mutex);
1450 cnt = SSL_write(client->peer.ssl, replyq->replies->buf, RADLEN(replyq->replies->buf));
1452 printf("tlsserverwr: Sent %d bytes, Radius packet of length %d\n",
1453 cnt, RADLEN(replyq->replies->buf));
1455 while ((error = ERR_get_error()))
1456 err("tlsserverwr: SSL: %s", ERR_error_string(error, NULL));
1457 free(replyq->replies->buf);
1459 pthread_mutex_lock(&replyq->count_mutex);
1461 memmove(replyq->replies, replyq->replies + 1, replyq->count * sizeof(struct reply));
1465 void *tlsserverrd(void *arg) {
1468 unsigned long error;
1471 struct client *client = (struct client *)arg;
1472 pthread_t tlsserverwrth;
1475 printf("tlsserverrd starting for %s\n", client->peer.host);
1476 ssl = client->peer.ssl;
1478 if (SSL_accept(ssl) <= 0) {
1479 while ((error = ERR_get_error()))
1480 err("tlsserverrd: SSL: %s", ERR_error_string(error, NULL));
1481 errx("accept failed, child exiting");
1484 if (tlsverifycert(&client->peer)) {
1485 if (pthread_create(&tlsserverwrth, NULL, tlsserverwr, (void *)client))
1486 errx("pthread_create failed");
1489 buf = radtlsget(client->peer.ssl);
1492 printf("tlsserverrd: got Radius message from %s\n", client->peer.host);
1493 memset(&rq, 0, sizeof(struct request));
1494 to = radsrv(&rq, buf, client);
1496 printf("ignoring request, no place to send it\n");
1499 sendrq(to, client, &rq);
1501 printf("tlsserverrd: connection lost\n");
1502 /* stop writer by setting peer.ssl to NULL and give signal in case waiting for data */
1503 client->peer.ssl = NULL;
1504 pthread_mutex_lock(&client->replyq->count_mutex);
1505 pthread_cond_signal(&client->replyq->count_cond);
1506 pthread_mutex_unlock(&client->replyq->count_mutex);
1507 printf("tlsserverrd: waiting for writer to end\n");
1508 pthread_join(tlsserverwrth, NULL);
1510 s = SSL_get_fd(ssl);
1513 printf("tlsserverrd thread for %s exiting\n", client->peer.host);
1514 client->peer.ssl = NULL;
1519 pthread_t tlsserverth;
1521 struct sockaddr_storage from;
1522 size_t fromlen = sizeof(from);
1523 struct client *client;
1525 if ((s = bindtoaddr(tcp_server_listen->addrinfo)) < 0) {
1526 printf("tlslistener: socket/bind failed\n");
1531 printf("listening for incoming TCP on address %s port %s\n", tcp_server_listen->host, tcp_server_listen->port);
1534 snew = accept(s, (struct sockaddr *)&from, &fromlen);
1536 err("accept failed");
1539 printf("incoming TLS connection from %s\n", addr2string((struct sockaddr *)&from, fromlen));
1541 client = find_client('T', (struct sockaddr *)&from, NULL);
1543 printf("ignoring request, not a known TLS client\n");
1544 shutdown(snew, SHUT_RDWR);
1549 if (client->peer.ssl) {
1550 printf("Ignoring incoming connection, already have one from this client\n");
1551 shutdown(snew, SHUT_RDWR);
1555 client->peer.ssl = SSL_new(ssl_ctx);
1556 SSL_set_fd(client->peer.ssl, snew);
1557 if (pthread_create(&tlsserverth, NULL, tlsserverrd, (void *)client))
1558 errx("pthread_create failed");
1559 pthread_detach(tlsserverth);
1564 char *parsehostport(char *s, struct peer *peer) {
1569 /* allow literal addresses and port, e.g. [2001:db8::1]:1812 */
1573 for (; *p && *p != ']' && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1575 printf("no ] matching initial [\n");
1581 for (; *p && *p != ':' && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1584 printf("missing host/address\n");
1587 peer->host = stringcopy(field, p - field);
1590 if (*p && *p != ':' && *p != ' ' && *p != '\t' && *p != '\n') {
1591 printf("unexpected character after ]\n");
1596 /* port number or service name is specified */;
1598 for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1600 printf("syntax error, : but no following port\n");
1603 peer->port = stringcopy(field, p - field);
1605 peer->port = stringcopy(peer->type == 'U' ? DEFAULT_UDP_PORT : DEFAULT_TLS_PORT, 0);
1609 /* * is default, else longest match ... ";" used for separator */
1610 char *parserealmlist(char *s, struct server *server) {
1614 for (p = s, n = 1; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++)
1619 printf("realm list must be specified\n");
1622 server->realmdata = stringcopy(s, l);
1623 server->realms = malloc((1+n) * sizeof(char *));
1624 if (!server->realms)
1625 errx("malloc failed");
1626 server->realms[0] = server->realmdata;
1627 for (n = 1, i = 0; i < l; i++)
1628 if (server->realmdata[i] == ';') {
1629 server->realmdata[i] = '\0';
1630 server->realms[n++] = server->realmdata + i + 1;
1632 server->realms[n] = NULL;
1636 FILE *openconfigfile(const char *filename) {
1638 char pathname[100], *base;
1640 f = fopen(filename, "r");
1642 printf("reading config file %s\n", filename);
1646 if (strlen(filename) + 1 <= sizeof(pathname)) {
1647 /* basename() might modify the string */
1648 strcpy(pathname, filename);
1649 base = basename(pathname);
1650 f = fopen(base, "r");
1654 err("could not read config file %s nor %s\n", filename, base);
1656 printf("reading config file %s\n", base);
1660 /* exactly one argument must be non-NULL */
1661 void getconfig(const char *serverfile, const char *clientfile) {
1664 char *p, *field, **r;
1665 struct client *client;
1666 struct server *server;
1668 int i, count, *ucount, *tcount;
1670 f = openconfigfile(serverfile ? serverfile : clientfile);
1672 ucount = &server_udp_count;
1673 tcount = &server_tls_count;
1675 ucount = &client_udp_count;
1676 tcount = &client_tls_count;
1678 while (fgets(line, 1024, f)) {
1679 for (p = line; *p == ' ' || *p == '\t'; p++);
1691 printf("type must be U or T, got %c\n", *p);
1697 count = server_count = server_udp_count + server_tls_count;
1698 servers = calloc(count, sizeof(struct server));
1700 errx("malloc failed");
1702 count = client_count = client_udp_count + client_tls_count;
1703 clients = calloc(count, sizeof(struct client));
1705 errx("malloc failed");
1708 if (client_udp_count) {
1709 udp_server_replyq.replies = malloc(client_udp_count * MAX_REQUESTS * sizeof(struct reply));
1710 if (!udp_server_replyq.replies)
1711 errx("malloc failed");
1712 udp_server_replyq.size = client_udp_count * MAX_REQUESTS;
1713 udp_server_replyq.count = 0;
1714 pthread_mutex_init(&udp_server_replyq.count_mutex, NULL);
1715 pthread_cond_init(&udp_server_replyq.count_cond, NULL);
1719 for (i = 0; i < count && fgets(line, 1024, f);) {
1721 server = &servers[i];
1722 peer = &server->peer;
1724 client = &clients[i];
1725 peer = &client->peer;
1727 for (p = line; *p == ' ' || *p == '\t'; p++);
1728 if (*p == '#' || *p == '\n')
1730 peer->type = *p; /* we already know it must be U or T */
1731 for (p++; *p == ' ' || *p == '\t'; p++);
1732 p = parsehostport(p, peer);
1733 for (; *p == ' ' || *p == '\t'; p++);
1735 p = parserealmlist(p, server);
1736 for (; *p == ' ' || *p == '\t'; p++);
1739 for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1741 /* no secret set and end of line, line is complete if TLS */
1742 if (peer->type == 'U') {
1743 printf("secret must be specified for UDP\n");
1746 peer->secret = stringcopy(DEFAULT_TLS_SECRET, 0);
1748 peer->secret = stringcopy(field, p - field);
1749 /* check that rest of line only white space */
1750 for (; *p == ' ' || *p == '\t'; p++);
1751 if (*p && *p != '\n') {
1752 printf("max 4 fields per line, found a 5th\n");
1757 if ((serverfile && !resolvepeer(&server->peer, 0)) ||
1758 (clientfile && !resolvepeer(&client->peer, 0))) {
1759 printf("failed to resolve host %s port %s, exiting\n", peer->host, peer->port);
1764 pthread_mutex_init(&server->lock, NULL);
1766 server->requests = calloc(MAX_REQUESTS, sizeof(struct request));
1767 if (!server->requests)
1768 errx("malloc failed");
1770 pthread_mutex_init(&server->newrq_mutex, NULL);
1771 pthread_cond_init(&server->newrq_cond, NULL);
1773 if (peer->type == 'U')
1774 client->replyq = &udp_server_replyq;
1776 client->replyq = malloc(sizeof(struct replyq));
1777 if (!client->replyq)
1778 errx("malloc failed");
1779 client->replyq->replies = calloc(MAX_REQUESTS, sizeof(struct reply));
1780 if (!client->replyq->replies)
1781 errx("malloc failed");
1782 client->replyq->size = MAX_REQUESTS;
1783 client->replyq->count = 0;
1784 pthread_mutex_init(&client->replyq->count_mutex, NULL);
1785 pthread_cond_init(&client->replyq->count_cond, NULL);
1788 printf("got type %c, host %s, port %s, secret %s\n", peer->type, peer->host, peer->port, peer->secret);
1790 printf(" with realms:");
1791 for (r = server->realms; *r; r++)
1800 struct peer *server_create(char type) {
1801 struct peer *server;
1804 server = malloc(sizeof(struct peer));
1806 errx("malloc failed");
1807 memset(server, 0, sizeof(struct peer));
1808 server->type = type;
1809 conf = (type == 'T' ? options.listentcp : options.listenudp);
1811 parsehostport(conf, server);
1812 if (!strcmp(server->host, "*")) {
1814 server->host = NULL;
1816 } else if (type == 'T')
1817 server->port = stringcopy(DEFAULT_TLS_PORT, 0);
1819 server->port = stringcopy(options.udpserverport ? options.udpserverport : DEFAULT_UDP_PORT, 0);
1820 if (!resolvepeer(server, AI_PASSIVE)) {
1821 printf("failed to resolve host %s port %s, exiting\n", server->host, server->port);
1827 void getmainconfig(const char *configfile) {
1830 char *p, *opt, *endopt, *val, *endval;
1832 f = openconfigfile(configfile);
1833 memset(&options, 0, sizeof(options));
1835 while (fgets(line, 1024, f)) {
1836 for (p = line; *p == ' ' || *p == '\t'; p++);
1837 if (!*p || *p == '#' || *p == '\n')
1840 for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1842 for (; *p == ' ' || *p == '\t'; p++);
1843 if (!*p || *p == '\n') {
1845 printf("error in %s, option %s has no value\n", configfile, opt);
1849 for (; *p && *p != '\n'; p++)
1850 if (*p != ' ' && *p != '\t')
1854 printf("getmainconfig: %s = %s\n", opt, val);
1856 if (!strcasecmp(opt, "TLSCACertificateFile")) {
1857 options.tlscacertificatefile = stringcopy(val, 0);
1860 if (!strcasecmp(opt, "TLSCACertificatePath")) {
1861 options.tlscacertificatepath = stringcopy(val, 0);
1864 if (!strcasecmp(opt, "TLSCertificateFile")) {
1865 options.tlscertificatefile = stringcopy(val, 0);
1868 if (!strcasecmp(opt, "TLSCertificateKeyFile")) {
1869 options.tlscertificatekeyfile = stringcopy(val, 0);
1872 if (!strcasecmp(opt, "TLSCertificateKeyPassword")) {
1873 options.tlscertificatekeypassword = stringcopy(val, 0);
1876 if (!strcasecmp(opt, "UDPServerPort")) {
1877 options.udpserverport = stringcopy(val, 0);
1880 if (!strcasecmp(opt, "ListenUDP")) {
1881 options.listenudp = stringcopy(val, 0);
1884 if (!strcasecmp(opt, "ListenTCP")) {
1885 options.listentcp = stringcopy(val, 0);
1888 printf("error in %s, unknown option %s\n", configfile, opt);
1895 void parseargs(int argc, char **argv) {
1898 while ((c = getopt(argc, argv, "p:")) != -1) {
1901 udp_server_port = optarg;
1911 printf("radsecproxy [ -p UDP-port ]\n");
1916 int main(int argc, char **argv) {
1917 pthread_t udpserverth;
1918 /* pthread_attr_t joinable; */
1921 /* parseargs(argc, argv); */
1922 getmainconfig(CONFIG_MAIN);
1923 getconfig(CONFIG_SERVERS, NULL);
1924 getconfig(NULL, CONFIG_CLIENTS);
1926 /* pthread_attr_init(&joinable); */
1927 /* pthread_attr_setdetachstate(&joinable, PTHREAD_CREATE_JOINABLE); */
1929 if (client_udp_count) {
1930 udp_server_listen = server_create('U');
1931 if (pthread_create(&udpserverth, NULL /*&joinable*/, udpserverrd, NULL))
1932 errx("pthread_create failed");
1935 if (client_tls_count || server_tls_count)
1936 ssl_ctx = ssl_init();
1938 for (i = 0; i < server_count; i++)
1939 if (pthread_create(&servers[i].clientth, NULL, clientwr, (void *)&servers[i]))
1940 errx("pthread_create failed");
1942 if (client_tls_count) {
1943 tcp_server_listen = server_create('T');
1944 return tlslistener();
1947 /* just hang around doing nothing, anything to do here? */