radlib.c revision 243956
1/*-
2 * Copyright 1998 Juniper Networks, Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 *    notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 *    notice, this list of conditions and the following disclaimer in the
12 *    documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/lib/libradius/radlib.c 243956 2012-12-06 19:00:37Z sem $");
29
30#include <sys/types.h>
31#include <sys/socket.h>
32#include <sys/time.h>
33#include <netinet/in.h>
34#include <arpa/inet.h>
35#ifdef WITH_SSL
36#include <openssl/hmac.h>
37#include <openssl/md5.h>
38#define MD5Init MD5_Init
39#define MD5Update MD5_Update
40#define MD5Final MD5_Final
41#else
42#define MD5_DIGEST_LENGTH 16
43#include <md5.h>
44#endif
45
46#define	MAX_FIELDS	7
47
48/* We need the MPPE_KEY_LEN define */
49#include <netgraph/ng_mppc.h>
50
51#include <errno.h>
52#include <netdb.h>
53#include <stdarg.h>
54#include <stddef.h>
55#include <stdio.h>
56#include <stdlib.h>
57#include <string.h>
58#include <unistd.h>
59
60#include "radlib_private.h"
61
62static void	 clear_password(struct rad_handle *);
63static void	 generr(struct rad_handle *, const char *, ...)
64		    __printflike(2, 3);
65static void	 insert_scrambled_password(struct rad_handle *, int);
66static void	 insert_request_authenticator(struct rad_handle *, int);
67static void	 insert_message_authenticator(struct rad_handle *, int);
68static int	 is_valid_response(struct rad_handle *, int,
69		    const struct sockaddr_in *);
70static int	 put_password_attr(struct rad_handle *, int,
71		    const void *, size_t);
72static int	 put_raw_attr(struct rad_handle *, int,
73		    const void *, size_t);
74static int	 split(char *, char *[], int, char *, size_t);
75
76static void
77clear_password(struct rad_handle *h)
78{
79	if (h->pass_len != 0) {
80		memset(h->pass, 0, h->pass_len);
81		h->pass_len = 0;
82	}
83	h->pass_pos = 0;
84}
85
86static void
87generr(struct rad_handle *h, const char *format, ...)
88{
89	va_list		 ap;
90
91	va_start(ap, format);
92	vsnprintf(h->errmsg, ERRSIZE, format, ap);
93	va_end(ap);
94}
95
96static void
97insert_scrambled_password(struct rad_handle *h, int srv)
98{
99	MD5_CTX ctx;
100	unsigned char md5[MD5_DIGEST_LENGTH];
101	const struct rad_server *srvp;
102	int padded_len;
103	int pos;
104
105	srvp = &h->servers[srv];
106	padded_len = h->pass_len == 0 ? 16 : (h->pass_len+15) & ~0xf;
107
108	memcpy(md5, &h->out[POS_AUTH], LEN_AUTH);
109	for (pos = 0;  pos < padded_len;  pos += 16) {
110		int i;
111
112		/* Calculate the new scrambler */
113		MD5Init(&ctx);
114		MD5Update(&ctx, srvp->secret, strlen(srvp->secret));
115		MD5Update(&ctx, md5, 16);
116		MD5Final(md5, &ctx);
117
118		/*
119		 * Mix in the current chunk of the password, and copy
120		 * the result into the right place in the request.  Also
121		 * modify the scrambler in place, since we will use this
122		 * in calculating the scrambler for next time.
123		 */
124		for (i = 0;  i < 16;  i++)
125			h->out[h->pass_pos + pos + i] =
126			    md5[i] ^= h->pass[pos + i];
127	}
128}
129
130static void
131insert_request_authenticator(struct rad_handle *h, int resp)
132{
133	MD5_CTX ctx;
134	const struct rad_server *srvp;
135
136	srvp = &h->servers[h->srv];
137
138	/* Create the request authenticator */
139	MD5Init(&ctx);
140	MD5Update(&ctx, &h->out[POS_CODE], POS_AUTH - POS_CODE);
141	if (resp)
142	    MD5Update(&ctx, &h->in[POS_AUTH], LEN_AUTH);
143	else
144	    MD5Update(&ctx, &h->out[POS_AUTH], LEN_AUTH);
145	MD5Update(&ctx, &h->out[POS_ATTRS], h->out_len - POS_ATTRS);
146	MD5Update(&ctx, srvp->secret, strlen(srvp->secret));
147	MD5Final(&h->out[POS_AUTH], &ctx);
148}
149
150static void
151insert_message_authenticator(struct rad_handle *h, int resp)
152{
153#ifdef WITH_SSL
154	u_char md[EVP_MAX_MD_SIZE];
155	u_int md_len;
156	const struct rad_server *srvp;
157	HMAC_CTX ctx;
158	srvp = &h->servers[h->srv];
159
160	if (h->authentic_pos != 0) {
161		HMAC_CTX_init(&ctx);
162		HMAC_Init(&ctx, srvp->secret, strlen(srvp->secret), EVP_md5());
163		HMAC_Update(&ctx, &h->out[POS_CODE], POS_AUTH - POS_CODE);
164		if (resp)
165		    HMAC_Update(&ctx, &h->in[POS_AUTH], LEN_AUTH);
166		else
167		    HMAC_Update(&ctx, &h->out[POS_AUTH], LEN_AUTH);
168		HMAC_Update(&ctx, &h->out[POS_ATTRS],
169		    h->out_len - POS_ATTRS);
170		HMAC_Final(&ctx, md, &md_len);
171		HMAC_CTX_cleanup(&ctx);
172		HMAC_cleanup(&ctx);
173		memcpy(&h->out[h->authentic_pos + 2], md, md_len);
174	}
175#endif
176}
177
178/*
179 * Return true if the current response is valid for a request to the
180 * specified server.
181 */
182static int
183is_valid_response(struct rad_handle *h, int srv,
184    const struct sockaddr_in *from)
185{
186	MD5_CTX ctx;
187	unsigned char md5[MD5_DIGEST_LENGTH];
188	const struct rad_server *srvp;
189	int len;
190#ifdef WITH_SSL
191	HMAC_CTX hctx;
192	u_char resp[MSGSIZE], md[EVP_MAX_MD_SIZE];
193	u_int md_len;
194	int pos;
195#endif
196
197	srvp = &h->servers[srv];
198
199	/* Check the source address */
200	if (from->sin_family != srvp->addr.sin_family ||
201	    from->sin_addr.s_addr != srvp->addr.sin_addr.s_addr ||
202	    from->sin_port != srvp->addr.sin_port)
203		return 0;
204
205	/* Check the message length */
206	if (h->in_len < POS_ATTRS)
207		return 0;
208	len = h->in[POS_LENGTH] << 8 | h->in[POS_LENGTH+1];
209	if (len > h->in_len)
210		return 0;
211
212	/* Check the response authenticator */
213	MD5Init(&ctx);
214	MD5Update(&ctx, &h->in[POS_CODE], POS_AUTH - POS_CODE);
215	MD5Update(&ctx, &h->out[POS_AUTH], LEN_AUTH);
216	MD5Update(&ctx, &h->in[POS_ATTRS], len - POS_ATTRS);
217	MD5Update(&ctx, srvp->secret, strlen(srvp->secret));
218	MD5Final(md5, &ctx);
219	if (memcmp(&h->in[POS_AUTH], md5, sizeof md5) != 0)
220		return 0;
221
222#ifdef WITH_SSL
223	/*
224	 * For non accounting responses check the message authenticator,
225	 * if any.
226	 */
227	if (h->in[POS_CODE] != RAD_ACCOUNTING_RESPONSE) {
228
229		memcpy(resp, h->in, MSGSIZE);
230		pos = POS_ATTRS;
231
232		/* Search and verify the Message-Authenticator */
233		while (pos < len - 2) {
234
235			if (h->in[pos] == RAD_MESSAGE_AUTHENTIC) {
236				/* zero fill the Message-Authenticator */
237				memset(&resp[pos + 2], 0, MD5_DIGEST_LENGTH);
238
239				HMAC_CTX_init(&hctx);
240				HMAC_Init(&hctx, srvp->secret,
241				    strlen(srvp->secret), EVP_md5());
242				HMAC_Update(&hctx, &h->in[POS_CODE],
243				    POS_AUTH - POS_CODE);
244				HMAC_Update(&hctx, &h->out[POS_AUTH],
245				    LEN_AUTH);
246				HMAC_Update(&hctx, &resp[POS_ATTRS],
247				    h->in_len - POS_ATTRS);
248				HMAC_Final(&hctx, md, &md_len);
249				HMAC_CTX_cleanup(&hctx);
250				HMAC_cleanup(&hctx);
251				if (memcmp(md, &h->in[pos + 2],
252				    MD5_DIGEST_LENGTH) != 0)
253					return 0;
254				break;
255			}
256			pos += h->in[pos + 1];
257		}
258	}
259#endif
260	return 1;
261}
262
263/*
264 * Return true if the current request is valid for the specified server.
265 */
266static int
267is_valid_request(struct rad_handle *h)
268{
269	MD5_CTX ctx;
270	unsigned char md5[MD5_DIGEST_LENGTH];
271	const struct rad_server *srvp;
272	int len;
273#ifdef WITH_SSL
274	HMAC_CTX hctx;
275	u_char resp[MSGSIZE], md[EVP_MAX_MD_SIZE];
276	u_int md_len;
277	int pos;
278#endif
279
280	srvp = &h->servers[h->srv];
281
282	/* Check the message length */
283	if (h->in_len < POS_ATTRS)
284		return (0);
285	len = h->in[POS_LENGTH] << 8 | h->in[POS_LENGTH+1];
286	if (len > h->in_len)
287		return (0);
288
289	if (h->in[POS_CODE] != RAD_ACCESS_REQUEST) {
290		uint32_t zeroes[4] = { 0, 0, 0, 0 };
291		/* Check the request authenticator */
292		MD5Init(&ctx);
293		MD5Update(&ctx, &h->in[POS_CODE], POS_AUTH - POS_CODE);
294		MD5Update(&ctx, zeroes, LEN_AUTH);
295		MD5Update(&ctx, &h->in[POS_ATTRS], len - POS_ATTRS);
296		MD5Update(&ctx, srvp->secret, strlen(srvp->secret));
297		MD5Final(md5, &ctx);
298		if (memcmp(&h->in[POS_AUTH], md5, sizeof md5) != 0)
299			return (0);
300	}
301
302#ifdef WITH_SSL
303	/* Search and verify the Message-Authenticator */
304	pos = POS_ATTRS;
305	while (pos < len - 2) {
306		if (h->in[pos] == RAD_MESSAGE_AUTHENTIC) {
307			memcpy(resp, h->in, MSGSIZE);
308			/* zero fill the Request-Authenticator */
309			if (h->in[POS_CODE] != RAD_ACCESS_REQUEST)
310				memset(&resp[POS_AUTH], 0, LEN_AUTH);
311			/* zero fill the Message-Authenticator */
312			memset(&resp[pos + 2], 0, MD5_DIGEST_LENGTH);
313
314			HMAC_CTX_init(&hctx);
315			HMAC_Init(&hctx, srvp->secret,
316			    strlen(srvp->secret), EVP_md5());
317			HMAC_Update(&hctx, resp, h->in_len);
318			HMAC_Final(&hctx, md, &md_len);
319			HMAC_CTX_cleanup(&hctx);
320			HMAC_cleanup(&hctx);
321			if (memcmp(md, &h->in[pos + 2],
322			    MD5_DIGEST_LENGTH) != 0)
323				return (0);
324			break;
325		}
326		pos += h->in[pos + 1];
327	}
328#endif
329	return (1);
330}
331
332static int
333put_password_attr(struct rad_handle *h, int type, const void *value, size_t len)
334{
335	int padded_len;
336	int pad_len;
337
338	if (h->pass_pos != 0) {
339		generr(h, "Multiple User-Password attributes specified");
340		return -1;
341	}
342	if (len > PASSSIZE)
343		len = PASSSIZE;
344	padded_len = len == 0 ? 16 : (len+15) & ~0xf;
345	pad_len = padded_len - len;
346
347	/*
348	 * Put in a place-holder attribute containing all zeros, and
349	 * remember where it is so we can fill it in later.
350	 */
351	clear_password(h);
352	put_raw_attr(h, type, h->pass, padded_len);
353	h->pass_pos = h->out_len - padded_len;
354
355	/* Save the cleartext password, padded as necessary */
356	memcpy(h->pass, value, len);
357	h->pass_len = len;
358	memset(h->pass + len, 0, pad_len);
359	return 0;
360}
361
362static int
363put_raw_attr(struct rad_handle *h, int type, const void *value, size_t len)
364{
365	if (len > 253) {
366		generr(h, "Attribute too long");
367		return -1;
368	}
369	if (h->out_len + 2 + len > MSGSIZE) {
370		generr(h, "Maximum message length exceeded");
371		return -1;
372	}
373	h->out[h->out_len++] = type;
374	h->out[h->out_len++] = len + 2;
375	memcpy(&h->out[h->out_len], value, len);
376	h->out_len += len;
377	return 0;
378}
379
380int
381rad_add_server(struct rad_handle *h, const char *host, int port,
382    const char *secret, int timeout, int tries)
383{
384    	struct in_addr bindto;
385	bindto.s_addr = INADDR_ANY;
386
387	return rad_add_server_ex(h, host, port, secret, timeout, tries,
388		DEAD_TIME, &bindto);
389}
390
391int
392rad_add_server_ex(struct rad_handle *h, const char *host, int port,
393    const char *secret, int timeout, int tries, int dead_time,
394    struct in_addr *bindto)
395{
396	struct rad_server *srvp;
397
398	if (h->num_servers >= MAXSERVERS) {
399		generr(h, "Too many RADIUS servers specified");
400		return -1;
401	}
402	srvp = &h->servers[h->num_servers];
403
404	memset(&srvp->addr, 0, sizeof srvp->addr);
405	srvp->addr.sin_len = sizeof srvp->addr;
406	srvp->addr.sin_family = AF_INET;
407	if (!inet_aton(host, &srvp->addr.sin_addr)) {
408		struct hostent *hent;
409
410		if ((hent = gethostbyname(host)) == NULL) {
411			generr(h, "%s: host not found", host);
412			return -1;
413		}
414		memcpy(&srvp->addr.sin_addr, hent->h_addr,
415		    sizeof srvp->addr.sin_addr);
416	}
417	if (port != 0)
418		srvp->addr.sin_port = htons((u_short)port);
419	else {
420		struct servent *sent;
421
422		if (h->type == RADIUS_AUTH)
423			srvp->addr.sin_port =
424			    (sent = getservbyname("radius", "udp")) != NULL ?
425				sent->s_port : htons(RADIUS_PORT);
426		else
427			srvp->addr.sin_port =
428			    (sent = getservbyname("radacct", "udp")) != NULL ?
429				sent->s_port : htons(RADACCT_PORT);
430	}
431	if ((srvp->secret = strdup(secret)) == NULL) {
432		generr(h, "Out of memory");
433		return -1;
434	}
435	srvp->timeout = timeout;
436	srvp->max_tries = tries;
437	srvp->num_tries = 0;
438	srvp->is_dead = 0;
439	srvp->dead_time = dead_time;
440	srvp->next_probe = 0;
441	srvp->bindto = bindto->s_addr;
442	h->num_servers++;
443	return 0;
444}
445
446void
447rad_close(struct rad_handle *h)
448{
449	int srv;
450
451	if (h->fd != -1)
452		close(h->fd);
453	for (srv = 0;  srv < h->num_servers;  srv++) {
454		memset(h->servers[srv].secret, 0,
455		    strlen(h->servers[srv].secret));
456		free(h->servers[srv].secret);
457	}
458	clear_password(h);
459	free(h);
460}
461
462void
463rad_bind_to(struct rad_handle *h, in_addr_t addr)
464{
465
466	h->bindto = addr;
467}
468
469int
470rad_config(struct rad_handle *h, const char *path)
471{
472	FILE *fp;
473	char buf[MAXCONFLINE];
474	int linenum;
475	int retval;
476
477	if (path == NULL)
478		path = PATH_RADIUS_CONF;
479	if ((fp = fopen(path, "r")) == NULL) {
480		generr(h, "Cannot open \"%s\": %s", path, strerror(errno));
481		return -1;
482	}
483	retval = 0;
484	linenum = 0;
485	while (fgets(buf, sizeof buf, fp) != NULL) {
486		int len;
487		char *fields[5];
488		int nfields;
489		char msg[ERRSIZE];
490		char *type;
491		char *host, *res;
492		char *port_str;
493		char *secret;
494		char *timeout_str;
495		char *maxtries_str;
496		char *dead_time_str;
497		char *bindto_str;
498		char *end;
499		char *wanttype;
500		unsigned long timeout;
501		unsigned long maxtries;
502		unsigned long dead_time;
503		int port;
504		struct in_addr bindto;
505		int i;
506
507		linenum++;
508		len = strlen(buf);
509		/* We know len > 0, else fgets would have returned NULL. */
510		if (buf[len - 1] != '\n') {
511			if (len == sizeof buf - 1)
512				generr(h, "%s:%d: line too long", path,
513				    linenum);
514			else
515				generr(h, "%s:%d: missing newline", path,
516				    linenum);
517			retval = -1;
518			break;
519		}
520		buf[len - 1] = '\0';
521
522		/* Extract the fields from the line. */
523		nfields = split(buf, fields, MAX_FIELDS, msg, sizeof msg);
524		if (nfields == -1) {
525			generr(h, "%s:%d: %s", path, linenum, msg);
526			retval = -1;
527			break;
528		}
529		if (nfields == 0)
530			continue;
531		/*
532		 * The first field should contain "auth" or "acct" for
533		 * authentication or accounting, respectively.  But older
534		 * versions of the file didn't have that field.  Default
535		 * it to "auth" for backward compatibility.
536		 */
537		if (strcmp(fields[0], "auth") != 0 &&
538		    strcmp(fields[0], "acct") != 0) {
539			if (nfields >= MAX_FIELDS) {
540				generr(h, "%s:%d: invalid service type", path,
541				    linenum);
542				retval = -1;
543				break;
544			}
545			nfields++;
546			for (i = nfields;  --i > 0;  )
547				fields[i] = fields[i - 1];
548			fields[0] = "auth";
549		}
550		if (nfields < 3) {
551			generr(h, "%s:%d: missing shared secret", path,
552			    linenum);
553			retval = -1;
554			break;
555		}
556		type = fields[0];
557		host = fields[1];
558		secret = fields[2];
559		timeout_str = fields[3];
560		maxtries_str = fields[4];
561		dead_time_str = fields[5];
562		bindto_str = fields[6];
563
564		/* Ignore the line if it is for the wrong service type. */
565		wanttype = h->type == RADIUS_AUTH ? "auth" : "acct";
566		if (strcmp(type, wanttype) != 0)
567			continue;
568
569		/* Parse and validate the fields. */
570		res = host;
571		host = strsep(&res, ":");
572		port_str = strsep(&res, ":");
573		if (port_str != NULL) {
574			port = strtoul(port_str, &end, 10);
575			if (*end != '\0') {
576				generr(h, "%s:%d: invalid port", path,
577				    linenum);
578				retval = -1;
579				break;
580			}
581		} else
582			port = 0;
583		if (timeout_str != NULL) {
584			timeout = strtoul(timeout_str, &end, 10);
585			if (*end != '\0') {
586				generr(h, "%s:%d: invalid timeout", path,
587				    linenum);
588				retval = -1;
589				break;
590			}
591		} else
592			timeout = TIMEOUT;
593		if (maxtries_str != NULL) {
594			maxtries = strtoul(maxtries_str, &end, 10);
595			if (*end != '\0') {
596				generr(h, "%s:%d: invalid maxtries", path,
597				    linenum);
598				retval = -1;
599				break;
600			}
601		} else
602			maxtries = MAXTRIES;
603
604		if (dead_time_str != NULL) {
605			dead_time = strtoul(dead_time_str, &end, 10);
606			if (*end != '\0') {
607				generr(h, "%s:%d: invalid dead_time", path,
608				    linenum);
609				retval = -1;
610				break;
611			}
612		} else
613		    	dead_time = DEAD_TIME;
614
615		if (bindto_str != NULL) {
616		    	bindto.s_addr = inet_addr(bindto_str);
617			if (bindto.s_addr == INADDR_NONE) {
618				generr(h, "%s:%d: invalid bindto", path,
619				    linenum);
620				retval = -1;
621				break;
622			}
623		} else
624		    	bindto.s_addr = INADDR_ANY;
625
626		if (rad_add_server_ex(h, host, port, secret, timeout, maxtries,
627			    dead_time, &bindto) == -1) {
628			strcpy(msg, h->errmsg);
629			generr(h, "%s:%d: %s", path, linenum, msg);
630			retval = -1;
631			break;
632		}
633	}
634	/* Clear out the buffer to wipe a possible copy of a shared secret */
635	memset(buf, 0, sizeof buf);
636	fclose(fp);
637	return retval;
638}
639
640/*
641 * rad_init_send_request() must have previously been called.
642 * Returns:
643 *   0     The application should select on *fd with a timeout of tv before
644 *         calling rad_continue_send_request again.
645 *   < 0   Failure
646 *   > 0   Success
647 */
648int
649rad_continue_send_request(struct rad_handle *h, int selected, int *fd,
650                          struct timeval *tv)
651{
652	int n, cur_srv;
653	time_t now;
654	struct sockaddr_in sin;
655
656	if (h->type == RADIUS_SERVER) {
657		generr(h, "denied function call");
658		return (-1);
659	}
660	if (selected) {
661		struct sockaddr_in from;
662		socklen_t fromlen;
663
664		fromlen = sizeof from;
665		h->in_len = recvfrom(h->fd, h->in,
666		    MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen);
667		if (h->in_len == -1) {
668			generr(h, "recvfrom: %s", strerror(errno));
669			return -1;
670		}
671		if (is_valid_response(h, h->srv, &from)) {
672			h->in_len = h->in[POS_LENGTH] << 8 |
673			    h->in[POS_LENGTH+1];
674			h->in_pos = POS_ATTRS;
675			return h->in[POS_CODE];
676		}
677	}
678
679	/*
680         * Scan round-robin to the next server that has some
681         * tries left.  There is guaranteed to be one, or we
682         * would have exited this loop by now.
683	 */
684	cur_srv = h->srv;
685	now = time(NULL);
686	if (h->servers[h->srv].num_tries >= h->servers[h->srv].max_tries) {
687		/* Set next probe time for this server */
688		if (h->servers[h->srv].dead_time) {
689			h->servers[h->srv].is_dead = 1;
690			h->servers[h->srv].next_probe = now +
691			    h->servers[h->srv].dead_time;
692		}
693		do {
694		    	h->srv++;
695			if (h->srv >= h->num_servers)
696				h->srv = 0;
697			if (h->servers[h->srv].is_dead == 0)
698			    	break;
699			if (h->servers[h->srv].dead_time &&
700			    h->servers[h->srv].next_probe <= now) {
701			    	h->servers[h->srv].is_dead = 0;
702				h->servers[h->srv].num_tries = 0;
703				break;
704			}
705		} while (h->srv != cur_srv);
706
707		if (h->srv == cur_srv) {
708			generr(h, "No valid RADIUS responses received");
709			return (-1);
710		}
711	}
712
713	/* Rebind */
714	if (h->bindto != h->servers[h->srv].bindto) {
715	    	h->bindto = h->servers[h->srv].bindto;
716		close(h->fd);
717		if ((h->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
718			generr(h, "Cannot create socket: %s", strerror(errno));
719			return -1;
720		}
721		memset(&sin, 0, sizeof sin);
722		sin.sin_len = sizeof sin;
723		sin.sin_family = AF_INET;
724		sin.sin_addr.s_addr = h->bindto;
725		sin.sin_port = 0;
726		if (bind(h->fd, (const struct sockaddr *)&sin,
727		    sizeof sin) == -1) {
728			generr(h, "bind: %s", strerror(errno));
729			close(h->fd);
730			h->fd = -1;
731			return (-1);
732		}
733	}
734
735	if (h->out[POS_CODE] == RAD_ACCESS_REQUEST) {
736		/* Insert the scrambled password into the request */
737		if (h->pass_pos != 0)
738			insert_scrambled_password(h, h->srv);
739	}
740	insert_message_authenticator(h, 0);
741
742	if (h->out[POS_CODE] != RAD_ACCESS_REQUEST) {
743		/* Insert the request authenticator into the request */
744		memset(&h->out[POS_AUTH], 0, LEN_AUTH);
745		insert_request_authenticator(h, 0);
746	}
747
748	/* Send the request */
749	n = sendto(h->fd, h->out, h->out_len, 0,
750	    (const struct sockaddr *)&h->servers[h->srv].addr,
751	    sizeof h->servers[h->srv].addr);
752	if (n != h->out_len)
753		tv->tv_sec = 1; /* Do not wait full timeout if send failed. */
754	else
755		tv->tv_sec = h->servers[h->srv].timeout;
756	h->servers[h->srv].num_tries++;
757	tv->tv_usec = 0;
758	*fd = h->fd;
759
760	return 0;
761}
762
763int
764rad_receive_request(struct rad_handle *h)
765{
766	struct sockaddr_in from;
767	socklen_t fromlen;
768	int n;
769
770	if (h->type != RADIUS_SERVER) {
771		generr(h, "denied function call");
772		return (-1);
773	}
774	h->srv = -1;
775	fromlen = sizeof(from);
776	h->in_len = recvfrom(h->fd, h->in,
777	    MSGSIZE, MSG_WAITALL, (struct sockaddr *)&from, &fromlen);
778	if (h->in_len == -1) {
779		generr(h, "recvfrom: %s", strerror(errno));
780		return (-1);
781	}
782	for (n = 0; n < h->num_servers; n++) {
783		if (h->servers[n].addr.sin_addr.s_addr == from.sin_addr.s_addr) {
784			h->servers[n].addr.sin_port = from.sin_port;
785			h->srv = n;
786			break;
787		}
788	}
789	if (h->srv == -1)
790		return (-2);
791	if (is_valid_request(h)) {
792		h->in_len = h->in[POS_LENGTH] << 8 |
793		    h->in[POS_LENGTH+1];
794		h->in_pos = POS_ATTRS;
795		return (h->in[POS_CODE]);
796	}
797	return (-3);
798}
799
800int
801rad_send_response(struct rad_handle *h)
802{
803	int n;
804
805	if (h->type != RADIUS_SERVER) {
806		generr(h, "denied function call");
807		return (-1);
808	}
809	/* Fill in the length field in the message */
810	h->out[POS_LENGTH] = h->out_len >> 8;
811	h->out[POS_LENGTH+1] = h->out_len;
812
813	insert_message_authenticator(h,
814	    (h->in[POS_CODE] == RAD_ACCESS_REQUEST) ? 1 : 0);
815	insert_request_authenticator(h, 1);
816
817	/* Send the request */
818	n = sendto(h->fd, h->out, h->out_len, 0,
819	    (const struct sockaddr *)&h->servers[h->srv].addr,
820	    sizeof h->servers[h->srv].addr);
821	if (n != h->out_len) {
822		if (n == -1)
823			generr(h, "sendto: %s", strerror(errno));
824		else
825			generr(h, "sendto: short write");
826		return -1;
827	}
828
829	return 0;
830}
831
832int
833rad_create_request(struct rad_handle *h, int code)
834{
835	int i;
836
837	if (h->type == RADIUS_SERVER) {
838		generr(h, "denied function call");
839		return (-1);
840	}
841	if (h->num_servers == 0) {
842	    	generr(h, "No RADIUS servers specified");
843		return (-1);
844	}
845	h->out[POS_CODE] = code;
846	h->out[POS_IDENT] = ++h->ident;
847	if (code == RAD_ACCESS_REQUEST) {
848		/* Create a random authenticator */
849		for (i = 0;  i < LEN_AUTH;  i += 2) {
850			long r;
851			r = random();
852			h->out[POS_AUTH+i] = (u_char)r;
853			h->out[POS_AUTH+i+1] = (u_char)(r >> 8);
854		}
855	} else
856		memset(&h->out[POS_AUTH], 0, LEN_AUTH);
857	h->out_len = POS_ATTRS;
858	clear_password(h);
859	h->authentic_pos = 0;
860	h->out_created = 1;
861	return 0;
862}
863
864int
865rad_create_response(struct rad_handle *h, int code)
866{
867
868	if (h->type != RADIUS_SERVER) {
869		generr(h, "denied function call");
870		return (-1);
871	}
872	h->out[POS_CODE] = code;
873	h->out[POS_IDENT] = h->in[POS_IDENT];
874	memset(&h->out[POS_AUTH], 0, LEN_AUTH);
875	h->out_len = POS_ATTRS;
876	clear_password(h);
877	h->authentic_pos = 0;
878	h->out_created = 1;
879	return 0;
880}
881
882struct in_addr
883rad_cvt_addr(const void *data)
884{
885	struct in_addr value;
886
887	memcpy(&value.s_addr, data, sizeof value.s_addr);
888	return value;
889}
890
891struct in6_addr
892rad_cvt_addr6(const void *data)
893{
894	struct in6_addr value;
895
896	memcpy(&value.s6_addr, data, sizeof value.s6_addr);
897	return value;
898}
899
900u_int32_t
901rad_cvt_int(const void *data)
902{
903	u_int32_t value;
904
905	memcpy(&value, data, sizeof value);
906	return ntohl(value);
907}
908
909char *
910rad_cvt_string(const void *data, size_t len)
911{
912	char *s;
913
914	s = malloc(len + 1);
915	if (s != NULL) {
916		memcpy(s, data, len);
917		s[len] = '\0';
918	}
919	return s;
920}
921
922/*
923 * Returns the attribute type.  If none are left, returns 0.  On failure,
924 * returns -1.
925 */
926int
927rad_get_attr(struct rad_handle *h, const void **value, size_t *len)
928{
929	int type;
930
931	if (h->in_pos >= h->in_len)
932		return 0;
933	if (h->in_pos + 2 > h->in_len) {
934		generr(h, "Malformed attribute in response");
935		return -1;
936	}
937	type = h->in[h->in_pos++];
938	*len = h->in[h->in_pos++] - 2;
939	if (h->in_pos + (int)*len > h->in_len) {
940		generr(h, "Malformed attribute in response");
941		return -1;
942	}
943	*value = &h->in[h->in_pos];
944	h->in_pos += *len;
945	return type;
946}
947
948/*
949 * Returns -1 on error, 0 to indicate no event and >0 for success
950 */
951int
952rad_init_send_request(struct rad_handle *h, int *fd, struct timeval *tv)
953{
954	int srv;
955	time_t now;
956	struct sockaddr_in sin;
957
958	if (h->type == RADIUS_SERVER) {
959		generr(h, "denied function call");
960		return (-1);
961	}
962	/* Make sure we have a socket to use */
963	if (h->fd == -1) {
964		if ((h->fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
965			generr(h, "Cannot create socket: %s", strerror(errno));
966			return -1;
967		}
968		memset(&sin, 0, sizeof sin);
969		sin.sin_len = sizeof sin;
970		sin.sin_family = AF_INET;
971		sin.sin_addr.s_addr = h->bindto;
972		sin.sin_port = htons(0);
973		if (bind(h->fd, (const struct sockaddr *)&sin,
974		    sizeof sin) == -1) {
975			generr(h, "bind: %s", strerror(errno));
976			close(h->fd);
977			h->fd = -1;
978			return -1;
979		}
980	}
981
982	if (h->out[POS_CODE] != RAD_ACCESS_REQUEST) {
983		/* Make sure no password given */
984		if (h->pass_pos || h->chap_pass) {
985			generr(h, "User or Chap Password"
986			    " in accounting request");
987			return -1;
988		}
989	} else {
990		if (h->eap_msg == 0) {
991			/* Make sure the user gave us a password */
992			if (h->pass_pos == 0 && !h->chap_pass) {
993				generr(h, "No User or Chap Password"
994				    " attributes given");
995				return -1;
996			}
997			if (h->pass_pos != 0 && h->chap_pass) {
998				generr(h, "Both User and Chap Password"
999				    " attributes given");
1000				return -1;
1001			}
1002		}
1003	}
1004
1005	/* Fill in the length field in the message */
1006	h->out[POS_LENGTH] = h->out_len >> 8;
1007	h->out[POS_LENGTH+1] = h->out_len;
1008
1009	h->srv = 0;
1010	now = time(NULL);
1011	for (srv = 0;  srv < h->num_servers;  srv++)
1012		h->servers[srv].num_tries = 0;
1013	/* Find a first good server. */
1014	for (srv = 0;  srv < h->num_servers;  srv++) {
1015		if (h->servers[srv].is_dead == 0)
1016			break;
1017		if (h->servers[srv].dead_time &&
1018		    h->servers[srv].next_probe <= now) {
1019		    	h->servers[srv].is_dead = 0;
1020			break;
1021		}
1022		h->srv++;
1023	}
1024
1025	/* If all servers was dead on the last probe, try from beginning */
1026	if (h->srv == h->num_servers) {
1027		for (srv = 0;  srv < h->num_servers;  srv++) {
1028		    	h->servers[srv].is_dead = 0;
1029			h->servers[srv].next_probe = 0;
1030		}
1031		h->srv = 0;
1032	}
1033
1034	return rad_continue_send_request(h, 0, fd, tv);
1035}
1036
1037/*
1038 * Create and initialize a rad_handle structure, and return it to the
1039 * caller.  Can fail only if the necessary memory cannot be allocated.
1040 * In that case, it returns NULL.
1041 */
1042struct rad_handle *
1043rad_auth_open(void)
1044{
1045	struct rad_handle *h;
1046
1047	h = (struct rad_handle *)malloc(sizeof(struct rad_handle));
1048	if (h != NULL) {
1049		srandomdev();
1050		h->fd = -1;
1051		h->num_servers = 0;
1052		h->ident = random();
1053		h->errmsg[0] = '\0';
1054		memset(h->pass, 0, sizeof h->pass);
1055		h->pass_len = 0;
1056		h->pass_pos = 0;
1057		h->chap_pass = 0;
1058		h->authentic_pos = 0;
1059		h->type = RADIUS_AUTH;
1060		h->out_created = 0;
1061		h->eap_msg = 0;
1062		h->bindto = INADDR_ANY;
1063	}
1064	return h;
1065}
1066
1067struct rad_handle *
1068rad_acct_open(void)
1069{
1070	struct rad_handle *h;
1071
1072	h = rad_open();
1073	if (h != NULL)
1074	        h->type = RADIUS_ACCT;
1075	return h;
1076}
1077
1078struct rad_handle *
1079rad_server_open(int fd)
1080{
1081	struct rad_handle *h;
1082
1083	h = rad_open();
1084	if (h != NULL) {
1085	        h->type = RADIUS_SERVER;
1086	        h->fd = fd;
1087	}
1088	return h;
1089}
1090
1091struct rad_handle *
1092rad_open(void)
1093{
1094    return rad_auth_open();
1095}
1096
1097int
1098rad_put_addr(struct rad_handle *h, int type, struct in_addr addr)
1099{
1100	return rad_put_attr(h, type, &addr.s_addr, sizeof addr.s_addr);
1101}
1102
1103int
1104rad_put_addr6(struct rad_handle *h, int type, struct in6_addr addr)
1105{
1106
1107	return rad_put_attr(h, type, &addr.s6_addr, sizeof addr.s6_addr);
1108}
1109
1110int
1111rad_put_attr(struct rad_handle *h, int type, const void *value, size_t len)
1112{
1113	int result;
1114
1115	if (!h->out_created) {
1116		generr(h, "Please call rad_create_request()"
1117		    " before putting attributes");
1118		return -1;
1119	}
1120
1121	if (h->out[POS_CODE] == RAD_ACCOUNTING_REQUEST) {
1122		if (type == RAD_EAP_MESSAGE) {
1123			generr(h, "EAP-Message attribute is not valid"
1124			    " in accounting requests");
1125			return -1;
1126		}
1127	}
1128
1129	/*
1130	 * When proxying EAP Messages, the Message Authenticator
1131	 * MUST be present; see RFC 3579.
1132	 */
1133	if (type == RAD_EAP_MESSAGE) {
1134		if (rad_put_message_authentic(h) == -1)
1135			return -1;
1136	}
1137
1138	if (type == RAD_USER_PASSWORD) {
1139		result = put_password_attr(h, type, value, len);
1140	} else if (type == RAD_MESSAGE_AUTHENTIC) {
1141		result = rad_put_message_authentic(h);
1142	} else {
1143		result = put_raw_attr(h, type, value, len);
1144		if (result == 0) {
1145			if (type == RAD_CHAP_PASSWORD)
1146				h->chap_pass = 1;
1147			else if (type == RAD_EAP_MESSAGE)
1148				h->eap_msg = 1;
1149		}
1150	}
1151
1152	return result;
1153}
1154
1155int
1156rad_put_int(struct rad_handle *h, int type, u_int32_t value)
1157{
1158	u_int32_t nvalue;
1159
1160	nvalue = htonl(value);
1161	return rad_put_attr(h, type, &nvalue, sizeof nvalue);
1162}
1163
1164int
1165rad_put_string(struct rad_handle *h, int type, const char *str)
1166{
1167	return rad_put_attr(h, type, str, strlen(str));
1168}
1169
1170int
1171rad_put_message_authentic(struct rad_handle *h)
1172{
1173#ifdef WITH_SSL
1174	u_char md_zero[MD5_DIGEST_LENGTH];
1175
1176	if (h->out[POS_CODE] == RAD_ACCOUNTING_REQUEST) {
1177		generr(h, "Message-Authenticator is not valid"
1178		    " in accounting requests");
1179		return -1;
1180	}
1181
1182	if (h->authentic_pos == 0) {
1183		h->authentic_pos = h->out_len;
1184		memset(md_zero, 0, sizeof(md_zero));
1185		return (put_raw_attr(h, RAD_MESSAGE_AUTHENTIC, md_zero,
1186		    sizeof(md_zero)));
1187	}
1188	return 0;
1189#else
1190	generr(h, "Message Authenticator not supported,"
1191	    " please recompile libradius with SSL support");
1192	return -1;
1193#endif
1194}
1195
1196/*
1197 * Returns the response type code on success, or -1 on failure.
1198 */
1199int
1200rad_send_request(struct rad_handle *h)
1201{
1202	struct timeval timelimit;
1203	struct timeval tv;
1204	int fd;
1205	int n;
1206
1207	n = rad_init_send_request(h, &fd, &tv);
1208
1209	if (n != 0)
1210		return n;
1211
1212	gettimeofday(&timelimit, NULL);
1213	timeradd(&tv, &timelimit, &timelimit);
1214
1215	for ( ; ; ) {
1216		fd_set readfds;
1217
1218		FD_ZERO(&readfds);
1219		FD_SET(fd, &readfds);
1220
1221		n = select(fd + 1, &readfds, NULL, NULL, &tv);
1222
1223		if (n == -1) {
1224			generr(h, "select: %s", strerror(errno));
1225			return -1;
1226		}
1227
1228		if (!FD_ISSET(fd, &readfds)) {
1229			/* Compute a new timeout */
1230			gettimeofday(&tv, NULL);
1231			timersub(&timelimit, &tv, &tv);
1232			if (tv.tv_sec > 0 || (tv.tv_sec == 0 && tv.tv_usec > 0))
1233				/* Continue the select */
1234				continue;
1235		}
1236
1237		n = rad_continue_send_request(h, n, &fd, &tv);
1238
1239		if (n != 0)
1240			return n;
1241
1242		gettimeofday(&timelimit, NULL);
1243		timeradd(&tv, &timelimit, &timelimit);
1244	}
1245}
1246
1247const char *
1248rad_strerror(struct rad_handle *h)
1249{
1250	return h->errmsg;
1251}
1252
1253/*
1254 * Destructively split a string into fields separated by white space.
1255 * `#' at the beginning of a field begins a comment that extends to the
1256 * end of the string.  Fields may be quoted with `"'.  Inside quoted
1257 * strings, the backslash escapes `\"' and `\\' are honored.
1258 *
1259 * Pointers to up to the first maxfields fields are stored in the fields
1260 * array.  Missing fields get NULL pointers.
1261 *
1262 * The return value is the actual number of fields parsed, and is always
1263 * <= maxfields.
1264 *
1265 * On a syntax error, places a message in the msg string, and returns -1.
1266 */
1267static int
1268split(char *str, char *fields[], int maxfields, char *msg, size_t msglen)
1269{
1270	char *p;
1271	int i;
1272	static const char ws[] = " \t";
1273
1274	for (i = 0;  i < maxfields;  i++)
1275		fields[i] = NULL;
1276	p = str;
1277	i = 0;
1278	while (*p != '\0') {
1279		p += strspn(p, ws);
1280		if (*p == '#' || *p == '\0')
1281			break;
1282		if (i >= maxfields) {
1283			snprintf(msg, msglen, "line has too many fields");
1284			return -1;
1285		}
1286		if (*p == '"') {
1287			char *dst;
1288
1289			dst = ++p;
1290			fields[i] = dst;
1291			while (*p != '"') {
1292				if (*p == '\\') {
1293					p++;
1294					if (*p != '"' && *p != '\\' &&
1295					    *p != '\0') {
1296						snprintf(msg, msglen,
1297						    "invalid `\\' escape");
1298						return -1;
1299					}
1300				}
1301				if (*p == '\0') {
1302					snprintf(msg, msglen,
1303					    "unterminated quoted string");
1304					return -1;
1305				}
1306				*dst++ = *p++;
1307			}
1308			*dst = '\0';
1309			p++;
1310			if (*fields[i] == '\0') {
1311				snprintf(msg, msglen,
1312				    "empty quoted string not permitted");
1313				return -1;
1314			}
1315			if (*p != '\0' && strspn(p, ws) == 0) {
1316				snprintf(msg, msglen, "quoted string not"
1317				    " followed by white space");
1318				return -1;
1319			}
1320		} else {
1321			fields[i] = p;
1322			p += strcspn(p, ws);
1323			if (*p != '\0')
1324				*p++ = '\0';
1325		}
1326		i++;
1327	}
1328	return i;
1329}
1330
1331int
1332rad_get_vendor_attr(u_int32_t *vendor, const void **data, size_t *len)
1333{
1334	struct vendor_attribute *attr;
1335
1336	attr = (struct vendor_attribute *)*data;
1337	*vendor = ntohl(attr->vendor_value);
1338	*data = attr->attrib_data;
1339	*len = attr->attrib_len - 2;
1340
1341	return (attr->attrib_type);
1342}
1343
1344int
1345rad_put_vendor_addr(struct rad_handle *h, int vendor, int type,
1346    struct in_addr addr)
1347{
1348	return (rad_put_vendor_attr(h, vendor, type, &addr.s_addr,
1349	    sizeof addr.s_addr));
1350}
1351
1352int
1353rad_put_vendor_addr6(struct rad_handle *h, int vendor, int type,
1354    struct in6_addr addr)
1355{
1356
1357	return (rad_put_vendor_attr(h, vendor, type, &addr.s6_addr,
1358	    sizeof addr.s6_addr));
1359}
1360
1361int
1362rad_put_vendor_attr(struct rad_handle *h, int vendor, int type,
1363    const void *value, size_t len)
1364{
1365	struct vendor_attribute *attr;
1366	int res;
1367
1368	if (!h->out_created) {
1369		generr(h, "Please call rad_create_request()"
1370		    " before putting attributes");
1371		return -1;
1372	}
1373
1374	if ((attr = malloc(len + 6)) == NULL) {
1375		generr(h, "malloc failure (%zu bytes)", len + 6);
1376		return -1;
1377	}
1378
1379	attr->vendor_value = htonl(vendor);
1380	attr->attrib_type = type;
1381	attr->attrib_len = len + 2;
1382	memcpy(attr->attrib_data, value, len);
1383
1384	res = put_raw_attr(h, RAD_VENDOR_SPECIFIC, attr, len + 6);
1385	free(attr);
1386	if (res == 0 && vendor == RAD_VENDOR_MICROSOFT
1387	    && (type == RAD_MICROSOFT_MS_CHAP_RESPONSE
1388	    || type == RAD_MICROSOFT_MS_CHAP2_RESPONSE)) {
1389		h->chap_pass = 1;
1390	}
1391	return (res);
1392}
1393
1394int
1395rad_put_vendor_int(struct rad_handle *h, int vendor, int type, u_int32_t i)
1396{
1397	u_int32_t value;
1398
1399	value = htonl(i);
1400	return (rad_put_vendor_attr(h, vendor, type, &value, sizeof value));
1401}
1402
1403int
1404rad_put_vendor_string(struct rad_handle *h, int vendor, int type,
1405    const char *str)
1406{
1407	return (rad_put_vendor_attr(h, vendor, type, str, strlen(str)));
1408}
1409
1410ssize_t
1411rad_request_authenticator(struct rad_handle *h, char *buf, size_t len)
1412{
1413	if (len < LEN_AUTH)
1414		return (-1);
1415	memcpy(buf, h->out + POS_AUTH, LEN_AUTH);
1416	if (len > LEN_AUTH)
1417		buf[LEN_AUTH] = '\0';
1418	return (LEN_AUTH);
1419}
1420
1421u_char *
1422rad_demangle(struct rad_handle *h, const void *mangled, size_t mlen)
1423{
1424	char R[LEN_AUTH];
1425	const char *S;
1426	int i, Ppos;
1427	MD5_CTX Context;
1428	u_char b[MD5_DIGEST_LENGTH], *C, *demangled;
1429
1430	if ((mlen % 16 != 0) || mlen > 128) {
1431		generr(h, "Cannot interpret mangled data of length %lu",
1432		    (u_long)mlen);
1433		return NULL;
1434	}
1435
1436	C = (u_char *)mangled;
1437
1438	/* We need the shared secret as Salt */
1439	S = rad_server_secret(h);
1440
1441	/* We need the request authenticator */
1442	if (rad_request_authenticator(h, R, sizeof R) != LEN_AUTH) {
1443		generr(h, "Cannot obtain the RADIUS request authenticator");
1444		return NULL;
1445	}
1446
1447	demangled = malloc(mlen);
1448	if (!demangled)
1449		return NULL;
1450
1451	MD5Init(&Context);
1452	MD5Update(&Context, S, strlen(S));
1453	MD5Update(&Context, R, LEN_AUTH);
1454	MD5Final(b, &Context);
1455	Ppos = 0;
1456	while (mlen) {
1457
1458		mlen -= 16;
1459		for (i = 0; i < 16; i++)
1460			demangled[Ppos++] = C[i] ^ b[i];
1461
1462		if (mlen) {
1463			MD5Init(&Context);
1464			MD5Update(&Context, S, strlen(S));
1465			MD5Update(&Context, C, 16);
1466			MD5Final(b, &Context);
1467		}
1468
1469		C += 16;
1470	}
1471
1472	return demangled;
1473}
1474
1475u_char *
1476rad_demangle_mppe_key(struct rad_handle *h, const void *mangled,
1477    size_t mlen, size_t *len)
1478{
1479	char R[LEN_AUTH];    /* variable names as per rfc2548 */
1480	const char *S;
1481	u_char b[MD5_DIGEST_LENGTH], *demangled;
1482	const u_char *A, *C;
1483	MD5_CTX Context;
1484	int Slen, i, Clen, Ppos;
1485	u_char *P;
1486
1487	if (mlen % 16 != SALT_LEN) {
1488		generr(h, "Cannot interpret mangled data of length %lu",
1489		    (u_long)mlen);
1490		return NULL;
1491	}
1492
1493	/* We need the RADIUS Request-Authenticator */
1494	if (rad_request_authenticator(h, R, sizeof R) != LEN_AUTH) {
1495		generr(h, "Cannot obtain the RADIUS request authenticator");
1496		return NULL;
1497	}
1498
1499	A = (const u_char *)mangled;      /* Salt comes first */
1500	C = (const u_char *)mangled + SALT_LEN;  /* Then the ciphertext */
1501	Clen = mlen - SALT_LEN;
1502	S = rad_server_secret(h);    /* We need the RADIUS secret */
1503	Slen = strlen(S);
1504	P = alloca(Clen);        /* We derive our plaintext */
1505
1506	MD5Init(&Context);
1507	MD5Update(&Context, S, Slen);
1508	MD5Update(&Context, R, LEN_AUTH);
1509	MD5Update(&Context, A, SALT_LEN);
1510	MD5Final(b, &Context);
1511	Ppos = 0;
1512
1513	while (Clen) {
1514		Clen -= 16;
1515
1516		for (i = 0; i < 16; i++)
1517		    P[Ppos++] = C[i] ^ b[i];
1518
1519		if (Clen) {
1520			MD5Init(&Context);
1521			MD5Update(&Context, S, Slen);
1522			MD5Update(&Context, C, 16);
1523			MD5Final(b, &Context);
1524		}
1525
1526		C += 16;
1527	}
1528
1529	/*
1530	* The resulting plain text consists of a one-byte length, the text and
1531	* maybe some padding.
1532	*/
1533	*len = *P;
1534	if (*len > mlen - 1) {
1535		generr(h, "Mangled data seems to be garbage %zu %zu",
1536		    *len, mlen-1);
1537		return NULL;
1538	}
1539
1540	if (*len > MPPE_KEY_LEN * 2) {
1541		generr(h, "Key to long (%zu) for me max. %d",
1542		    *len, MPPE_KEY_LEN * 2);
1543		return NULL;
1544	}
1545	demangled = malloc(*len);
1546	if (!demangled)
1547		return NULL;
1548
1549	memcpy(demangled, P + 1, *len);
1550	return demangled;
1551}
1552
1553const char *
1554rad_server_secret(struct rad_handle *h)
1555{
1556	return (h->servers[h->srv].secret);
1557}
1558