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.
10 * peers can not yet be specified with literal IPv6 addresses due to port syntax
14 * make our server ignore client retrans and do its own instead?
15 * tls keep alives (server status)
16 * tls certificate validation
19 /* For UDP there is one server instance consisting of udpserverrd and udpserverth
20 * rd is responsible for init and launching wr
21 * For TLS there is a server instance that launches tlsserverrd for each TLS peer
22 * each tlsserverrd launches tlsserverwr
23 * For each UDP/TLS peer there is clientrd and clientwr, clientwr is responsible
24 * for init and launching rd
26 * serverrd will receive a request, processes it and puts it in the requestq of
27 * the appropriate clientwr
28 * clientwr monitors its requestq and sends requests
29 * clientrd looks for responses, processes them and puts them in the replyq of
30 * the peer the request came from
31 * serverwr monitors its reply and sends replies
33 * In addition to the main thread, we have:
34 * If UDP peers are configured, there will be 2 + 2 * #peers UDP threads
35 * If TLS peers are configured, there will initially be 2 * #peers TLS threads
36 * For each TLS peer connecting to us there will be 2 more TLS threads
37 * This is only for connected peers
38 * Example: With 3 UDP peer and 30 TLS peers, there will be a max of
39 * 1 + (2 + 2 * 3) + (2 * 30) + (2 * 30) = 129 threads
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 client clients[MAX_PEERS];
54 static struct server servers[MAX_PEERS];
56 static int client_count = 0;
57 static int server_count = 0;
59 static struct replyq udp_server_replyq;
60 static int udp_server_sock = -1;
61 static char *udp_server_port = DEFAULT_UDP_PORT;
62 static pthread_mutex_t *ssl_locks;
63 static long *ssl_lock_count;
64 static SSL_CTX *ssl_ctx_cl;
68 /* callbacks for making OpenSSL thread safe */
69 unsigned long ssl_thread_id() {
70 return (unsigned long)pthread_self();
73 void ssl_locking_callback(int mode, int type, const char *file, int line) {
74 if (mode & CRYPTO_LOCK) {
75 pthread_mutex_lock(&ssl_locks[type]);
76 ssl_lock_count[type]++;
78 pthread_mutex_unlock(&ssl_locks[type]);
81 void ssl_locks_setup() {
84 ssl_locks = malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));
85 ssl_lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));
86 for (i = 0; i < CRYPTO_num_locks(); i++) {
87 ssl_lock_count[i] = 0;
88 pthread_mutex_init(&ssl_locks[i], NULL);
91 CRYPTO_set_id_callback(ssl_thread_id);
92 CRYPTO_set_locking_callback(ssl_locking_callback);
95 void printauth(char *s, unsigned char *t) {
98 for (i = 0; i < 16; i++)
99 printf("%02x ", t[i]);
103 int resolvepeer(struct peer *peer) {
104 struct addrinfo hints, *addrinfo;
106 memset(&hints, 0, sizeof(hints));
107 hints.ai_socktype = (peer->type == 'T' ? SOCK_STREAM : SOCK_DGRAM);
108 hints.ai_family = AF_UNSPEC;
109 if (getaddrinfo(peer->host, peer->port, &hints, &addrinfo)) {
110 err("resolvepeer: can't resolve %s port %s", peer->host, peer->port);
115 freeaddrinfo(peer->addrinfo);
116 peer->addrinfo = addrinfo;
120 int connecttoserver(struct addrinfo *addrinfo) {
122 struct addrinfo *res;
124 for (res = addrinfo; res; res = res->ai_next) {
125 s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
127 err("connecttoserver: socket failed");
130 if (connect(s, res->ai_addr, res->ai_addrlen) == 0)
132 err("connecttoserver: connect failed");
139 /* returns the client with matching address, or NULL */
140 /* if client argument is not NULL, we only check that one client */
141 struct client *find_client(char type, struct sockaddr *addr, struct client *client) {
142 struct sockaddr_in6 *sa6;
143 struct in_addr *a4 = NULL;
146 struct addrinfo *res;
148 if (addr->sa_family == AF_INET6) {
149 sa6 = (struct sockaddr_in6 *)addr;
150 if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
151 a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12];
153 a4 = &((struct sockaddr_in *)addr)->sin_addr;
155 c = (client ? client : clients);
156 for (i = 0; i < client_count; i++) {
157 if (c->peer.type == type)
158 for (res = c->peer.addrinfo; res; res = res->ai_next)
159 if ((a4 && res->ai_family == AF_INET &&
160 !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) ||
161 (res->ai_family == AF_INET6 &&
162 !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16)))
171 /* returns the server with matching address, or NULL */
172 /* if server argument is not NULL, we only check that one server */
173 struct server *find_server(char type, struct sockaddr *addr, struct server *server) {
174 struct sockaddr_in6 *sa6;
175 struct in_addr *a4 = NULL;
178 struct addrinfo *res;
180 if (addr->sa_family == AF_INET6) {
181 sa6 = (struct sockaddr_in6 *)addr;
182 if (IN6_IS_ADDR_V4MAPPED(&sa6->sin6_addr))
183 a4 = (struct in_addr *)&sa6->sin6_addr.s6_addr[12];
185 a4 = &((struct sockaddr_in *)addr)->sin_addr;
187 s = (server ? server : servers);
188 for (i = 0; i < server_count; i++) {
189 if (s->peer.type == type)
190 for (res = s->peer.addrinfo; res; res = res->ai_next)
191 if ((a4 && res->ai_family == AF_INET &&
192 !memcmp(a4, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4)) ||
193 (res->ai_family == AF_INET6 &&
194 !memcmp(&sa6->sin6_addr, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16)))
203 /* exactly one of client and server must be non-NULL */
204 /* if *peer == NULL we return who we received from, else require it to be from peer */
205 /* return from in sa if not NULL */
206 unsigned char *radudpget(int s, struct client **client, struct server **server, struct sockaddr_storage *sa) {
209 unsigned char buf[65536], *rad;
210 struct sockaddr_storage from;
211 socklen_t fromlen = sizeof(from);
214 cnt = recvfrom(s, buf, sizeof(buf), 0, (struct sockaddr *)&from, &fromlen);
216 err("radudpget: recv failed");
219 printf("radudpget: got %d bytes from %s\n", cnt, addr2string((struct sockaddr *)&from, fromlen));
222 printf("radudpget: packet too small\n");
229 printf("radudpget: packet smaller than length field in radius header\n");
233 printf("radudpget: packet was padded with %d bytes\n", cnt - len);
236 ? (void *)find_client('U', (struct sockaddr *)&from, *client)
237 : (void *)find_server('U', (struct sockaddr *)&from, *server));
239 printf("radudpget: got packet from wrong or unknown UDP peer, ignoring\n");
246 err("radudpget: malloc failed");
248 memcpy(rad, buf, len);
250 *client = (struct client *)f; /* only need this if *client == NULL, but if not NULL *client == f here */
252 *server = (struct server *)f; /* only need this if *server == NULL, but if not NULL *server == f here */
258 void tlsconnect(struct server *server, struct timeval *when, char *text) {
263 printf("tlsconnect called from %s\n", text);
264 pthread_mutex_lock(&server->lock);
265 if (when && memcmp(&server->lastconnecttry, when, sizeof(struct timeval))) {
266 /* already reconnected, nothing to do */
267 printf("tlsconnect(%s): seems already reconnected\n", text);
268 pthread_mutex_unlock(&server->lock);
272 printf("tlsconnect %s\n", text);
275 gettimeofday(&now, NULL);
276 elapsed = now.tv_sec - server->lastconnecttry.tv_sec;
277 if (server->connectionok) {
278 server->connectionok = 0;
280 } else if (elapsed < 5)
282 else if (elapsed < 600)
284 else if (elapsed < 10000) /* no sleep at startup */
286 printf("tlsconnect: trying to open TLS connection to %s port %s\n", server->peer.host, server->peer.port);
287 if (server->sock >= 0)
289 if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0)
291 SSL_free(server->peer.ssl);
292 server->peer.ssl = SSL_new(ssl_ctx_cl);
293 SSL_set_fd(server->peer.ssl, server->sock);
294 if (SSL_connect(server->peer.ssl) > 0)
296 while ((error = ERR_get_error()))
297 err("tlsconnect: TLS: %s", ERR_error_string(error, NULL));
299 printf("tlsconnect: TLS connection to %s port %s up\n", server->peer.host, server->peer.port);
300 gettimeofday(&server->lastconnecttry, NULL);
301 pthread_mutex_unlock(&server->lock);
304 unsigned char *radtlsget(SSL *ssl) {
306 unsigned char buf[4], *rad;
309 for (total = 0; total < 4; total += cnt) {
310 cnt = SSL_read(ssl, buf + total, 4 - total);
312 printf("radtlsget: connection lost\n");
320 err("radtlsget: malloc failed");
325 for (; total < len; total += cnt) {
326 cnt = SSL_read(ssl, rad + total, len - total);
328 printf("radtlsget: connection lost\n");
338 printf("radtlsget: packet smaller than minimum radius size\n");
341 printf("radtlsget: got %d bytes\n", total);
345 int clientradput(struct server *server, unsigned char *rad) {
349 struct timeval lastconnecttry;
352 if (server->peer.type == 'U') {
353 if (send(server->sock, rad, len, 0) >= 0) {
354 printf("clienradput: sent UDP of length %d to %s port %s\n", len, server->peer.host, server->peer.port);
357 err("clientradput: send failed");
361 lastconnecttry = server->lastconnecttry;
362 while ((cnt = SSL_write(server->peer.ssl, rad, len)) <= 0) {
363 while ((error = ERR_get_error()))
364 err("clientwr: TLS: %s", ERR_error_string(error, NULL));
365 tlsconnect(server, &lastconnecttry, "clientradput");
366 lastconnecttry = server->lastconnecttry;
369 server->connectionok = 1;
370 printf("clientradput: Sent %d bytes, Radius packet of length %d to TLS peer %s\n",
371 cnt, len, server->peer.host);
375 int radsign(unsigned char *rad, unsigned char *sec) {
376 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
377 static unsigned char first = 1;
378 static EVP_MD_CTX mdctx;
382 pthread_mutex_lock(&lock);
384 EVP_MD_CTX_init(&mdctx);
388 result = (EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) &&
389 EVP_DigestUpdate(&mdctx, rad, RADLEN(rad)) &&
390 EVP_DigestUpdate(&mdctx, sec, strlen(sec)) &&
391 EVP_DigestFinal_ex(&mdctx, rad + 4, &md_len) &&
393 pthread_mutex_unlock(&lock);
397 int validauth(unsigned char *rad, unsigned char *reqauth, unsigned char *sec) {
398 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
399 static unsigned char first = 1;
400 static EVP_MD_CTX mdctx;
401 unsigned char hash[EVP_MAX_MD_SIZE];
405 pthread_mutex_lock(&lock);
407 EVP_MD_CTX_init(&mdctx);
413 result = (EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) &&
414 EVP_DigestUpdate(&mdctx, rad, 4) &&
415 EVP_DigestUpdate(&mdctx, reqauth, 16) &&
416 (len <= 20 || EVP_DigestUpdate(&mdctx, rad + 20, len - 20)) &&
417 EVP_DigestUpdate(&mdctx, sec, strlen(sec)) &&
418 EVP_DigestFinal_ex(&mdctx, hash, &len) &&
420 !memcmp(hash, rad + 4, 16));
421 pthread_mutex_unlock(&lock);
425 int checkmessageauth(char *rad, uint8_t *authattr, char *secret) {
426 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
427 static unsigned char first = 1;
428 static HMAC_CTX hmacctx;
430 uint8_t auth[16], hash[EVP_MAX_MD_SIZE];
432 pthread_mutex_lock(&lock);
434 HMAC_CTX_init(&hmacctx);
438 memcpy(auth, authattr, 16);
439 memset(authattr, 0, 16);
441 HMAC_Init_ex(&hmacctx, secret, strlen(secret), EVP_md5(), NULL);
442 HMAC_Update(&hmacctx, rad, RADLEN(rad));
443 HMAC_Final(&hmacctx, hash, &md_len);
444 memcpy(authattr, auth, 16);
446 printf("message auth computation failed\n");
447 pthread_mutex_unlock(&lock);
451 if (memcmp(auth, hash, 16)) {
452 printf("message authenticator, wrong value\n");
453 pthread_mutex_unlock(&lock);
457 pthread_mutex_unlock(&lock);
461 int createmessageauth(char *rad, char *authattrval, char *secret) {
462 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
463 static unsigned char first = 1;
464 static HMAC_CTX hmacctx;
470 pthread_mutex_lock(&lock);
472 HMAC_CTX_init(&hmacctx);
476 memset(authattrval, 0, 16);
478 HMAC_Init_ex(&hmacctx, secret, strlen(secret), EVP_md5(), NULL);
479 HMAC_Update(&hmacctx, rad, RADLEN(rad));
480 HMAC_Final(&hmacctx, authattrval, &md_len);
482 printf("message auth computation failed\n");
483 pthread_mutex_unlock(&lock);
487 pthread_mutex_unlock(&lock);
491 void sendrq(struct server *to, struct client *from, struct request *rq) {
494 pthread_mutex_lock(&to->newrq_mutex);
496 /* should search from where inserted last */
497 for (i = 0; i < MAX_REQUESTS; i++)
498 if (!to->requests[i].buf)
500 if (i == MAX_REQUESTS) {
501 printf("No room in queue, dropping request\n");
502 pthread_mutex_unlock(&to->newrq_mutex);
505 rq->buf[1] = (char)i;
507 if (!createmessageauth(rq->buf, rq->messageauthattrval, to->peer.secret))
510 gettimeofday(&rq->expiry, NULL);
511 rq->expiry.tv_sec += 30;
512 to->requests[i] = *rq;
516 printf("signalling client writer\n");
517 pthread_cond_signal(&to->newrq_cond);
519 pthread_mutex_unlock(&to->newrq_mutex);
522 void sendreply(struct client *to, struct server *from, char *buf, struct sockaddr_storage *tosa) {
523 struct replyq *replyq = to->replyq;
525 pthread_mutex_lock(&replyq->count_mutex);
526 if (replyq->count == replyq->size) {
527 printf("No room in queue, dropping request\n");
528 pthread_mutex_unlock(&replyq->count_mutex);
532 replyq->replies[replyq->count].buf = buf;
534 replyq->replies[replyq->count].tosa = *tosa;
537 if (replyq->count == 1) {
538 printf("signalling client writer\n");
539 pthread_cond_signal(&replyq->count_cond);
541 pthread_mutex_unlock(&replyq->count_mutex);
544 int pwdencrypt(uint8_t *out, uint8_t *in, uint8_t len, uint8_t *shared, uint8_t sharedlen,
546 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
547 static unsigned char first = 1;
548 static EVP_MD_CTX mdctx;
549 unsigned char hash[EVP_MAX_MD_SIZE], *input;
551 uint8_t i, offset = 0;
553 pthread_mutex_lock(&lock);
555 EVP_MD_CTX_init(&mdctx);
561 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
562 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
563 !EVP_DigestUpdate(&mdctx, input, 16) ||
564 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
566 pthread_mutex_unlock(&lock);
569 for (i = 0; i < 16; i++)
570 out[offset + i] = hash[i] ^ in[offset + i];
571 input = out + offset - 16;
576 pthread_mutex_unlock(&lock);
580 int pwddecrypt(uint8_t *out, uint8_t *in, uint8_t len, uint8_t *shared, uint8_t sharedlen,
582 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
583 static unsigned char first = 1;
584 static EVP_MD_CTX mdctx;
585 unsigned char hash[EVP_MAX_MD_SIZE], *input;
587 uint8_t i, offset = 0;
589 pthread_mutex_lock(&lock);
591 EVP_MD_CTX_init(&mdctx);
597 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
598 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
599 !EVP_DigestUpdate(&mdctx, input, 16) ||
600 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
602 pthread_mutex_unlock(&lock);
605 for (i = 0; i < 16; i++)
606 out[offset + i] = hash[i] ^ in[offset + i];
612 pthread_mutex_unlock(&lock);
616 int msmppencrypt(uint8_t *text, uint8_t len, uint8_t *shared, uint8_t sharedlen, uint8_t *auth, uint8_t *salt) {
617 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
618 static unsigned char first = 1;
619 static EVP_MD_CTX mdctx;
620 unsigned char hash[EVP_MAX_MD_SIZE];
624 pthread_mutex_lock(&lock);
626 EVP_MD_CTX_init(&mdctx);
631 printf("msppencrypt auth in: ");
632 for (i = 0; i < 16; i++)
633 printf("%02x ", auth[i]);
636 printf("msppencrypt salt in: ");
637 for (i = 0; i < 2; i++)
638 printf("%02x ", salt[i]);
641 printf("msppencrypt in: ");
642 for (i = 0; i < len; i++)
643 printf("%02x ", text[i]);
647 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
648 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
649 !EVP_DigestUpdate(&mdctx, auth, 16) ||
650 !EVP_DigestUpdate(&mdctx, salt, 2) ||
651 !EVP_DigestFinal_ex(&mdctx, hash, &md_len)) {
652 pthread_mutex_unlock(&lock);
657 printf("msppencrypt hash: ");
658 for (i = 0; i < 16; i++)
659 printf("%02x ", hash[i]);
663 for (i = 0; i < 16; i++)
666 for (offset = 16; offset < len; offset += 16) {
667 printf("text + offset - 16 c(%d): ", offset / 16);
668 for (i = 0; i < 16; i++)
669 printf("%02x ", (text + offset - 16)[i]);
672 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
673 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
674 !EVP_DigestUpdate(&mdctx, text + offset - 16, 16) ||
675 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
677 pthread_mutex_unlock(&lock);
681 printf("msppencrypt hash: ");
682 for (i = 0; i < 16; i++)
683 printf("%02x ", hash[i]);
687 for (i = 0; i < 16; i++)
688 text[offset + i] ^= hash[i];
692 printf("msppencrypt out: ");
693 for (i = 0; i < len; i++)
694 printf("%02x ", text[i]);
698 pthread_mutex_unlock(&lock);
702 int msmppdecrypt(uint8_t *text, uint8_t len, uint8_t *shared, uint8_t sharedlen, uint8_t *auth, uint8_t *salt) {
703 static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
704 static unsigned char first = 1;
705 static EVP_MD_CTX mdctx;
706 unsigned char hash[EVP_MAX_MD_SIZE];
711 pthread_mutex_lock(&lock);
713 EVP_MD_CTX_init(&mdctx);
718 printf("msppdecrypt auth in: ");
719 for (i = 0; i < 16; i++)
720 printf("%02x ", auth[i]);
723 printf("msppedecrypt salt in: ");
724 for (i = 0; i < 2; i++)
725 printf("%02x ", salt[i]);
728 printf("msppedecrypt in: ");
729 for (i = 0; i < len; i++)
730 printf("%02x ", text[i]);
734 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
735 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
736 !EVP_DigestUpdate(&mdctx, auth, 16) ||
737 !EVP_DigestUpdate(&mdctx, salt, 2) ||
738 !EVP_DigestFinal_ex(&mdctx, hash, &md_len)) {
739 pthread_mutex_unlock(&lock);
744 printf("msppedecrypt hash: ");
745 for (i = 0; i < 16; i++)
746 printf("%02x ", hash[i]);
750 for (i = 0; i < 16; i++)
751 plain[i] = text[i] ^ hash[i];
753 for (offset = 16; offset < len; offset += 16) {
755 printf("text + offset - 16 c(%d): ", offset / 16);
756 for (i = 0; i < 16; i++)
757 printf("%02x ", (text + offset - 16)[i]);
760 if (!EVP_DigestInit_ex(&mdctx, EVP_md5(), NULL) ||
761 !EVP_DigestUpdate(&mdctx, shared, sharedlen) ||
762 !EVP_DigestUpdate(&mdctx, text + offset - 16, 16) ||
763 !EVP_DigestFinal_ex(&mdctx, hash, &md_len) ||
765 pthread_mutex_unlock(&lock);
769 printf("msppedecrypt hash: ");
770 for (i = 0; i < 16; i++)
771 printf("%02x ", hash[i]);
775 for (i = 0; i < 16; i++)
776 plain[offset + i] = text[offset + i] ^ hash[i];
779 memcpy(text, plain, len);
781 printf("msppedecrypt out: ");
782 for (i = 0; i < len; i++)
783 printf("%02x ", text[i]);
787 pthread_mutex_unlock(&lock);
791 struct server *id2server(char *id, uint8_t len) {
793 char **realm, *idrealm;
795 idrealm = strchr(id, '@');
803 for (i = 0; i < server_count; i++) {
804 for (realm = servers[i].realms; *realm; realm++) {
805 if ((strlen(*realm) == 1 && **realm == '*') ||
806 (strlen(*realm) == len && !memcmp(idrealm, *realm, len))) {
807 printf("found matching realm: %s, host %s\n", *realm, servers[i].peer.host);
815 struct server *radsrv(struct request *rq, char *buf, struct client *from) {
816 uint8_t code, id, *auth, *attr, pwd[128], attrvallen;
817 uint8_t *usernameattr = NULL, *userpwdattr = NULL, *tunnelpwdattr = NULL, *messageauthattr = NULL;
822 unsigned char newauth[16];
824 code = *(uint8_t *)buf;
825 id = *(uint8_t *)(buf + 1);
827 auth = (uint8_t *)(buf + 4);
829 printf("radsrv: code %d, id %d, length %d\n", code, id, len);
831 if (code != RAD_Access_Request) {
832 printf("radsrv: server currently accepts only access-requests, ignoring\n");
840 left -= attr[RAD_Attr_Length];
842 printf("radsrv: attribute length exceeds packet length, ignoring packet\n");
845 switch (attr[RAD_Attr_Type]) {
846 case RAD_Attr_User_Name:
849 case RAD_Attr_User_Password:
852 case RAD_Attr_Tunnel_Password:
853 tunnelpwdattr = attr;
855 case RAD_Attr_Message_Authenticator:
856 messageauthattr = attr;
859 attr += attr[RAD_Attr_Length];
862 printf("radsrv: malformed packet? remaining byte after last attribute\n");
865 printf("radsrv: Username: ");
866 for (i = 0; i < usernameattr[RAD_Attr_Length] - 2; i++)
867 printf("%c", usernameattr[RAD_Attr_Value + i]);
871 to = id2server(&usernameattr[RAD_Attr_Value], usernameattr[RAD_Attr_Length] - 2);
873 printf("radsrv: ignoring request, don't know where to send it\n");
877 if (messageauthattr && (messageauthattr[RAD_Attr_Length] != 18 ||
878 !checkmessageauth(buf, &messageauthattr[RAD_Attr_Value], from->peer.secret))) {
879 printf("radsrv: message authentication failed\n");
883 if (!RAND_bytes(newauth, 16)) {
884 printf("radsrv: failed to generate random auth\n");
888 printauth("auth", auth);
889 printauth("newauth", newauth);
892 printf("radsrv: found userpwdattr of length %d\n", userpwdattr[RAD_Attr_Length]);
893 attrvallen = userpwdattr[RAD_Attr_Length] - 2;
894 if (attrvallen < 16 || attrvallen > 128 || attrvallen % 16) {
895 printf("radsrv: invalid user password length\n");
899 if (!pwddecrypt(pwd, &userpwdattr[RAD_Attr_Value], attrvallen, from->peer.secret, strlen(from->peer.secret), auth)) {
900 printf("radsrv: cannot decrypt password\n");
903 printf("radsrv: password: ");
904 for (i = 0; i < attrvallen; i++)
905 printf("%02x ", pwd[i]);
907 if (!pwdencrypt(&userpwdattr[RAD_Attr_Value], pwd, attrvallen, to->peer.secret, strlen(to->peer.secret), newauth)) {
908 printf("radsrv: cannot encrypt password\n");
914 printf("radsrv: found tunnelpwdattr of length %d\n", tunnelpwdattr[RAD_Attr_Length]);
915 attrvallen = tunnelpwdattr[RAD_Attr_Length] - 2;
916 if (attrvallen < 16 || attrvallen > 128 || attrvallen % 16) {
917 printf("radsrv: invalid user password length\n");
921 if (!pwddecrypt(pwd, &tunnelpwdattr[RAD_Attr_Value], attrvallen, from->peer.secret, strlen(from->peer.secret), auth)) {
922 printf("radsrv: cannot decrypt password\n");
925 printf("radsrv: password: ");
926 for (i = 0; i < attrvallen; i++)
927 printf("%02x ", pwd[i]);
929 if (!pwdencrypt(&tunnelpwdattr[RAD_Attr_Value], pwd, attrvallen, to->peer.secret, strlen(to->peer.secret), newauth)) {
930 printf("radsrv: cannot encrypt password\n");
938 rq->messageauthattrval = (messageauthattr ? &messageauthattr[RAD_Attr_Value] : NULL);
939 memcpy(rq->origauth, auth, 16);
940 memcpy(auth, newauth, 16);
941 printauth("rq->origauth", rq->origauth);
942 printauth("auth", auth);
946 void *clientrd(void *arg) {
947 struct server *server = (struct server *)arg;
949 int i, left, subleft;
950 unsigned char *buf, *messageauthattr, *subattr, *attr;
951 struct sockaddr_storage fromsa;
952 struct timeval lastconnecttry;
957 lastconnecttry = server->lastconnecttry;
958 buf = (server->peer.type == 'U' ? radudpget(server->sock, NULL, &server, NULL) : radtlsget(server->peer.ssl));
959 if (!buf && server->peer.type == 'T') {
960 tlsconnect(server, &lastconnecttry, "clientrd");
964 server->connectionok = 1;
966 if (*buf != RAD_Access_Accept && *buf != RAD_Access_Reject && *buf != RAD_Access_Challenge) {
967 printf("clientrd: discarding, only accept access accept, access reject and access challenge messages\n");
971 i = buf[1]; /* i is the id */
973 pthread_mutex_lock(&server->newrq_mutex);
974 if (!server->requests[i].buf || !server->requests[i].tries) {
975 pthread_mutex_unlock(&server->newrq_mutex);
976 printf("clientrd: no matching request sent with this id, ignoring\n");
980 if (server->requests[i].received) {
981 pthread_mutex_unlock(&server->newrq_mutex);
982 printf("clientrd: already received, ignoring\n");
986 if (!validauth(buf, server->requests[i].buf + 4, server->peer.secret)) {
987 pthread_mutex_unlock(&server->newrq_mutex);
988 printf("clientrd: invalid auth, ignoring\n");
992 from = server->requests[i].from;
995 /* messageauthattr present? */
996 messageauthattr = NULL;
997 left = RADLEN(buf) - 20;
1000 left -= attr[RAD_Attr_Length];
1002 printf("clientrd: attribute length exceeds packet length, ignoring packet\n");
1005 if (attr[RAD_Attr_Type] == RAD_Attr_Message_Authenticator) {
1006 if (attr[RAD_Attr_Length] != 18) {
1007 printf("clientrd: illegal message auth attribute length, ignoring packet\n");
1010 memcpy(tmp, buf + 4, 16);
1011 memcpy(buf + 4, server->requests[i].buf + 4, 16);
1012 if (!checkmessageauth(buf, &attr[RAD_Attr_Value], server->peer.secret)) {
1013 printf("clientrd: message authentication failed\n");
1016 memcpy(buf + 4, tmp, 16);
1017 printf("clientrd: message auth ok\n");
1018 messageauthattr = attr;
1021 attr += attr[RAD_Attr_Length];
1024 /* handle MS MPPE */
1025 left = RADLEN(buf) - 20;
1028 left -= attr[RAD_Attr_Length];
1030 printf("clientrd: attribute length exceeds packet length, ignoring packet\n");
1033 if (attr[RAD_Attr_Type] == RAD_Attr_Vendor_Specific &&
1034 ((uint16_t *)attr)[1] == 0 && ntohs(((uint16_t *)attr)[2]) == 311) { // 311 == MS
1035 subleft = attr[RAD_Attr_Length] - 6;
1037 while (subleft > 1) {
1038 subleft -= subattr[RAD_Attr_Length];
1041 if (subattr[RAD_Attr_Type] != RAD_VS_ATTR_MS_MPPE_Send_Key &&
1042 subattr[RAD_Attr_Type] != RAD_VS_ATTR_MS_MPPE_Recv_Key)
1044 printf("clientrd: Got MS MPPE\n");
1045 if (subattr[RAD_Attr_Length] < 20)
1048 if (!msmppdecrypt(subattr + 4, subattr[RAD_Attr_Length] - 4,
1049 server->peer.secret, strlen(server->peer.secret), server->requests[i].buf + 4, subattr + 2)) {
1050 printf("clientrd: failed to decrypt msppe key\n");
1054 if (!msmppencrypt(subattr + 4, subattr[RAD_Attr_Length] - 4,
1055 from->peer.secret, strlen(from->peer.secret), server->requests[i].origauth, subattr + 2)) {
1056 printf("clientrd: failed to encrypt msppe key\n");
1061 printf("clientrd: bad vendor specific attr or subattr length, ignoring packet\n");
1065 attr += attr[RAD_Attr_Length];
1068 /* once we set received = 1, requests[i] may be reused */
1069 buf[1] = (char)server->requests[i].origid;
1070 memcpy(buf + 4, server->requests[i].origauth, 16);
1071 printauth("origauth/buf+4", buf + 4);
1072 if (messageauthattr) {
1073 if (!createmessageauth(buf, &messageauthattr[RAD_Attr_Value], from->peer.secret))
1075 printf("clientrd: computed messageauthattr\n");
1078 if (from->peer.type == 'U')
1079 fromsa = server->requests[i].fromsa;
1080 server->requests[i].received = 1;
1081 pthread_mutex_unlock(&server->newrq_mutex);
1083 if (!radsign(buf, from->peer.secret)) {
1084 printf("clientrd: failed to sign message\n");
1087 printauth("signedorigauth/buf+4", buf + 4);
1088 printf("clientrd: giving packet back to where it came from\n");
1089 sendreply(from, server, buf, from->peer.type == 'U' ? &fromsa : NULL);
1093 void *clientwr(void *arg) {
1094 struct server *server = (struct server *)arg;
1096 pthread_t clientrdth;
1100 if (server->peer.type == 'U') {
1101 if ((server->sock = connecttoserver(server->peer.addrinfo)) < 0) {
1102 printf("clientwr: connecttoserver failed\n");
1106 tlsconnect(server, NULL, "new client");
1108 if (pthread_create(&clientrdth, NULL, clientrd, (void *)server))
1109 errx("clientwr: pthread_create failed");
1112 pthread_mutex_lock(&server->newrq_mutex);
1113 while (!server->newrq) {
1114 printf("clientwr: waiting for signal\n");
1115 pthread_cond_wait(&server->newrq_cond, &server->newrq_mutex);
1116 printf("clientwr: got signal\n");
1119 pthread_mutex_unlock(&server->newrq_mutex);
1121 for (i = 0; i < MAX_REQUESTS; i++) {
1122 pthread_mutex_lock(&server->newrq_mutex);
1123 while (!server->requests[i].buf && i < MAX_REQUESTS)
1125 if (i == MAX_REQUESTS) {
1126 pthread_mutex_unlock(&server->newrq_mutex);
1130 gettimeofday(&now, NULL);
1131 rq = server->requests + i;
1134 printf("clientwr: removing received packet from queue\n");
1136 /* setting this to NULL means that it can be reused */
1138 pthread_mutex_unlock(&server->newrq_mutex);
1141 if (now.tv_sec > rq->expiry.tv_sec) {
1142 printf("clientwr: removing expired packet from queue\n");
1144 /* setting this to NULL means that it can be reused */
1146 pthread_mutex_unlock(&server->newrq_mutex);
1151 continue; // not re-sending (yet)
1154 pthread_mutex_unlock(&server->newrq_mutex);
1156 clientradput(server, server->requests[i].buf);
1159 /* should do more work to maintain TLS connections, keepalives etc */
1162 void *udpserverwr(void *arg) {
1163 struct replyq *replyq = &udp_server_replyq;
1164 struct reply *reply = replyq->replies;
1166 pthread_mutex_lock(&replyq->count_mutex);
1168 while (!replyq->count) {
1169 printf("udp server writer, waiting for signal\n");
1170 pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex);
1171 printf("udp server writer, got signal\n");
1173 pthread_mutex_unlock(&replyq->count_mutex);
1175 if (sendto(udp_server_sock, reply->buf, RADLEN(reply->buf), 0,
1176 (struct sockaddr *)&reply->tosa, SOCKADDR_SIZE(reply->tosa)) < 0)
1177 err("sendudp: send failed");
1180 pthread_mutex_lock(&replyq->count_mutex);
1182 memmove(replyq->replies, replyq->replies + 1,
1183 replyq->count * sizeof(struct reply));
1187 void *udpserverrd(void *arg) {
1192 pthread_t udpserverwrth;
1194 if ((udp_server_sock = bindport(SOCK_DGRAM, udp_server_port)) < 0) {
1195 printf("udpserverrd: socket/bind failed\n");
1198 printf("udpserverrd: listening on UDP port %s\n", udp_server_port);
1200 if (pthread_create(&udpserverwrth, NULL, udpserverwr, NULL))
1201 errx("pthread_create failed");
1205 memset(&rq, 0, sizeof(struct request));
1206 buf = radudpget(udp_server_sock, &fr, NULL, &rq.fromsa);
1207 to = radsrv(&rq, buf, fr);
1209 printf("udpserverrd: ignoring request, no place to send it\n");
1212 sendrq(to, fr, &rq);
1216 void *tlsserverwr(void *arg) {
1218 unsigned long error;
1219 struct client *client = (struct client *)arg;
1220 struct replyq *replyq;
1222 pthread_mutex_lock(&client->replycount_mutex);
1224 replyq = client->replyq;
1225 while (!replyq->count) {
1226 printf("tls server writer, waiting for signal\n");
1227 pthread_cond_wait(&replyq->count_cond, &replyq->count_mutex);
1228 printf("tls server writer, got signal\n");
1230 pthread_mutex_unlock(&replyq->count_mutex);
1231 cnt = SSL_write(client->peer.ssl, replyq->replies->buf, RADLEN(replyq->replies->buf));
1233 printf("tlsserverwr: Sent %d bytes, Radius packet of length %d\n",
1234 cnt, RADLEN(replyq->replies->buf));
1236 while ((error = ERR_get_error()))
1237 err("tlsserverwr: SSL: %s", ERR_error_string(error, NULL));
1238 free(replyq->replies->buf);
1240 pthread_mutex_lock(&replyq->count_mutex);
1242 memmove(replyq->replies, replyq->replies + 1, replyq->count * sizeof(struct reply));
1246 void *tlsserverrd(void *arg) {
1249 unsigned long error;
1252 struct client *client = (struct client *)arg;
1253 pthread_t tlsserverwrth;
1255 printf("tlsserverrd starting\n");
1256 if (SSL_accept(client->peer.ssl) <= 0) {
1257 while ((error = ERR_get_error()))
1258 err("tlsserverrd: SSL: %s", ERR_error_string(error, NULL));
1259 errx("accept failed, child exiting");
1262 if (pthread_create(&tlsserverwrth, NULL, tlsserverwr, (void *)client))
1263 errx("pthread_create failed");
1266 buf = radtlsget(client->peer.ssl);
1268 printf("tlsserverrd: connection lost\n");
1269 s = SSL_get_fd(client->peer.ssl);
1270 SSL_free(client->peer.ssl);
1271 client->peer.ssl = NULL;
1276 printf("tlsserverrd: got Radius message from %s\n", client->peer.host);
1277 memset(&rq, 0, sizeof(struct request));
1278 to = radsrv(&rq, buf, client);
1280 printf("ignoring request, no place to send it\n");
1283 sendrq(to, client, &rq);
1287 int tlslistener(SSL_CTX *ssl_ctx) {
1288 pthread_t tlsserverth;
1290 struct sockaddr_storage from;
1291 size_t fromlen = sizeof(from);
1292 struct client *client;
1294 if ((s = bindport(SOCK_STREAM, DEFAULT_TLS_PORT)) < 0) {
1295 printf("tlslistener: socket/bind failed\n");
1300 printf("listening for incoming TLS on port %s\n", DEFAULT_TLS_PORT);
1303 snew = accept(s, (struct sockaddr *)&from, &fromlen);
1305 errx("accept failed");
1306 printf("incoming TLS connection from %s\n", addr2string((struct sockaddr *)&from, fromlen));
1308 client = find_client('T', (struct sockaddr *)&from, NULL);
1310 printf("ignoring request, not a known TLS client\n");
1315 if (client->peer.ssl) {
1316 printf("Ignoring incoming connection, already have one from this client\n");
1320 client->peer.ssl = SSL_new(ssl_ctx);
1321 SSL_set_fd(client->peer.ssl, snew);
1322 if (pthread_create(&tlsserverth, NULL, tlsserverrd, (void *)client))
1323 errx("pthread_create failed");
1328 char *parsehostport(char *s, struct peer *peer) {
1333 // allow literal addresses and port, e.g. [2001:db8::1]:1812
1337 for (; *p && *p != ']' && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1339 printf("no ] matching initial [\n");
1345 for (; *p && *p != ':' && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1348 printf("missing host/address\n");
1351 peer->host = malloc(p - field + 1);
1353 errx("malloc failed");
1354 memcpy(peer->host, field, p - field);
1355 peer->host[p - field] = '\0';
1358 if (*p && *p != ':' && *p != ' ' && *p != '\t' && *p != '\n') {
1359 printf("unexpected character after ]\n");
1364 /* port number or service name is specified */;
1366 for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1368 printf("syntax error, : but no following port\n");
1371 peer->port = malloc(p - field + 1);
1373 errx("malloc failed");
1374 memcpy(peer->port, field, p - field);
1375 peer->port[p - field] = '\0';
1381 // * is default, else longest match ... ";" used for separator
1382 char *parserealmlist(char *s, struct server *server) {
1386 for (p = s, n = 1; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++)
1391 server->realms = NULL;
1394 server->realmdata = malloc(l + 1);
1395 if (!server->realmdata)
1396 errx("malloc failed");
1397 memcpy(server->realmdata, s, l);
1398 server->realmdata[l] = '\0';
1399 server->realms = malloc((1+n) * sizeof(char *));
1400 if (!server->realms)
1401 errx("malloc failed");
1402 server->realms[0] = server->realmdata;
1403 for (n = 1, i = 0; i < l; i++)
1404 if (server->realmdata[i] == ';') {
1405 server->realmdata[i] = '\0';
1406 server->realms[n++] = server->realmdata + i + 1;
1408 server->realms[n] = NULL;
1412 /* exactly one argument must be non-NULL */
1413 void getconfig(const char *serverfile, const char *clientfile) {
1416 char *p, *field, **r;
1417 struct client *client;
1418 struct server *server;
1423 printf("opening file %s for reading\n", serverfile);
1424 f = fopen(serverfile, "r");
1426 errx("getconfig failed to open %s for reading", serverfile);
1427 count = &server_count;
1429 printf("opening file %s for reading\n", clientfile);
1430 f = fopen(clientfile, "r");
1432 errx("getconfig failed to open %s for reading", clientfile);
1433 udp_server_replyq.replies = malloc(4 * MAX_REQUESTS * sizeof(struct reply));
1434 if (!udp_server_replyq.replies)
1435 errx("malloc failed");
1436 udp_server_replyq.size = 4 * MAX_REQUESTS;
1437 udp_server_replyq.count = 0;
1438 pthread_mutex_init(&udp_server_replyq.count_mutex, NULL);
1439 pthread_cond_init(&udp_server_replyq.count_cond, NULL);
1440 count = &client_count;
1444 while (fgets(line, 1024, f) && *count < MAX_PEERS) {
1446 server = &servers[*count];
1447 memset(server, 0, sizeof(struct server));
1448 peer = &server->peer;
1450 client = &clients[*count];
1451 memset(client, 0, sizeof(struct client));
1452 peer = &client->peer;
1454 for (p = line; *p == ' ' || *p == '\t'; p++);
1455 if (*p == '#' || *p == '\n')
1457 if (*p != 'U' && *p != 'T') {
1458 printf("server type must be U or T, got %c\n", *p);
1462 for (p++; *p == ' ' || *p == '\t'; p++);
1463 p = parsehostport(p, peer);
1465 peer->port = (peer->type == 'U' ? DEFAULT_UDP_PORT : DEFAULT_TLS_PORT);
1466 for (; *p == ' ' || *p == '\t'; p++);
1468 p = parserealmlist(p, server);
1469 if (!server->realms) {
1470 printf("realm list must be specified\n");
1473 for (; *p == ' ' || *p == '\t'; p++);
1476 for (; *p && *p != ' ' && *p != '\t' && *p != '\n'; p++);
1478 /* no secret set and end of line, line is complete if TLS */
1479 if (peer->type == 'U') {
1480 printf("secret must be specified for UDP\n");
1483 peer->secret = DEFAULT_TLS_SECRET;
1485 peer->secret = malloc(p - field + 1);
1487 errx("malloc failed");
1488 memcpy(peer->secret, field, p - field);
1489 peer->secret[p - field] = '\0';
1490 /* check that rest of line only white space */
1491 for (; *p == ' ' || *p == '\t'; p++);
1492 if (*p && *p != '\n') {
1493 printf("max 4 fields per line, found a 5th\n");
1498 if ((serverfile && !resolvepeer(&server->peer)) ||
1499 (clientfile && !resolvepeer(&client->peer))) {
1500 printf("failed to resolve host %s port %s, exiting\n", peer->host, peer->port);
1505 pthread_mutex_init(&server->lock, NULL);
1507 server->requests = malloc(MAX_REQUESTS * sizeof(struct request));
1508 if (!server->requests)
1509 errx("malloc failed");
1510 memset(server->requests, 0, MAX_REQUESTS * sizeof(struct request));
1512 pthread_mutex_init(&server->newrq_mutex, NULL);
1513 pthread_cond_init(&server->newrq_cond, NULL);
1515 if (peer->type == 'U')
1516 client->replyq = &udp_server_replyq;
1518 client->replyq = malloc(sizeof(struct replyq));
1519 if (!client->replyq)
1520 errx("malloc failed");
1521 client->replyq->replies = malloc(MAX_REQUESTS * sizeof(struct reply));
1522 if (!client->replyq->replies)
1523 errx("malloc failed");
1524 client->replyq->size = MAX_REQUESTS;
1525 client->replyq->count = 0;
1526 pthread_mutex_init(&client->replyq->count_mutex, NULL);
1527 pthread_cond_init(&client->replyq->count_cond, NULL);
1530 printf("got type %c, host %s, port %s, secret %s\n", peer->type, peer->host, peer->port, peer->secret);
1532 printf(" with realms:");
1533 for (r = server->realms; *r; r++)
1542 void parseargs(int argc, char **argv) {
1545 while ((c = getopt(argc, argv, "p:")) != -1) {
1548 udp_server_port = optarg;
1558 printf("radsecproxy [ -p UDP-port ]\n");
1562 int main(int argc, char **argv) {
1563 SSL_CTX *ssl_ctx_srv;
1564 unsigned long error;
1565 pthread_t udpserverth;
1566 pthread_attr_t joinable;
1569 parseargs(argc, argv);
1570 getconfig("servers.conf", NULL);
1571 getconfig(NULL, "clients.conf");
1575 pthread_attr_init(&joinable);
1576 pthread_attr_setdetachstate(&joinable, PTHREAD_CREATE_JOINABLE);
1578 /* listen on UDP if at least one UDP client */
1580 for (i = 0; i < client_count; i++)
1581 if (clients[i].peer.type == 'U') {
1582 if (pthread_create(&udpserverth, &joinable, udpserverrd, NULL))
1583 errx("pthread_create failed");
1588 SSL_load_error_strings();
1591 while (!RAND_status()) {
1592 time_t t = time(NULL);
1593 pid_t pid = getpid();
1594 RAND_seed((unsigned char *)&t, sizeof(time_t));
1595 RAND_seed((unsigned char *)&pid, sizeof(pid));
1598 /* initialise client part and start clients */
1599 ssl_ctx_cl = SSL_CTX_new(TLSv1_client_method());
1603 for (i = 0; i < server_count; i++) {
1604 if (pthread_create(&servers[i].clientth, NULL, clientwr, (void *)&servers[i]))
1605 errx("pthread_create failed");
1608 for (i = 0; i < client_count; i++)
1609 if (clients[i].peer.type == 'T')
1612 if (i == client_count) {
1613 printf("No TLS clients defined, not starting TLS listener\n");
1614 /* just hang around doing nothing, anything to do here? */
1619 /* setting up server/daemon part */
1620 ssl_ctx_srv = SSL_CTX_new(TLSv1_server_method());
1623 if (!SSL_CTX_use_certificate_file(ssl_ctx_srv, "/tmp/server.pem", SSL_FILETYPE_PEM)) {
1624 while ((error = ERR_get_error()))
1625 err("SSL: %s", ERR_error_string(error, NULL));
1626 errx("Failed to load certificate");
1628 if (!SSL_CTX_use_PrivateKey_file(ssl_ctx_srv, "/tmp/server.key", SSL_FILETYPE_PEM)) {
1629 while ((error = ERR_get_error()))
1630 err("SSL: %s", ERR_error_string(error, NULL));
1631 errx("Failed to load private key");
1634 return tlslistener(ssl_ctx_srv);