xref: /openbsd/usr.sbin/radiusd/radiusd_radius.c (revision c0c32a87)
1 /*	$OpenBSD: radiusd_radius.c,v 1.22 2024/08/16 09:52:16 yasuoka Exp $	*/
2 
3 /*
4  * Copyright (c) 2013 Internet Initiative Japan Inc.
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 
19 #include <sys/types.h>
20 #include <sys/queue.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 
24 #include <err.h>
25 #include <errno.h>
26 #include <event.h>
27 #include <fcntl.h>
28 #include <stdbool.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <syslog.h>
33 #include <unistd.h>
34 
35 #include <radius.h>
36 
37 #include "radiusd.h"
38 #include "radiusd_module.h"
39 #include "util.h"
40 #include "log.h"
41 
42 struct radius_server {
43 	struct module_radius		*module;
44 	int				 sock;
45 	union {
46 		struct sockaddr_in6	 sin6;
47 		struct sockaddr_in	 sin4;
48 	}				 addr;
49 	union {
50 		struct sockaddr_in6	 sin6;
51 		struct sockaddr_in	 sin4;
52 	}				 local;
53 	struct event			 ev;
54 	u_char				 req_id_seq;
55 };
56 
57 struct module_radius {
58 	struct module_base		*base;
59 	struct radius_server		 server[4];
60 	char				 secret[RADIUSD_SECRET_MAX];
61 	u_int				 nserver;
62 	u_int				 curr_server;
63 	u_int				 req_timeout;
64 	u_int				 max_tries;
65 	u_int				 max_failovers;
66 	u_int				 nfailover;
67 	TAILQ_HEAD(,module_radius_req)	 req;
68 };
69 
70 struct module_radius_req {
71 	struct module_radius		*module;
72 	struct radius_server		*server;
73 	u_int				 q_id;
74 	RADIUS_PACKET			*q_pkt;
75 	u_int				 ntry;
76 	u_int				 nfailover;
77 	u_char				 req_id;
78 	struct event			 ev;
79 	TAILQ_ENTRY(module_radius_req)	 next;
80 };
81 
82 static void	 module_radius_init(struct module_radius *);
83 static void	 module_radius_config_set(void *, const char *, int,
84 		    char * const *);
85 static void	 module_radius_start(void *);
86 static void	 module_radius_stop(void *);
87 static void	 module_radius_access_request(void *, u_int, const u_char *,
88 		    size_t);
89 static int	 radius_server_start(struct radius_server *);
90 static void	 radius_server_stop(struct radius_server *);
91 static void	 radius_server_on_event(int, short, void *);
92 static void	 radius_server_on_fail(struct radius_server *, const char *);
93 static void	 module_radius_req_send(struct module_radius_req *);
94 static int	 module_radius_req_reset_event(struct module_radius_req *);
95 static void	 module_radius_req_on_timeout(int, short, void *);
96 static void	 module_radius_req_on_success(struct module_radius_req *,
97 		    const u_char *, size_t);
98 static void	 module_radius_req_on_failure(struct module_radius_req *);
99 
100 static void	 module_radius_req_free(struct module_radius_req *);
101 static void	 module_radius_req_select_server(struct module_radius_req *);
102 
103 static void	 module_radius_req_reset_msgauth(struct module_radius_req *);
104 static void	 module_radius_log(struct module_radius *, int, const char *, ...);
105 
106 static struct module_handlers module_radius_handlers = {
107 	.config_set = module_radius_config_set,
108 	.start = module_radius_start,
109 	.stop = module_radius_stop,
110 	.access_request = module_radius_access_request
111 };
112 
113 #ifndef nitems
114 #define nitems(_x)    (sizeof((_x)) / sizeof((_x)[0]))
115 #endif
116 
117 int
main(int argc,char * argv[])118 main(int argc, char *argv[])
119 {
120 	static struct module_radius module_radius;
121 
122 	module_radius_init(&module_radius);
123 	openlog(NULL, LOG_PID, LOG_DAEMON);
124 
125 	if ((module_radius.base = module_create(
126 	    STDIN_FILENO, &module_radius, &module_radius_handlers)) == NULL)
127 		err(1, "Could not create a module instance");
128 	module_drop_privilege(module_radius.base, 0);
129 	setproctitle("[main]");
130 
131 	module_load(module_radius.base);
132 	log_init(0);
133 	event_init();
134 
135 	if (pledge("stdio inet", NULL) == -1)
136 		err(EXIT_FAILURE, "pledge");
137 
138 	module_start(module_radius.base);
139 	event_loop(0);
140 
141 	module_destroy(module_radius.base);
142 	event_base_free(NULL);
143 
144 	exit(EXIT_SUCCESS);
145 }
146 
147 static void
module_radius_init(struct module_radius * module)148 module_radius_init(struct module_radius *module)
149 {
150 	memset(module, 0, sizeof(struct module_radius));
151 	TAILQ_INIT(&module->req);
152 }
153 
154 static void
module_radius_config_set(void * ctx,const char * paramname,int paramvalc,char * const * paramvalv)155 module_radius_config_set(void *ctx, const char *paramname, int paramvalc,
156     char * const * paramvalv)
157 {
158 	const char		*errmsg = NULL;
159 	struct addrinfo		*res;
160 	struct module_radius	*module = ctx;
161 
162 	if (strcmp(paramname, "server") == 0) {
163 		SYNTAX_ASSERT(paramvalc == 1,
164 		    "`server' must have just one argument");
165 		SYNTAX_ASSERT(module->nserver < (int)nitems(module->server),
166 		    "number of server reached limit");
167 
168 		if (addrport_parse(paramvalv[0], IPPROTO_UDP, &res) != 0)
169 			SYNTAX_ASSERT(0, "could not parse address and port");
170 		memcpy(&module->server[module->nserver].addr, res->ai_addr,
171 		    res->ai_addrlen);
172 
173 		if (ntohs(module->server[module->nserver].addr.sin4.sin_port)
174 		    == 0)
175 			module->server[module->nserver].addr.sin4.sin_port
176 			    = htons(RADIUS_DEFAULT_PORT);
177 
178 		module->server[module->nserver].sock = -1;
179 		module->nserver++;
180 		freeaddrinfo(res);
181 	} else if (strcmp(paramname, "request-timeout") == 0) {
182 		SYNTAX_ASSERT(paramvalc == 1,
183 		    "`request-timeout' must have just one argument");
184 		module->req_timeout = (int)strtonum(paramvalv[0], 0,
185 		    UINT16_MAX, &errmsg);
186 		if (module->req_timeout == 0 && errmsg != NULL) {
187 			module_send_message(module->base, IMSG_NG,
188 			    "`request-timeout must be 0-%d", UINT16_MAX);
189 			return;
190 		}
191 	} else if (strcmp(paramname, "max-tries") == 0) {
192 		SYNTAX_ASSERT(paramvalc == 1,
193 		    "`max-tries' must have just one argument");
194 		module->max_tries = (int)strtonum(paramvalv[0], 0,
195 		    UINT16_MAX, &errmsg);
196 		if (module->max_tries == 0 && errmsg != NULL) {
197 			module_send_message(module->base, IMSG_NG,
198 			    "`max-tries must be 0-%d", UINT16_MAX);
199 			return;
200 		}
201 
202 	} else if (strcmp(paramname, "max-failovers") == 0) {
203 		SYNTAX_ASSERT(paramvalc == 1,
204 		    "`max-failovers' must have just one argument");
205 		module->max_failovers = (int)strtonum(paramvalv[0], 0,
206 		    UINT16_MAX, &errmsg);
207 		if (module->max_failovers == 0 && errmsg != NULL) {
208 			module_send_message(module->base, IMSG_NG,
209 			    "`max-failovers' must be 0-%d", UINT16_MAX);
210 			return;
211 		}
212 	} else if (strcmp(paramname, "secret") == 0) {
213 		SYNTAX_ASSERT(paramvalc == 1,
214 		    "`secret' must have just one argument");
215 		if (strlcpy(module->secret, paramvalv[0],
216 		    sizeof(module->secret)) >= sizeof(module->secret)) {
217 			module_send_message(module->base, IMSG_NG,
218 			    "`secret' length must be 0-%lu",
219 			    (u_long) sizeof(module->secret) - 1);
220 			return;
221 		}
222 	} else if (strcmp(paramname, "_debug") == 0)
223 		log_init(1);
224 	else if (strncmp(paramname, "_", 1) == 0)
225 		/* nothing */; /* ignore all internal messages */
226 	else {
227 		module_send_message(module->base, IMSG_NG,
228 		    "Unknown config parameter name `%s'", paramname);
229 		return;
230 	}
231 	module_send_message(module->base, IMSG_OK, NULL);
232 
233 	return;
234 syntax_error:
235 	module_send_message(module->base, IMSG_NG, "%s", errmsg);
236 }
237 
238 static void
module_radius_start(void * ctx)239 module_radius_start(void *ctx)
240 {
241 	u_int			 i;
242 	struct module_radius	*module = ctx;
243 
244 	if (module->nserver <= 0) {
245 		module_send_message(module->base, IMSG_NG,
246 			"needs one `server' at least");
247 		return;
248 	}
249 
250 	if (module->secret[0] == '\0') {
251 		module_send_message(module->base, IMSG_NG,
252 		    "`secret' configuration is required");
253 		return;
254 	}
255 
256 	for (i = 0; i < module->nserver; i++) {
257 		module->server[i].module = module;
258 		if (radius_server_start(&module->server[i]) != 0) {
259 			module_send_message(module->base, IMSG_NG,
260 				"module `radius' failed to start one of "
261 				"the servers");
262 			return;
263 		}
264 	}
265 	module_send_message(module->base, IMSG_OK, NULL);
266 
267 	module_notify_secret(module->base, module->secret);
268 }
269 
270 static void
module_radius_stop(void * ctx)271 module_radius_stop(void *ctx)
272 {
273 	u_int				 i;
274 	struct module_radius_req	*req, *treq;
275 	struct module_radius		*module = ctx;
276 
277 	TAILQ_FOREACH_SAFE(req, &module->req, next, treq)
278 		module_radius_req_on_failure(req);
279 
280 	for (i = 0; i < module->nserver; i++)
281 		radius_server_stop(&module->server[i]);
282 }
283 
284 static void
module_radius_access_request(void * ctx,u_int q_id,const u_char * pkt,size_t pktlen)285 module_radius_access_request(void *ctx, u_int q_id, const u_char *pkt,
286     size_t pktlen)
287 {
288 	struct module_radius		*module = ctx;
289 	struct module_radius_req	*req;
290 	u_char				 attrbuf[256];
291 	ssize_t				 attrlen;
292 
293 	req = calloc(1, sizeof(struct module_radius_req));
294 	if (req == NULL) {
295 		module_radius_log(module, LOG_WARNING,
296 		    "%s: Out of memory: %m", __func__);
297 		goto on_fail;
298 	}
299 
300 	req->ntry = 0;
301 	req->module = module;
302 	req->q_id = q_id;
303 	if ((req->q_pkt = radius_convert_packet(pkt, pktlen)) == NULL) {
304 		module_radius_log(module, LOG_WARNING,
305 		    "%s: radius_convert_packet() failed: %m", __func__);
306 		goto on_fail;
307 	}
308 	evtimer_set(&req->ev, module_radius_req_on_timeout, req);
309 	TAILQ_INSERT_TAIL(&req->module->req, req, next);
310 
311 	/*
312 	 * radiusd decrypt User-Password attribute.  crypt it again with our
313 	 * secret.
314 	 */
315 	attrlen = sizeof(attrbuf);
316 	if (radius_get_raw_attr(req->q_pkt, RADIUS_TYPE_USER_PASSWORD,
317 		    attrbuf, &attrlen) == 0) {
318 		attrbuf[attrlen] = '\0';
319 		radius_del_attr_all(req->q_pkt, RADIUS_TYPE_USER_PASSWORD);
320 		radius_put_user_password_attr(req->q_pkt, attrbuf,
321 		    module->secret);
322 	}
323 
324 	/* select current server */
325 	module_radius_req_select_server(req);
326 
327 	module_radius_req_send(req);
328 
329 	return;
330 
331 on_fail:
332 	free(req);
333 	module_accsreq_aborted(module->base, q_id);
334 }
335 
336 /*
337  * radius_server
338  */
339 static int
radius_server_start(struct radius_server * server)340 radius_server_start(struct radius_server *server)
341 {
342 	socklen_t	 locallen;
343 	char		 buf0[NI_MAXHOST + NI_MAXSERV + 32];
344 	char		 buf1[NI_MAXHOST + NI_MAXSERV + 32];
345 
346 	if ((server->sock = socket(AF_INET, SOCK_DGRAM | SOCK_NONBLOCK, 0))
347 	    == -1) {
348 		module_radius_log(server->module, LOG_WARNING,
349 		    "%s: socket() failed", __func__);
350 		goto on_error;
351 	}
352 	if (connect(server->sock, (struct sockaddr *)&server->addr,
353 		server->addr.sin4.sin_len) != 0) {
354 		module_radius_log(server->module, LOG_WARNING,
355 		    "%s: connect to %s failed", __func__,
356 		    addrport_tostring((struct sockaddr *)&server->addr,
357 			server->addr.sin4.sin_len, buf1, sizeof(buf1)));
358 		goto on_error;
359 	}
360 	locallen = sizeof(server->local);
361 	if (getsockname(server->sock, (struct sockaddr *)&server->local,
362 	    &locallen) != 0) {
363 		module_radius_log(server->module, LOG_WARNING,
364 		    "%s: getsockanme() failed", __func__);
365 		goto on_error;
366 	}
367 	module_radius_log(server->module, LOG_INFO,
368 	    "Use %s to send requests for %s",
369 	    addrport_tostring((struct sockaddr *)&server->local,
370 		    locallen, buf0, sizeof(buf0)),
371 	    addrport_tostring((struct sockaddr *)&server->addr,
372 		    server->addr.sin4.sin_len, buf1, sizeof(buf1)));
373 
374 	event_set(&server->ev, server->sock, EV_READ | EV_PERSIST,
375 	    radius_server_on_event, server);
376 	if (event_add(&server->ev, NULL)) {
377 		module_radius_log(server->module, LOG_WARNING,
378 		    "%s: event_add() failed", __func__);
379 		goto on_error;
380 	}
381 
382 	return (0);
383 on_error:
384 	if (server->sock >= 0)
385 		close(server->sock);
386 	server->sock = -1;
387 	return (-1);
388 }
389 
390 static void
radius_server_stop(struct radius_server * server)391 radius_server_stop(struct radius_server *server)
392 {
393 	event_del(&server->ev);
394 	if (server->sock >= 0)
395 		close(server->sock);
396 	server->sock = -1;
397 }
398 
399 static void
radius_server_on_event(int fd,short evmask,void * ctx)400 radius_server_on_event(int fd, short evmask, void *ctx)
401 {
402 	int				 sz, res_id;
403 	u_char				 pkt[65535];
404 	char				 buf[NI_MAXHOST + NI_MAXSERV + 32];
405 	struct radius_server		*server = ctx;
406 	RADIUS_PACKET			*radpkt = NULL;
407 	struct module_radius_req	*req;
408 	struct sockaddr			*peer;
409 
410 	peer = (struct sockaddr *)&server->addr;
411 	if ((sz = recv(server->sock, pkt, sizeof(pkt), 0)) == -1) {
412 		if (errno == EAGAIN)
413 			return;
414 		module_radius_log(server->module, LOG_WARNING,
415 		    "server=%s recv() failed: %m",
416 		    addrport_tostring(peer, peer->sa_len, buf, sizeof(buf)));
417 		return;
418 	}
419 	if ((radpkt = radius_convert_packet(pkt, sz)) == NULL) {
420 		module_radius_log(server->module, LOG_WARNING,
421 		    "server=%s could not convert the received message to a "
422 		    "RADIUS packet object: %m",
423 		    addrport_tostring(peer, peer->sa_len, buf, sizeof(buf)));
424 		return;
425 	}
426 	res_id = radius_get_id(radpkt);
427 	TAILQ_FOREACH(req, &server->module->req, next) {
428 		if (req->server == server && req->req_id == res_id)
429 			break;
430 	}
431 	if (req == NULL) {
432 		module_radius_log(server->module, LOG_WARNING,
433 		    "server=%s Received radius message has unknown id=%d",
434 		    addrport_tostring(peer, peer->sa_len, buf, sizeof(buf)),
435 		    res_id);
436 		goto out;
437 	}
438 	radius_set_request_packet(radpkt, req->q_pkt);
439 
440 	if (radius_check_response_authenticator(radpkt,
441 	    server->module->secret) != 0) {
442 		module_radius_log(server->module, LOG_WARNING,
443 		    "server=%s Received radius message(id=%d) has bad "
444 		    "authenticator",
445 		    addrport_tostring(peer, peer->sa_len, buf,
446 		    sizeof(buf)), res_id);
447 		goto out;
448 	}
449 	if (radius_has_attr(radpkt,
450 	    RADIUS_TYPE_MESSAGE_AUTHENTICATOR) &&
451 	    radius_check_message_authenticator(radpkt,
452 		    server->module->secret) != 0) {
453 		module_radius_log(server->module, LOG_WARNING,
454 		    "server=%s Received radius message(id=%d) has bad "
455 		    "message authenticator",
456 		    addrport_tostring(peer, peer->sa_len, buf,
457 		    sizeof(buf)), res_id);
458 		goto out;
459 	}
460 
461 	module_radius_log(server->module, LOG_INFO,
462 	    "q=%u received a response from server %s", req->q_id,
463 	    addrport_tostring(peer, peer->sa_len, buf, sizeof(buf)));
464 
465 	module_radius_req_on_success(req, radius_get_data(radpkt),
466 	    radius_get_length(radpkt));
467 out:
468 	if (radpkt != NULL)
469 		radius_delete_packet(radpkt);
470 }
471 
472 static void
radius_server_on_fail(struct radius_server * server,const char * failmsg)473 radius_server_on_fail(struct radius_server *server, const char *failmsg)
474 {
475 	char		 buf0[NI_MAXHOST + NI_MAXSERV + 32];
476 	char		 buf1[NI_MAXHOST + NI_MAXSERV + 32];
477 	struct sockaddr	*caddr, *naddr;
478 
479 	caddr = (struct sockaddr *)&server->addr;
480 	if (server->module->nserver <= 1) {
481 		module_radius_log(server->module, LOG_WARNING,
482 		    "Server %s failed: %s",
483 		    addrport_tostring(caddr, caddr->sa_len, buf0, sizeof(buf0)),
484 		    failmsg);
485 		return;
486 	}
487 	server->module->curr_server++;
488 	server->module->curr_server %= server->module->nserver;
489 	naddr = (struct sockaddr *)
490 	    &server->module->server[server->module->curr_server].addr;
491 
492 	module_radius_log(server->module, LOG_WARNING,
493 	    "Server %s failed: %s  Fail over to %s",
494 	    addrport_tostring(caddr, caddr->sa_len, buf0, sizeof(buf0)),
495 	    failmsg,
496 	    addrport_tostring(naddr, naddr->sa_len, buf1, sizeof(buf1)));
497 }
498 
499 /* module_radius_req */
500 
501 static void
module_radius_req_send(struct module_radius_req * req)502 module_radius_req_send(struct module_radius_req *req)
503 {
504 	int		 sz;
505 	struct sockaddr	*peer;
506 	char		 msg[BUFSIZ];
507 
508 	peer = (struct sockaddr *)&req->server->addr;
509 	if ((sz = send(req->server->sock, radius_get_data(req->q_pkt),
510 	    radius_get_length(req->q_pkt), 0)) < 0) {
511 		module_radius_log(req->module, LOG_WARNING,
512 		    "Sending RADIUS query q=%u to %s failed: %m",
513 		    req->q_id,
514 		    addrport_tostring(peer, peer->sa_len, msg, sizeof(msg)));
515 		/* retry anyway */
516 	}
517 	module_radius_log(req->module, LOG_INFO,
518 	    "Send RADIUS query q=%u id=%d to %s successfully",
519 	    req->q_id, req->req_id,
520 	    addrport_tostring(peer, peer->sa_len, msg, sizeof(msg)));
521 	if (module_radius_req_reset_event(req) != -1)
522 		req->ntry++;
523 }
524 
525 static int
module_radius_req_reset_event(struct module_radius_req * req)526 module_radius_req_reset_event(struct module_radius_req *req)
527 {
528 	struct timeval	 tv;
529 	static int	 timeouts[] = { 2, 4, 8 };
530 
531 	tv.tv_usec = 0;
532 	if (req->module->req_timeout != 0)
533 		tv.tv_sec = req->module->req_timeout;
534 	else {
535 		if (req->ntry < nitems(timeouts))
536 			tv.tv_sec = timeouts[req->ntry];
537 		else
538 			tv.tv_sec = timeouts[nitems(timeouts) - 1];
539 	}
540 	if (evtimer_add(&req->ev, &tv) != 0) {
541 		module_radius_log(req->module, LOG_WARNING,
542 		    "Cannot process the request for q=%u: "
543 		    "evtimer_add() failed: %m", req->q_id);
544 		module_radius_req_on_failure(req);
545 		return (-1);
546 	}
547 	return (0);
548 }
549 
550 static void
module_radius_req_on_timeout(int fd,short evmask,void * ctx)551 module_radius_req_on_timeout(int fd, short evmask, void *ctx)
552 {
553 	struct module_radius_req	*req = ctx;
554 	char				 msg[BUFSIZ];
555 
556 
557 	if (req->module->max_tries <= req->ntry) {
558 		snprintf(msg, sizeof(msg), "q=%u didn't response RADIUS query "
559 		    "%d time%s", req->q_id, req->ntry,
560 		    (req->ntry > 0)? "s" : "");
561 		radius_server_on_fail(req->server, msg);
562 		if (++req->nfailover >= req->module->max_failovers) {
563 			module_radius_log(req->module,
564 			    LOG_WARNING, "RADIUS query q=%u time out",
565 			    req->q_id);
566 			module_radius_req_on_failure(req);
567 			return;
568 		}
569 		/* select the next server */
570 		module_radius_req_select_server(req);
571 	}
572 	module_radius_req_send(req);
573 }
574 
575 static void
module_radius_req_on_success(struct module_radius_req * req,const u_char * pkt,size_t pktlen)576 module_radius_req_on_success(struct module_radius_req *req,
577     const u_char *pkt, size_t pktlen)
578 {
579 	module_accsreq_answer(req->module->base, req->q_id, pkt, pktlen);
580 	module_radius_req_free(req);
581 }
582 
583 static void
module_radius_req_on_failure(struct module_radius_req * req)584 module_radius_req_on_failure(struct module_radius_req *req)
585 {
586 	module_accsreq_aborted(req->module->base, req->q_id);
587 	module_radius_req_free(req);
588 }
589 
590 
591 static void
module_radius_req_free(struct module_radius_req * req)592 module_radius_req_free(struct module_radius_req *req)
593 {
594 	evtimer_del(&req->ev);
595 	TAILQ_REMOVE(&req->module->req, req, next);
596 	if (req->q_pkt != NULL)
597 		radius_delete_packet(req->q_pkt);
598 	free(req);
599 }
600 
601 static void
module_radius_req_select_server(struct module_radius_req * req)602 module_radius_req_select_server(struct module_radius_req *req)
603 {
604 	req->server = &req->module->server[req->module->curr_server];
605 	req->ntry = 0;
606 	req->req_id = req->server->req_id_seq++;
607 	radius_set_id(req->q_pkt, req->req_id);
608 	module_radius_req_reset_msgauth(req);
609 }
610 
611 static void
module_radius_req_reset_msgauth(struct module_radius_req * req)612 module_radius_req_reset_msgauth(struct module_radius_req *req)
613 {
614 	if (radius_has_attr(req->q_pkt, RADIUS_TYPE_MESSAGE_AUTHENTICATOR))
615 		radius_del_attr_all(req->q_pkt,
616 		    RADIUS_TYPE_MESSAGE_AUTHENTICATOR);
617 	radius_put_message_authenticator(req->q_pkt, req->module->secret);
618 }
619 
620 static void
module_radius_log(struct module_radius * module,int pri,const char * fmt,...)621 module_radius_log(struct module_radius *module, int pri, const char *fmt, ...)
622 {
623 	char		fmt0[BUFSIZ];
624 	va_list		va;
625 
626 	snprintf(fmt0, sizeof(fmt0), "radius: %s", fmt);
627 	va_start(va, fmt);
628 	vlog(pri, fmt0, va);
629 	va_end(va);
630 }
631