sync with OpenBSD -current
This commit is contained in:
parent
f5750f4f6e
commit
e42955765e
32 changed files with 1329 additions and 320 deletions
|
@ -1,4 +1,4 @@
|
||||||
# $OpenBSD: sftp-cmds.sh,v 1.19 2024/03/29 10:40:07 dtucker Exp $
|
# $OpenBSD: sftp-cmds.sh,v 1.20 2024/07/01 03:10:19 djm Exp $
|
||||||
# Placed in the Public Domain.
|
# Placed in the Public Domain.
|
||||||
|
|
||||||
# XXX - TODO:
|
# XXX - TODO:
|
||||||
|
@ -22,7 +22,7 @@ rm -rf ${COPY} ${COPY}.1 ${COPY}.2 ${COPY}.dd ${COPY}.dd2
|
||||||
mkdir ${COPY}.dd
|
mkdir ${COPY}.dd
|
||||||
|
|
||||||
verbose "$tid: lls"
|
verbose "$tid: lls"
|
||||||
printf "cd ${OBJ}\nlls\n" | ${SFTP} -D ${SFTPSERVER} 2>&1 | \
|
printf "lcd ${OBJ}\nlls\n" | ${SFTP} -D ${SFTPSERVER} 2>&1 | \
|
||||||
grep copy.dd >/dev/null || fail "lls failed"
|
grep copy.dd >/dev/null || fail "lls failed"
|
||||||
|
|
||||||
verbose "$tid: lls w/path"
|
verbose "$tid: lls w/path"
|
||||||
|
|
|
@ -32,7 +32,9 @@ our %args = (
|
||||||
loggrep => {
|
loggrep => {
|
||||||
qr{Keyfile /etc/ssl/private/localhost.key} => 1,
|
qr{Keyfile /etc/ssl/private/localhost.key} => 1,
|
||||||
qr{Certfile /etc/ssl/localhost.crt} => 1,
|
qr{Certfile /etc/ssl/localhost.crt} => 1,
|
||||||
|
qr/Accepting tcp connection/ => 1,
|
||||||
qr/syslogd\[\d+\]: tls logger .* accepted/ => 1,
|
qr/syslogd\[\d+\]: tls logger .* accepted/ => 1,
|
||||||
|
qr/Completed tls handshake/ => 1,
|
||||||
qr/syslogd\[\d+\]: tls logger .* connection close/ => 1,
|
qr/syslogd\[\d+\]: tls logger .* connection close/ => 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: util.c,v 1.44 2024/02/03 00:38:08 jsg Exp $ */
|
/* $OpenBSD: util.c,v 1.45 2024/07/01 14:15:15 yasuoka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
|
* Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org>
|
||||||
|
@ -644,16 +644,16 @@ prefixlen2mask6(uint8_t prefixlen, uint32_t *mask)
|
||||||
const char *
|
const char *
|
||||||
print_addr(void *addr)
|
print_addr(void *addr)
|
||||||
{
|
{
|
||||||
static char sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 7];
|
static char sbuf[IKED_CYCLE_BUFFERS][NI_MAXHOST + 9];
|
||||||
static int idx;
|
static int idx;
|
||||||
struct sockaddr *sa = addr;
|
struct sockaddr *sa = addr;
|
||||||
char *buf;
|
char *buf, *hbuf;
|
||||||
size_t len;
|
size_t len, hlen;
|
||||||
char pbuf[7];
|
char pbuf[7];
|
||||||
in_port_t port;
|
in_port_t port;
|
||||||
|
|
||||||
buf = sbuf[idx];
|
hbuf = buf = sbuf[idx];
|
||||||
len = sizeof(sbuf[idx]);
|
hlen = len = sizeof(sbuf[idx]);
|
||||||
if (++idx >= IKED_CYCLE_BUFFERS)
|
if (++idx >= IKED_CYCLE_BUFFERS)
|
||||||
idx = 0;
|
idx = 0;
|
||||||
|
|
||||||
|
@ -662,13 +662,21 @@ print_addr(void *addr)
|
||||||
return (buf);
|
return (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((port = socket_getport(sa)) != 0 && sa->sa_family == AF_INET6) {
|
||||||
|
/* surround [] */
|
||||||
|
*(hbuf++) = '[';
|
||||||
|
hlen--;
|
||||||
|
}
|
||||||
|
|
||||||
if (getnameinfo(sa, sa->sa_len,
|
if (getnameinfo(sa, sa->sa_len,
|
||||||
buf, len, NULL, 0, NI_NUMERICHOST) != 0) {
|
hbuf, hlen, NULL, 0, NI_NUMERICHOST) != 0) {
|
||||||
strlcpy(buf, "unknown", len);
|
strlcpy(buf, "unknown", len);
|
||||||
return (buf);
|
return (buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((port = socket_getport(sa)) != 0) {
|
if (port != 0) {
|
||||||
|
if (sa->sa_family == AF_INET6)
|
||||||
|
(void)strlcat(buf, "]", len);
|
||||||
snprintf(pbuf, sizeof(pbuf), ":%d", port);
|
snprintf(pbuf, sizeof(pbuf), ":%d", port);
|
||||||
(void)strlcat(buf, pbuf, len);
|
(void)strlcat(buf, pbuf, len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: ofw_thermal.c,v 1.9 2024/06/27 09:37:07 kettenis Exp $ */
|
/* $OpenBSD: ofw_thermal.c,v 1.10 2024/07/01 14:13:43 kettenis Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2019 Mark Kettenis
|
* Copyright (c) 2019 Mark Kettenis
|
||||||
*
|
*
|
||||||
|
@ -306,12 +306,12 @@ thermal_zone_poll(void *arg)
|
||||||
int32_t temp, delta;
|
int32_t temp, delta;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
tp = tz->tz_trips;
|
||||||
temp = thermal_get_temperature_cells(tz->tz_sensors);
|
temp = thermal_get_temperature_cells(tz->tz_sensors);
|
||||||
if (temp == THERMAL_SENSOR_MAX)
|
if (temp == THERMAL_SENSOR_MAX)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
newtp = NULL;
|
newtp = NULL;
|
||||||
tp = tz->tz_trips;
|
|
||||||
for (i = 0; i < tz->tz_ntrips; i++) {
|
for (i = 0; i < tz->tz_ntrips; i++) {
|
||||||
if (temp < tp->tp_temperature && tp != tz->tz_tp)
|
if (temp < tp->tp_temperature && tp != tz->tz_tp)
|
||||||
break;
|
break;
|
||||||
|
@ -372,7 +372,7 @@ out:
|
||||||
|
|
||||||
if (polling_delay > 0)
|
if (polling_delay > 0)
|
||||||
timeout_add_msec(&tz->tz_poll_to, polling_delay);
|
timeout_add_msec(&tz->tz_poll_to, polling_delay);
|
||||||
else
|
else if (tp)
|
||||||
thermal_set_limit_cells(tz->tz_sensors, tp->tp_temperature);
|
thermal_set_limit_cells(tz->tz_sensors, tp->tp_temperature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: misc.c,v 1.8 2017/12/18 09:12:49 job Exp $ */
|
/* $OpenBSD: misc.c,v 1.9 2024/07/01 18:43:50 deraadt Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
|
* Copyright (c) 2005, 2006 Reyk Floeter <reyk@openbsd.org>
|
||||||
|
@ -79,10 +79,13 @@ lg_help(struct cmd *cmds, char **argv)
|
||||||
void
|
void
|
||||||
lg_sig_alarm(int sig)
|
lg_sig_alarm(int sig)
|
||||||
{
|
{
|
||||||
|
int save_errno = errno;
|
||||||
|
|
||||||
if (child != -1) {
|
if (child != -1) {
|
||||||
/* Forcibly kill the child, no excuse... */
|
/* Forcibly kill the child, no excuse... */
|
||||||
kill(child, SIGKILL);
|
kill(child, SIGKILL);
|
||||||
}
|
}
|
||||||
|
errno = save_errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: speed.c,v 1.34 2023/07/27 07:01:50 tb Exp $ */
|
/* $OpenBSD: speed.c,v 1.35 2024/07/01 18:52:22 deraadt Exp $ */
|
||||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -150,7 +150,7 @@
|
||||||
#include "./testrsa.h"
|
#include "./testrsa.h"
|
||||||
|
|
||||||
#define BUFSIZE (1024*8+64)
|
#define BUFSIZE (1024*8+64)
|
||||||
int run = 0;
|
volatile sig_atomic_t run = 0;
|
||||||
|
|
||||||
static int mr = 0;
|
static int mr = 0;
|
||||||
static int usertime = 1;
|
static int usertime = 1;
|
||||||
|
@ -193,7 +193,10 @@ static void sig_done(int sig);
|
||||||
static void
|
static void
|
||||||
sig_done(int sig)
|
sig_done(int sig)
|
||||||
{
|
{
|
||||||
|
int save_errno = errno;
|
||||||
|
|
||||||
signal(SIGALRM, sig_done);
|
signal(SIGALRM, sig_done);
|
||||||
|
errno = save_errno;
|
||||||
run = 0;
|
run = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: clientloop.c,v 1.407 2024/05/17 06:42:04 jsg Exp $ */
|
/* $OpenBSD: clientloop.c,v 1.408 2024/07/01 04:31:17 djm Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
||||||
|
@ -598,8 +598,9 @@ obfuscate_keystroke_timing(struct ssh *ssh, struct timespec *timeout,
|
||||||
if (timespeccmp(&now, &chaff_until, >=)) {
|
if (timespeccmp(&now, &chaff_until, >=)) {
|
||||||
/* Stop if there have been no keystrokes for a while */
|
/* Stop if there have been no keystrokes for a while */
|
||||||
stop_reason = "chaff time expired";
|
stop_reason = "chaff time expired";
|
||||||
} else if (timespeccmp(&now, &next_interval, >=)) {
|
} else if (timespeccmp(&now, &next_interval, >=) &&
|
||||||
/* Otherwise if we were due to send, then send chaff */
|
!ssh_packet_have_data_to_write(ssh)) {
|
||||||
|
/* If due to send but have no data, then send chaff */
|
||||||
if (send_chaff(ssh))
|
if (send_chaff(ssh))
|
||||||
nchaff++;
|
nchaff++;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
/* $OpenBSD: version.h,v 1.101 2024/03/11 04:59:47 djm Exp $ */
|
/* $OpenBSD: version.h,v 1.102 2024/07/01 04:31:59 djm Exp $ */
|
||||||
|
|
||||||
#define SSH_VERSION "OpenSSH_9.7"
|
#define SSH_VERSION "OpenSSH_9.8"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: chap.c,v 1.18 2024/02/26 08:47:28 yasuoka Exp $ */
|
/* $OpenBSD: chap.c,v 1.19 2024/07/01 07:09:07 yasuoka Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
* </ul></p>
|
* </ul></p>
|
||||||
*/
|
*/
|
||||||
/* RFC 1994, 2433 */
|
/* RFC 1994, 2433 */
|
||||||
/* $Id: chap.c,v 1.18 2024/02/26 08:47:28 yasuoka Exp $ */
|
/* $Id: chap.c,v 1.19 2024/07/01 07:09:07 yasuoka Exp $ */
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
@ -914,7 +914,7 @@ chap_radius_response(void *context, RADIUS_PACKET *pkt, int flags,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ppp_process_radius_framed_ip(_this->ppp, pkt);
|
ppp_process_radius_attrs(_this->ppp, pkt);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
auth_failed:
|
auth_failed:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.\" $OpenBSD: npppd.conf.5,v 1.32 2023/03/02 17:09:53 jmc Exp $
|
.\" $OpenBSD: npppd.conf.5,v 1.34 2024/07/01 14:56:19 jmc Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2012 YASUOKA Masahiko <yasuoka@openbsd.org>
|
.\" Copyright (c) 2012 YASUOKA Masahiko <yasuoka@openbsd.org>
|
||||||
.\"
|
.\"
|
||||||
|
@ -14,7 +14,7 @@
|
||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: March 2 2023 $
|
.Dd $Mdocdate: July 1 2024 $
|
||||||
.Dt NPPPD.CONF 5
|
.Dt NPPPD.CONF 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -506,8 +506,20 @@ The default is
|
||||||
This option can be used multiple times.
|
This option can be used multiple times.
|
||||||
.It Ic dns-servers Ar primary-server-address Op Ar secondary-server-address
|
.It Ic dns-servers Ar primary-server-address Op Ar secondary-server-address
|
||||||
Specify the DNS servers' IP addresses.
|
Specify the DNS servers' IP addresses.
|
||||||
|
When this option is not specified and the authenticated realm
|
||||||
|
.Pq the RADIUS server
|
||||||
|
specifies the DNS servers' addresses,
|
||||||
|
they are used as the default.
|
||||||
|
To stop using them, set this option to
|
||||||
|
.Qq 0.0.0.0 .
|
||||||
.It Ic nbns-servers Ar primary-server-address Op Ar secondary-server-address
|
.It Ic nbns-servers Ar primary-server-address Op Ar secondary-server-address
|
||||||
Specify the NetBIOS name servers' IP addresses.
|
Specify the NetBIOS name servers' IP addresses.
|
||||||
|
When this option is not specified and the authenticated realm
|
||||||
|
.Pq the RADIUS server
|
||||||
|
specifies the NetBIOS servers' addresses,
|
||||||
|
they are used as the default.
|
||||||
|
To stop using them, set this option to
|
||||||
|
.Qq 0.0.0.0 .
|
||||||
.It Ic allow-user-selected-address Ar yes | no
|
.It Ic allow-user-selected-address Ar yes | no
|
||||||
Specify whether
|
Specify whether
|
||||||
.Xr npppd 8
|
.Xr npppd 8
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: npppd.h,v 1.19 2017/08/12 11:20:34 goda Exp $ */
|
/* $OpenBSD: npppd.h,v 1.20 2024/07/01 07:09:07 yasuoka Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
||||||
|
@ -174,7 +174,9 @@ struct ipcpconf {
|
||||||
TAILQ_ENTRY(ipcpconf) entry;
|
TAILQ_ENTRY(ipcpconf) entry;
|
||||||
char name[NPPPD_GENERIC_NAME_LEN];
|
char name[NPPPD_GENERIC_NAME_LEN];
|
||||||
bool dns_use_resolver;
|
bool dns_use_resolver;
|
||||||
|
bool dns_configured;
|
||||||
struct in_addr dns_servers[2];
|
struct in_addr dns_servers[2];
|
||||||
|
bool nbns_configured;
|
||||||
struct in_addr nbns_servers[2];
|
struct in_addr nbns_servers[2];
|
||||||
bool allow_user_select;
|
bool allow_user_select;
|
||||||
struct in_addr_range *dynamic_pool;
|
struct in_addr_range *dynamic_pool;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: npppd_radius.c,v 1.10 2024/02/26 10:42:05 yasuoka Exp $ */
|
/* $Id: npppd_radius.c,v 1.11 2024/07/01 07:09:07 yasuoka Exp $ */
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
|
@ -38,6 +38,7 @@
|
||||||
#include <sys/syslog.h>
|
#include <sys/syslog.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
@ -73,10 +74,11 @@ static void npppd_ppp_radius_acct_reqcb(void *, RADIUS_PACKET *, int, RADIUS_REQ
|
||||||
* the given RADIUS packet and set them as the fields of ppp context.
|
* the given RADIUS packet and set them as the fields of ppp context.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ppp_proccess_radius_framed_ip(npppd_ppp *_this, RADIUS_PACKET *pkt)
|
ppp_process_radius_attrs(npppd_ppp *_this, RADIUS_PACKET *pkt)
|
||||||
{
|
{
|
||||||
struct in_addr ip4;
|
struct in_addr ip4;
|
||||||
|
int got_pri, got_sec;
|
||||||
|
char buf0[40], buf1[40];
|
||||||
if (radius_get_ipv4_attr(pkt, RADIUS_TYPE_FRAMED_IP_ADDRESS, &ip4)
|
if (radius_get_ipv4_attr(pkt, RADIUS_TYPE_FRAMED_IP_ADDRESS, &ip4)
|
||||||
== 0)
|
== 0)
|
||||||
_this->realm_framed_ip_address = ip4;
|
_this->realm_framed_ip_address = ip4;
|
||||||
|
@ -87,6 +89,53 @@ ppp_proccess_radius_framed_ip(npppd_ppp *_this, RADIUS_PACKET *pkt)
|
||||||
== 0)
|
== 0)
|
||||||
_this->realm_framed_ip_netmask = ip4;
|
_this->realm_framed_ip_netmask = ip4;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!ppp_ipcp(_this)->dns_configured) {
|
||||||
|
got_pri = got_sec = 0;
|
||||||
|
if (radius_get_vs_ipv4_attr(pkt, RADIUS_VENDOR_MICROSOFT,
|
||||||
|
RADIUS_VTYPE_MS_PRIMARY_DNS_SERVER, &ip4) == 0) {
|
||||||
|
got_pri = 1;
|
||||||
|
_this->ipcp.dns_pri = ip4;
|
||||||
|
}
|
||||||
|
if (radius_get_vs_ipv4_attr(pkt, RADIUS_VENDOR_MICROSOFT,
|
||||||
|
RADIUS_VTYPE_MS_SECONDARY_DNS_SERVER, &ip4) == 0) {
|
||||||
|
got_sec = 1;
|
||||||
|
_this->ipcp.dns_sec = ip4;
|
||||||
|
}
|
||||||
|
if (got_pri || got_sec)
|
||||||
|
ppp_log(_this, LOG_INFO, "DNS server address%s "
|
||||||
|
"(%s%s%s) %s configured by RADIUS server",
|
||||||
|
((got_pri + got_sec) > 1)? "es" : "",
|
||||||
|
(got_pri)? inet_ntop(AF_INET, &_this->ipcp.dns_pri,
|
||||||
|
buf0, sizeof(buf0)) : "",
|
||||||
|
(got_pri != 0 && got_sec != 0)? "," : "",
|
||||||
|
(got_sec)? inet_ntop(AF_INET, &_this->ipcp.dns_sec,
|
||||||
|
buf1, sizeof(buf1)) : "",
|
||||||
|
((got_pri + got_sec) > 1)? "are" : "is");
|
||||||
|
}
|
||||||
|
if (!ppp_ipcp(_this)->nbns_configured) {
|
||||||
|
got_pri = got_sec = 0;
|
||||||
|
if (radius_get_vs_ipv4_attr(pkt, RADIUS_VENDOR_MICROSOFT,
|
||||||
|
RADIUS_VTYPE_MS_PRIMARY_NBNS_SERVER, &ip4) == 0) {
|
||||||
|
got_pri = 1;
|
||||||
|
_this->ipcp.nbns_pri = ip4;
|
||||||
|
}
|
||||||
|
if (radius_get_vs_ipv4_attr(pkt, RADIUS_VENDOR_MICROSOFT,
|
||||||
|
RADIUS_VTYPE_MS_SECONDARY_NBNS_SERVER, &ip4) == 0) {
|
||||||
|
got_sec = 1;
|
||||||
|
_this->ipcp.nbns_sec = ip4;
|
||||||
|
}
|
||||||
|
if (got_pri || got_sec)
|
||||||
|
ppp_log(_this, LOG_INFO, "NBNS server address%s "
|
||||||
|
"(%s%s%s) %s configured by RADIUS server",
|
||||||
|
((got_pri + got_sec) > 1)? "es" : "",
|
||||||
|
(got_pri)? inet_ntop(AF_INET, &_this->ipcp.nbns_pri,
|
||||||
|
buf0, sizeof(buf0)) : "",
|
||||||
|
(got_pri != 0 && got_sec != 0)? "," : "",
|
||||||
|
(got_sec)? inet_ntop(AF_INET, &_this->ipcp.nbns_sec,
|
||||||
|
buf1, sizeof(buf1)) : "",
|
||||||
|
((got_pri + got_sec) > 1)? "are" : "is");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -480,3 +529,35 @@ fail:
|
||||||
#endif
|
#endif
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set RADIUS attributes for RADIUS authentication request.
|
||||||
|
* Return 0 on success.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
ppp_set_radius_attrs_for_authreq(npppd_ppp *_this,
|
||||||
|
radius_req_setting *rad_setting, RADIUS_PACKET *radpkt)
|
||||||
|
{
|
||||||
|
/* RFC 2865 "5.4 NAS-IP-Address" or RFC3162 "2.1. NAS-IPv6-Address" */
|
||||||
|
if (radius_prepare_nas_address(rad_setting, radpkt) != 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* RFC 2865 "5.6. Service-Type" */
|
||||||
|
if (radius_put_uint32_attr(radpkt, RADIUS_TYPE_SERVICE_TYPE,
|
||||||
|
RADIUS_SERVICE_TYPE_FRAMED) != 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* RFC 2865 "5.7. Framed-Protocol" */
|
||||||
|
if (radius_put_uint32_attr(radpkt, RADIUS_TYPE_FRAMED_PROTOCOL,
|
||||||
|
RADIUS_FRAMED_PROTOCOL_PPP) != 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (_this->calling_number[0] != '\0') {
|
||||||
|
if (radius_put_string_attr(radpkt,
|
||||||
|
RADIUS_TYPE_CALLING_STATION_ID, _this->calling_number) != 0)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: pap.c,v 1.13 2024/02/26 08:47:28 yasuoka Exp $ */
|
/* $OpenBSD: pap.c,v 1.14 2024/07/01 07:09:07 yasuoka Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
/* $Id: pap.c,v 1.13 2024/02/26 08:47:28 yasuoka Exp $ */
|
/* $Id: pap.c,v 1.14 2024/07/01 07:09:07 yasuoka Exp $ */
|
||||||
/**@file
|
/**@file
|
||||||
* This file provides Password Authentication Protocol (PAP) handlers.
|
* This file provides Password Authentication Protocol (PAP) handlers.
|
||||||
* @author Yasuoka Masahiko
|
* @author Yasuoka Masahiko
|
||||||
|
@ -508,7 +508,7 @@ pap_radius_response(void *context, RADIUS_PACKET *pkt, int flags,
|
||||||
}
|
}
|
||||||
/* Authentication succeeded */
|
/* Authentication succeeded */
|
||||||
pap_response(_this, 1, DEFAULT_SUCCESS_MESSAGE);
|
pap_response(_this, 1, DEFAULT_SUCCESS_MESSAGE);
|
||||||
ppp_process_radius_framed_ip(_this->ppp, pkt);
|
ppp_process_radius_attrs(_this->ppp, pkt);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
auth_failed:
|
auth_failed:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: parse.y,v 1.27 2023/04/19 13:33:37 jsg Exp $ */
|
/* $OpenBSD: parse.y,v 1.28 2024/07/01 07:09:07 yasuoka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
|
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||||
|
@ -818,19 +818,23 @@ ipcpopt : POOL_ADDRESS STRING ipcppooltype {
|
||||||
}
|
}
|
||||||
| DNS_SERVERS in4_addr in4_addr {
|
| DNS_SERVERS in4_addr in4_addr {
|
||||||
curr_ipcpconf->dns_use_resolver = false;
|
curr_ipcpconf->dns_use_resolver = false;
|
||||||
|
curr_ipcpconf->dns_configured = true;
|
||||||
curr_ipcpconf->dns_servers[0] = $2;
|
curr_ipcpconf->dns_servers[0] = $2;
|
||||||
curr_ipcpconf->dns_servers[1] = $3;
|
curr_ipcpconf->dns_servers[1] = $3;
|
||||||
}
|
}
|
||||||
| DNS_SERVERS in4_addr {
|
| DNS_SERVERS in4_addr {
|
||||||
curr_ipcpconf->dns_use_resolver = false;
|
curr_ipcpconf->dns_use_resolver = false;
|
||||||
|
curr_ipcpconf->dns_configured = true;
|
||||||
curr_ipcpconf->dns_servers[0] = $2;
|
curr_ipcpconf->dns_servers[0] = $2;
|
||||||
curr_ipcpconf->dns_servers[1].s_addr = 0;
|
curr_ipcpconf->dns_servers[1].s_addr = 0;
|
||||||
}
|
}
|
||||||
| NBNS_SERVERS in4_addr in4_addr {
|
| NBNS_SERVERS in4_addr in4_addr {
|
||||||
|
curr_ipcpconf->nbns_configured = true;
|
||||||
curr_ipcpconf->nbns_servers[0] = $2;
|
curr_ipcpconf->nbns_servers[0] = $2;
|
||||||
curr_ipcpconf->nbns_servers[1] = $3;
|
curr_ipcpconf->nbns_servers[1] = $3;
|
||||||
}
|
}
|
||||||
| NBNS_SERVERS in4_addr {
|
| NBNS_SERVERS in4_addr {
|
||||||
|
curr_ipcpconf->nbns_configured = true;
|
||||||
curr_ipcpconf->nbns_servers[0] = $2;
|
curr_ipcpconf->nbns_servers[0] = $2;
|
||||||
curr_ipcpconf->nbns_servers[1].s_addr = 0;
|
curr_ipcpconf->nbns_servers[1].s_addr = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: ppp.c,v 1.31 2024/02/26 10:42:05 yasuoka Exp $ */
|
/* $OpenBSD: ppp.c,v 1.32 2024/07/01 07:09:07 yasuoka Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
||||||
|
@ -25,7 +25,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*/
|
*/
|
||||||
/* $Id: ppp.c,v 1.31 2024/02/26 10:42:05 yasuoka Exp $ */
|
/* $Id: ppp.c,v 1.32 2024/07/01 07:09:07 yasuoka Exp $ */
|
||||||
/**@file
|
/**@file
|
||||||
* This file provides PPP(Point-to-Point Protocol, RFC 1661) and
|
* This file provides PPP(Point-to-Point Protocol, RFC 1661) and
|
||||||
* {@link :: _npppd_ppp PPP instance} related functions.
|
* {@link :: _npppd_ppp PPP instance} related functions.
|
||||||
|
@ -1061,65 +1061,6 @@ ppp_log(npppd_ppp *_this, int prio, const char *fmt, ...)
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef USE_NPPPD_RADIUS
|
|
||||||
#define UCHAR_BUFSIZ 255
|
|
||||||
/**
|
|
||||||
* Process the Framed-IP-Address attribute and the Framed-IP-Netmask
|
|
||||||
* attribute of given RADIUS packet.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
ppp_process_radius_framed_ip(npppd_ppp *_this, RADIUS_PACKET *pkt)
|
|
||||||
{
|
|
||||||
struct in_addr ip4;
|
|
||||||
|
|
||||||
if (radius_get_ipv4_attr(pkt, RADIUS_TYPE_FRAMED_IP_ADDRESS, &ip4)
|
|
||||||
== 0)
|
|
||||||
_this->realm_framed_ip_address = ip4;
|
|
||||||
|
|
||||||
_this->realm_framed_ip_netmask.s_addr = 0xffffffffL;
|
|
||||||
if (radius_get_ipv4_attr(pkt, RADIUS_TYPE_FRAMED_IP_NETMASK, &ip4)
|
|
||||||
== 0)
|
|
||||||
_this->realm_framed_ip_netmask = ip4;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set RADIUS attributes for RADIUS authentication request.
|
|
||||||
* Return 0 on success.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
ppp_set_radius_attrs_for_authreq(npppd_ppp *_this,
|
|
||||||
radius_req_setting *rad_setting, RADIUS_PACKET *radpkt)
|
|
||||||
{
|
|
||||||
/* RFC 2865 "5.4 NAS-IP-Address" or RFC3162 "2.1. NAS-IPv6-Address" */
|
|
||||||
if (radius_prepare_nas_address(rad_setting, radpkt) != 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* RFC 2865 5.32. NAS-Identifier */
|
|
||||||
if (radius_put_string_attr(radpkt, RADIUS_TYPE_NAS_IDENTIFIER, "npppd")
|
|
||||||
!= 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* RFC 2865 "5.6. Service-Type" */
|
|
||||||
if (radius_put_uint32_attr(radpkt, RADIUS_TYPE_SERVICE_TYPE,
|
|
||||||
RADIUS_SERVICE_TYPE_FRAMED) != 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* RFC 2865 "5.7. Framed-Protocol" */
|
|
||||||
if (radius_put_uint32_attr(radpkt, RADIUS_TYPE_FRAMED_PROTOCOL,
|
|
||||||
RADIUS_FRAMED_PROTOCOL_PPP) != 0)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (_this->calling_number[0] != '\0') {
|
|
||||||
if (radius_put_string_attr(radpkt,
|
|
||||||
RADIUS_TYPE_CALLING_STATION_ID, _this->calling_number) != 0)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
fail:
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_NPPPD_PIPEX
|
#ifdef USE_NPPPD_PIPEX
|
||||||
/** The callback function on network is available for pipex */
|
/** The callback function on network is available for pipex */
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: ppp.h,v 1.24 2022/12/28 21:30:17 jmc Exp $ */
|
/* $OpenBSD: ppp.h,v 1.25 2024/07/01 07:09:07 yasuoka Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
||||||
|
@ -779,7 +779,7 @@ u_char *ppp_packetbuf (npppd_ppp *, int);
|
||||||
int ppp_log (npppd_ppp *, int, const char *, ...) __printflike(3,4);
|
int ppp_log (npppd_ppp *, int, const char *, ...) __printflike(3,4);
|
||||||
void ppp_reset_idle_timeout(npppd_ppp *);
|
void ppp_reset_idle_timeout(npppd_ppp *);
|
||||||
#ifdef USE_NPPPD_RADIUS
|
#ifdef USE_NPPPD_RADIUS
|
||||||
void ppp_process_radius_framed_ip (npppd_ppp *, RADIUS_PACKET *);
|
void ppp_process_radius_attrs (npppd_ppp *, RADIUS_PACKET *);
|
||||||
int ppp_set_radius_attrs_for_authreq (npppd_ppp *, radius_req_setting *, RADIUS_PACKET *);
|
int ppp_set_radius_attrs_for_authreq (npppd_ppp *, radius_req_setting *, RADIUS_PACKET *);
|
||||||
#endif
|
#endif
|
||||||
struct tunnconf *ppp_get_tunnconf(npppd_ppp *);
|
struct tunnconf *ppp_get_tunnconf(npppd_ppp *);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: parse.y,v 1.17 2023/09/08 05:56:22 yasuoka Exp $ */
|
/* $OpenBSD: parse.y,v 1.20 2024/07/02 00:33:51 yasuoka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
|
* Copyright (c) 2002, 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||||
|
@ -37,14 +37,17 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
static struct radiusd *conf;
|
static struct radiusd *conf;
|
||||||
static struct radiusd_authentication authen;
|
static struct radiusd_authentication authen;
|
||||||
static struct radiusd_client client;
|
static struct radiusd_module *conf_module = NULL;
|
||||||
|
static struct radiusd_client client;
|
||||||
|
|
||||||
static struct radiusd_module *find_module (const char *);
|
static struct radiusd_module *find_module(const char *);
|
||||||
static void free_str_l (void *);
|
static void free_str_l(void *);
|
||||||
static struct radiusd_module_ref *create_module_ref (const char *);
|
static struct radiusd_module_ref *create_module_ref(const char *);
|
||||||
static void radiusd_authentication_init (struct radiusd_authentication *);
|
static void radiusd_authentication_init(struct radiusd_authentication *);
|
||||||
static void radiusd_client_init (struct radiusd_client *);
|
static void radiusd_client_init(struct radiusd_client *);
|
||||||
|
static const char
|
||||||
|
*default_module_path(const char *);
|
||||||
|
|
||||||
TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
|
TAILQ_HEAD(files, file) files = TAILQ_HEAD_INITIALIZER(files);
|
||||||
static struct file {
|
static struct file {
|
||||||
|
@ -89,17 +92,18 @@ typedef struct {
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%token INCLUDE LISTEN ON PORT CLIENT SECRET LOAD MODULE MSGAUTH_REQUIRED
|
%token INCLUDE LISTEN ON PORT CLIENT SECRET LOAD MODULE MSGAUTH_REQUIRED
|
||||||
%token AUTHENTICATE AUTHENTICATE_BY DECORATE_BY SET
|
%token ACCOUNT ACCOUNTING AUTHENTICATE AUTHENTICATE_BY BY DECORATE_BY QUICK
|
||||||
%token ERROR YES NO
|
%token SET TO ERROR YES NO
|
||||||
%token <v.string> STRING
|
%token <v.string> STRING
|
||||||
%token <v.number> NUMBER
|
%token <v.number> NUMBER
|
||||||
%type <v.number> optport
|
%type <v.number> optport optacct
|
||||||
%type <v.listen> listen_addr
|
%type <v.listen> listen_addr
|
||||||
%type <v.str_l> str_l
|
%type <v.str_l> str_l optdeco
|
||||||
%type <v.prefix> prefix
|
%type <v.prefix> prefix
|
||||||
%type <v.yesno> yesno
|
%type <v.yesno> yesno optquick
|
||||||
%type <v.string> strnum
|
%type <v.string> strnum
|
||||||
%type <v.string> key
|
%type <v.string> key
|
||||||
|
%type <v.string> optstring
|
||||||
%%
|
%%
|
||||||
|
|
||||||
grammar : /* empty */
|
grammar : /* empty */
|
||||||
|
@ -109,6 +113,7 @@ grammar : /* empty */
|
||||||
| grammar client '\n'
|
| grammar client '\n'
|
||||||
| grammar module '\n'
|
| grammar module '\n'
|
||||||
| grammar authenticate '\n'
|
| grammar authenticate '\n'
|
||||||
|
| grammar account '\n'
|
||||||
| grammar error '\n'
|
| grammar error '\n'
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -139,7 +144,7 @@ outofmemory:
|
||||||
*n = $3;
|
*n = $3;
|
||||||
TAILQ_INSERT_TAIL(&conf->listen, n, next);
|
TAILQ_INSERT_TAIL(&conf->listen, n, next);
|
||||||
}
|
}
|
||||||
listen_addr : STRING optport {
|
listen_addr : STRING optacct optport {
|
||||||
int gai_errno;
|
int gai_errno;
|
||||||
struct addrinfo hints, *res;
|
struct addrinfo hints, *res;
|
||||||
|
|
||||||
|
@ -160,11 +165,22 @@ listen_addr : STRING optport {
|
||||||
free($1);
|
free($1);
|
||||||
$$.stype = res->ai_socktype;
|
$$.stype = res->ai_socktype;
|
||||||
$$.sproto = res->ai_protocol;
|
$$.sproto = res->ai_protocol;
|
||||||
|
$$.accounting = $2;
|
||||||
memcpy(&$$.addr, res->ai_addr, res->ai_addrlen);
|
memcpy(&$$.addr, res->ai_addr, res->ai_addrlen);
|
||||||
$$.addr.ipv4.sin_port = ($2 == 0)?
|
if ($3 != 0)
|
||||||
htons(RADIUS_DEFAULT_PORT) : htons($2);
|
$$.addr.ipv4.sin_port = htons($3);
|
||||||
|
else if ($2)
|
||||||
|
$$.addr.ipv4.sin_port =
|
||||||
|
htons(RADIUS_ACCT_DEFAULT_PORT);
|
||||||
|
else
|
||||||
|
$$.addr.ipv4.sin_port =
|
||||||
|
htons(RADIUS_DEFAULT_PORT);
|
||||||
|
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
}
|
}
|
||||||
|
optacct : ACCOUNTING { $$ = 1; }
|
||||||
|
| { $$ = 0; }
|
||||||
|
;
|
||||||
optport : { $$ = 0; }
|
optport : { $$ = 0; }
|
||||||
| PORT NUMBER { $$ = $2; }
|
| PORT NUMBER { $$ = $2; }
|
||||||
;
|
;
|
||||||
|
@ -265,7 +281,45 @@ prefix : STRING '/' NUMBER {
|
||||||
freeaddrinfo(res);
|
freeaddrinfo(res);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
module : MODULE LOAD STRING STRING {
|
module : MODULE STRING optstring {
|
||||||
|
const char *path = $3;
|
||||||
|
if (path == NULL && (path = default_module_path($2))
|
||||||
|
== NULL) {
|
||||||
|
yyerror("default path for `%s' is unknown.",
|
||||||
|
$2);
|
||||||
|
free($2);
|
||||||
|
free($3);
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
|
conf_module = radiusd_module_load(conf, path, $2);
|
||||||
|
free($2);
|
||||||
|
free($3);
|
||||||
|
if (conf_module == NULL)
|
||||||
|
YYERROR;
|
||||||
|
TAILQ_INSERT_TAIL(&conf->module, conf_module, next);
|
||||||
|
conf_module = NULL;
|
||||||
|
}
|
||||||
|
| MODULE STRING optstring {
|
||||||
|
const char *path = $3;
|
||||||
|
if (path == NULL && (path = default_module_path($2))
|
||||||
|
== NULL) {
|
||||||
|
yyerror("default path for `%s' is unknown.",
|
||||||
|
$2);
|
||||||
|
free($2);
|
||||||
|
free($3);
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
|
conf_module = radiusd_module_load(conf, path, $2);
|
||||||
|
free($2);
|
||||||
|
free($3);
|
||||||
|
if (conf_module == NULL)
|
||||||
|
YYERROR;
|
||||||
|
} '{' moduleopts '}' {
|
||||||
|
TAILQ_INSERT_TAIL(&conf->module, conf_module, next);
|
||||||
|
conf_module = NULL;
|
||||||
|
}
|
||||||
|
/* following syntaxes are for backward compatilities */
|
||||||
|
| MODULE LOAD STRING STRING {
|
||||||
struct radiusd_module *module;
|
struct radiusd_module *module;
|
||||||
if ((module = radiusd_module_load(conf, $4, $3))
|
if ((module = radiusd_module_load(conf, $4, $3))
|
||||||
== NULL) {
|
== NULL) {
|
||||||
|
@ -303,34 +357,104 @@ setstrerr:
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
moduleopts : moduleopts '\n' moduleopt
|
||||||
|
| moduleopt
|
||||||
|
;
|
||||||
|
moduleopt : /* empty */
|
||||||
|
| SET key str_l {
|
||||||
|
if ($2[0] == '_') {
|
||||||
|
yyerror("setting `%s' is not allowed", $2);
|
||||||
|
free($2);
|
||||||
|
free_str_l(&$3);
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
|
if (radiusd_module_set(conf_module, $2, $3.c, $3.v)) {
|
||||||
|
yyerror("syntax error by module `%s'",
|
||||||
|
conf_module->name);
|
||||||
|
free($2);
|
||||||
|
free_str_l(&$3);
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
|
free($2);
|
||||||
|
free_str_l(&$3);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
key : STRING
|
key : STRING
|
||||||
| SECRET { $$ = strdup("secret"); }
|
| SECRET { $$ = strdup("secret"); }
|
||||||
;
|
;
|
||||||
|
|
||||||
authenticate : AUTHENTICATE {
|
authenticate : AUTHENTICATE str_l BY STRING optdeco {
|
||||||
|
int i;
|
||||||
|
struct radiusd_authentication *auth;
|
||||||
|
struct radiusd_module_ref *modref, *modreft;
|
||||||
|
|
||||||
|
if ((auth = calloc(1,
|
||||||
|
sizeof(struct radiusd_authentication))) == NULL) {
|
||||||
|
yyerror("Out of memory: %s", strerror(errno));
|
||||||
|
goto authenticate_error;
|
||||||
|
}
|
||||||
|
modref = create_module_ref($4);
|
||||||
|
if ((auth->auth = create_module_ref($4)) == NULL)
|
||||||
|
goto authenticate_error;
|
||||||
|
auth->username = $2.v;
|
||||||
|
TAILQ_INIT(&auth->deco);
|
||||||
|
for (i = 0; i < $5.c; i++) {
|
||||||
|
if ((modref = create_module_ref($5.v[i]))
|
||||||
|
== NULL)
|
||||||
|
goto authenticate_error;
|
||||||
|
TAILQ_INSERT_TAIL(&auth->deco, modref, next);
|
||||||
|
}
|
||||||
|
TAILQ_INSERT_TAIL(&conf->authen, auth, next);
|
||||||
|
auth = NULL;
|
||||||
|
authenticate_error:
|
||||||
|
if (auth != NULL) {
|
||||||
|
free(auth->auth);
|
||||||
|
TAILQ_FOREACH_SAFE(modref, &auth->deco, next,
|
||||||
|
modreft) {
|
||||||
|
TAILQ_REMOVE(&auth->deco, modref, next);
|
||||||
|
free(modref);
|
||||||
|
}
|
||||||
|
free_str_l(&$2);
|
||||||
|
}
|
||||||
|
free(auth);
|
||||||
|
free($4);
|
||||||
|
free_str_l(&$5);
|
||||||
|
}
|
||||||
|
/* the followings are for backward compatibilities */
|
||||||
|
| AUTHENTICATE str_l optnl '{' {
|
||||||
radiusd_authentication_init(&authen);
|
radiusd_authentication_init(&authen);
|
||||||
} str_l optnl '{' authopts '}' {
|
authen.username = $2.v;
|
||||||
struct radiusd_authentication *a;
|
} authopts '}' {
|
||||||
|
int i;
|
||||||
|
struct radiusd_authentication *a;
|
||||||
|
|
||||||
if (authen.auth == NULL) {
|
if (authen.auth == NULL) {
|
||||||
free_str_l(&$3);
|
|
||||||
yyerror("no authentication module specified");
|
yyerror("no authentication module specified");
|
||||||
|
for (i = 0; authen.username[i] != NULL; i++)
|
||||||
|
free(authen.username[i]);
|
||||||
|
free(authen.username);
|
||||||
YYERROR;
|
YYERROR;
|
||||||
}
|
}
|
||||||
if ((a = calloc(1,
|
if ((a = calloc(1,
|
||||||
sizeof(struct radiusd_authentication))) == NULL) {
|
sizeof(struct radiusd_authentication))) == NULL) {
|
||||||
free_str_l(&$3);
|
for (i = 0; authen.username[i] != NULL; i++)
|
||||||
|
free(authen.username[i]);
|
||||||
|
free(authen.username);
|
||||||
goto outofmemory;
|
goto outofmemory;
|
||||||
}
|
}
|
||||||
a->auth = authen.auth;
|
a->auth = authen.auth;
|
||||||
authen.auth = NULL;
|
authen.auth = NULL;
|
||||||
a->deco = authen.deco;
|
a->deco = authen.deco;
|
||||||
a->username = $3.v;
|
a->username = authen.username;
|
||||||
|
|
||||||
TAILQ_INSERT_TAIL(&conf->authen, a, next);
|
TAILQ_INSERT_TAIL(&conf->authen, a, next);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
optdeco : { $$.c = 0; $$.v = NULL; }
|
||||||
|
| DECORATE_BY str_l { $$ = $2; }
|
||||||
|
;
|
||||||
|
|
||||||
authopts : authopts '\n' authopt
|
authopts : authopts '\n' authopt
|
||||||
| authopt
|
| authopt
|
||||||
;
|
;
|
||||||
|
@ -363,8 +487,53 @@ authopt : AUTHENTICATE_BY STRING {
|
||||||
}
|
}
|
||||||
free_str_l(&$2);
|
free_str_l(&$2);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
account : ACCOUNT optquick str_l TO STRING optdeco {
|
||||||
|
int i, error = 1;
|
||||||
|
struct radiusd_accounting *acct;
|
||||||
|
struct radiusd_module_ref *modref, *modreft;
|
||||||
|
|
||||||
|
if ((acct = calloc(1,
|
||||||
|
sizeof(struct radiusd_authentication))) == NULL) {
|
||||||
|
yyerror("Out of memory: %s", strerror(errno));
|
||||||
|
goto account_error;
|
||||||
|
}
|
||||||
|
if ((acct->acct = create_module_ref($5)) == NULL)
|
||||||
|
goto account_error;
|
||||||
|
acct->username = $3.v;
|
||||||
|
acct->quick = $2;
|
||||||
|
TAILQ_INIT(&acct->deco);
|
||||||
|
for (i = 0; i < $6.c; i++) {
|
||||||
|
if ((modref = create_module_ref($6.v[i]))
|
||||||
|
== NULL)
|
||||||
|
goto account_error;
|
||||||
|
TAILQ_INSERT_TAIL(&acct->deco, modref, next);
|
||||||
|
}
|
||||||
|
TAILQ_INSERT_TAIL(&conf->account, acct, next);
|
||||||
|
acct = NULL;
|
||||||
|
error = 0;
|
||||||
|
account_error:
|
||||||
|
if (acct != NULL) {
|
||||||
|
free(acct->acct);
|
||||||
|
TAILQ_FOREACH_SAFE(modref, &acct->deco, next,
|
||||||
|
modreft) {
|
||||||
|
TAILQ_REMOVE(&acct->deco, modref, next);
|
||||||
|
free(modref);
|
||||||
|
}
|
||||||
|
free_str_l(&$3);
|
||||||
|
}
|
||||||
|
free(acct);
|
||||||
|
free($5);
|
||||||
|
free_str_l(&$6);
|
||||||
|
if (error > 0)
|
||||||
|
YYERROR;
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
|
optquick : { $$ = 0; }
|
||||||
|
| QUICK { $$ = 1; }
|
||||||
|
|
||||||
str_l : str_l strnum {
|
str_l : str_l strnum {
|
||||||
int i;
|
int i;
|
||||||
char **v;
|
char **v;
|
||||||
|
@ -397,6 +566,9 @@ strnum : STRING { $$ = $1; }
|
||||||
optnl :
|
optnl :
|
||||||
| '\n'
|
| '\n'
|
||||||
;
|
;
|
||||||
|
optstring : { $$ = NULL; }
|
||||||
|
| STRING { $$ = $1; }
|
||||||
|
;
|
||||||
yesno : YES { $$ = true; }
|
yesno : YES { $$ = true; }
|
||||||
| NO { $$ = false; }
|
| NO { $$ = false; }
|
||||||
;
|
;
|
||||||
|
@ -434,8 +606,11 @@ lookup(char *s)
|
||||||
{
|
{
|
||||||
/* this has to be sorted always */
|
/* this has to be sorted always */
|
||||||
static const struct keywords keywords[] = {
|
static const struct keywords keywords[] = {
|
||||||
|
{ "account", ACCOUNT},
|
||||||
|
{ "accounting", ACCOUNTING},
|
||||||
{ "authenticate", AUTHENTICATE},
|
{ "authenticate", AUTHENTICATE},
|
||||||
{ "authenticate-by", AUTHENTICATE_BY},
|
{ "authenticate-by", AUTHENTICATE_BY},
|
||||||
|
{ "by", BY},
|
||||||
{ "client", CLIENT},
|
{ "client", CLIENT},
|
||||||
{ "decorate-by", DECORATE_BY},
|
{ "decorate-by", DECORATE_BY},
|
||||||
{ "include", INCLUDE},
|
{ "include", INCLUDE},
|
||||||
|
@ -446,8 +621,10 @@ lookup(char *s)
|
||||||
{ "no", NO},
|
{ "no", NO},
|
||||||
{ "on", ON},
|
{ "on", ON},
|
||||||
{ "port", PORT},
|
{ "port", PORT},
|
||||||
|
{ "quick", QUICK},
|
||||||
{ "secret", SECRET},
|
{ "secret", SECRET},
|
||||||
{ "set", SET},
|
{ "set", SET},
|
||||||
|
{ "to", TO},
|
||||||
{ "yes", YES},
|
{ "yes", YES},
|
||||||
};
|
};
|
||||||
const struct keywords *p;
|
const struct keywords *p;
|
||||||
|
@ -724,7 +901,6 @@ parse_config(const char *filename, struct radiusd *radiusd)
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
struct radiusd_listen *l;
|
struct radiusd_listen *l;
|
||||||
struct radiusd_module_ref *m, *mt;
|
|
||||||
|
|
||||||
conf = radiusd;
|
conf = radiusd;
|
||||||
radiusd_conf_init(conf);
|
radiusd_conf_init(conf);
|
||||||
|
@ -758,10 +934,8 @@ parse_config(const char *filename, struct radiusd *radiusd)
|
||||||
l->sock = -1;
|
l->sock = -1;
|
||||||
}
|
}
|
||||||
radiusd_authentication_init(&authen);
|
radiusd_authentication_init(&authen);
|
||||||
TAILQ_FOREACH_SAFE(m, &authen.deco, next, mt) {
|
if (conf_module != NULL)
|
||||||
TAILQ_REMOVE(&authen.deco, m, next);
|
radiusd_module_unload(conf_module);
|
||||||
free(m);
|
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
conf = NULL;
|
conf = NULL;
|
||||||
return (errors ? -1 : 0);
|
return (errors ? -1 : 0);
|
||||||
|
@ -827,3 +1001,24 @@ radiusd_client_init(struct radiusd_client *clnt)
|
||||||
memset(clnt, 0, sizeof(struct radiusd_client));
|
memset(clnt, 0, sizeof(struct radiusd_client));
|
||||||
clnt->msgauth_required = true;
|
clnt->msgauth_required = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
default_module_path(const char *name)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
struct {
|
||||||
|
const char *name;
|
||||||
|
const char *path;
|
||||||
|
} module_paths[] = {
|
||||||
|
{ "bsdauth", "/usr/libexec/radiusd/radiusd_bsdauth" },
|
||||||
|
{ "radius", "/usr/libexec/radiusd/radiusd_radius" },
|
||||||
|
{ "standard", "/usr/libexec/radiusd/radiusd_standard" }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < nitems(module_paths); i++) {
|
||||||
|
if (strcmp(name, module_paths[i].name) == 0)
|
||||||
|
return (module_paths[i].path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: radiusd.c,v 1.36 2024/02/14 02:44:58 jsg Exp $ */
|
/* $OpenBSD: radiusd.c,v 1.44 2024/07/02 00:33:51 yasuoka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2023 Internet Initiative Japan Inc.
|
* Copyright (c) 2013, 2023 Internet Initiative Japan Inc.
|
||||||
|
@ -33,6 +33,7 @@
|
||||||
#include <imsg.h>
|
#include <imsg.h>
|
||||||
#include <md5.h>
|
#include <md5.h>
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
#include <paths.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
@ -62,15 +63,18 @@ static void radiusd_on_sighup(int, short, void *);
|
||||||
static void radiusd_on_sigchld(int, short, void *);
|
static void radiusd_on_sigchld(int, short, void *);
|
||||||
static void raidus_query_access_request(struct radius_query *);
|
static void raidus_query_access_request(struct radius_query *);
|
||||||
static void radius_query_access_response(struct radius_query *);
|
static void radius_query_access_response(struct radius_query *);
|
||||||
|
static void raidus_query_accounting_request(
|
||||||
|
struct radiusd_accounting *, struct radius_query *);
|
||||||
|
static void radius_query_accounting_response(struct radius_query *);
|
||||||
static const char *radius_code_string(int);
|
static const char *radius_code_string(int);
|
||||||
|
static const char *radius_acct_status_type_string(uint32_t);
|
||||||
static int radiusd_access_response_fixup (struct radius_query *);
|
static int radiusd_access_response_fixup (struct radius_query *);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void radiusd_module_reset_ev_handler(
|
static void radiusd_module_reset_ev_handler(
|
||||||
struct radiusd_module *);
|
struct radiusd_module *);
|
||||||
static int radiusd_module_imsg_read(struct radiusd_module *,
|
static int radiusd_module_imsg_read(struct radiusd_module *);
|
||||||
bool);
|
|
||||||
static void radiusd_module_imsg(struct radiusd_module *,
|
static void radiusd_module_imsg(struct radiusd_module *,
|
||||||
struct imsg *);
|
struct imsg *);
|
||||||
|
|
||||||
|
@ -89,8 +93,11 @@ static void radiusd_module_request_decoration(
|
||||||
struct radiusd_module *, struct radius_query *);
|
struct radiusd_module *, struct radius_query *);
|
||||||
static void radiusd_module_response_decoration(
|
static void radiusd_module_response_decoration(
|
||||||
struct radiusd_module *, struct radius_query *);
|
struct radiusd_module *, struct radius_query *);
|
||||||
|
static void radiusd_module_account_request(struct radiusd_module *,
|
||||||
|
struct radius_query *);
|
||||||
static int imsg_compose_radius_packet(struct imsgbuf *,
|
static int imsg_compose_radius_packet(struct imsgbuf *,
|
||||||
uint32_t, u_int, RADIUS_PACKET *);
|
uint32_t, u_int, RADIUS_PACKET *);
|
||||||
|
static void close_stdio(void);
|
||||||
|
|
||||||
static u_int radius_query_id_seq = 0;
|
static u_int radius_query_id_seq = 0;
|
||||||
int debug = 0;
|
int debug = 0;
|
||||||
|
@ -144,16 +151,20 @@ main(int argc, char *argv[])
|
||||||
TAILQ_INIT(&radiusd->listen);
|
TAILQ_INIT(&radiusd->listen);
|
||||||
TAILQ_INIT(&radiusd->query);
|
TAILQ_INIT(&radiusd->query);
|
||||||
|
|
||||||
log_init(debug);
|
if (!noaction && debug == 0)
|
||||||
|
daemon(0, 1); /* pend closing stdio files */
|
||||||
|
|
||||||
if (parse_config(conffile, radiusd) != 0)
|
if (parse_config(conffile, radiusd) != 0)
|
||||||
errx(EXIT_FAILURE, "config error");
|
errx(EXIT_FAILURE, "config error");
|
||||||
|
log_init(debug);
|
||||||
if (noaction) {
|
if (noaction) {
|
||||||
fprintf(stderr, "configuration OK\n");
|
fprintf(stderr, "configuration OK\n");
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (debug == 0)
|
if (debug == 0)
|
||||||
daemon(0, 0);
|
close_stdio(); /* close stdio files now */
|
||||||
|
|
||||||
event_init();
|
event_init();
|
||||||
|
|
||||||
if ((pw = getpwnam(RADIUSD_USER)) == NULL)
|
if ((pw = getpwnam(RADIUSD_USER)) == NULL)
|
||||||
|
@ -187,10 +198,16 @@ main(int argc, char *argv[])
|
||||||
if (event_loop(0) < 0)
|
if (event_loop(0) < 0)
|
||||||
radiusd_stop(radiusd);
|
radiusd_stop(radiusd);
|
||||||
|
|
||||||
|
if (radiusd->error != 0)
|
||||||
|
log_warnx("exiting on error");
|
||||||
|
|
||||||
radiusd_free(radiusd);
|
radiusd_free(radiusd);
|
||||||
event_base_free(NULL);
|
event_base_free(NULL);
|
||||||
|
|
||||||
exit(EXIT_SUCCESS);
|
if (radiusd->error != 0)
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
else
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -198,7 +215,7 @@ radiusd_start(struct radiusd *radiusd)
|
||||||
{
|
{
|
||||||
struct radiusd_listen *l;
|
struct radiusd_listen *l;
|
||||||
struct radiusd_module *module;
|
struct radiusd_module *module;
|
||||||
int s;
|
int s, on;
|
||||||
char hbuf[NI_MAXHOST];
|
char hbuf[NI_MAXHOST];
|
||||||
|
|
||||||
TAILQ_FOREACH(l, &radiusd->listen, next) {
|
TAILQ_FOREACH(l, &radiusd->listen, next) {
|
||||||
|
@ -214,6 +231,12 @@ radiusd_start(struct radiusd *radiusd)
|
||||||
hbuf, (int)htons(l->addr.ipv4.sin_port));
|
hbuf, (int)htons(l->addr.ipv4.sin_port));
|
||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
on = 1;
|
||||||
|
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))
|
||||||
|
== -1)
|
||||||
|
log_warn("%s: setsockopt(,,SO_REUSEADDR) failed: %m",
|
||||||
|
__func__);
|
||||||
if (bind(s, (struct sockaddr *)&l->addr, l->addr.ipv4.sin_len)
|
if (bind(s, (struct sockaddr *)&l->addr, l->addr.ipv4.sin_len)
|
||||||
!= 0) {
|
!= 0) {
|
||||||
log_warn("Listen %s port %d is failed: bind()",
|
log_warn("Listen %s port %d is failed: bind()",
|
||||||
|
@ -251,6 +274,7 @@ radiusd_start(struct radiusd *radiusd)
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
on_error:
|
on_error:
|
||||||
|
radiusd->error++;
|
||||||
radiusd_stop(radiusd);
|
radiusd_stop(radiusd);
|
||||||
|
|
||||||
return (-1);
|
return (-1);
|
||||||
|
@ -387,8 +411,10 @@ radiusd_listen_handle_packet(struct radiusd_listen *listn,
|
||||||
static char username[256];
|
static char username[256];
|
||||||
char peerstr[NI_MAXHOST + NI_MAXSERV + 30];
|
char peerstr[NI_MAXHOST + NI_MAXSERV + 30];
|
||||||
struct radiusd_authentication *authen;
|
struct radiusd_authentication *authen;
|
||||||
|
struct radiusd_accounting *accounting;
|
||||||
struct radiusd_client *client;
|
struct radiusd_client *client;
|
||||||
struct radius_query *q = NULL;
|
struct radius_query *q = NULL;
|
||||||
|
uint32_t acct_status;
|
||||||
#define in(_x) (((struct sockaddr_in *)_x)->sin_addr)
|
#define in(_x) (((struct sockaddr_in *)_x)->sin_addr)
|
||||||
#define in6(_x) (((struct sockaddr_in6 *)_x)->sin6_addr)
|
#define in6(_x) (((struct sockaddr_in6 *)_x)->sin6_addr)
|
||||||
|
|
||||||
|
@ -421,9 +447,19 @@ radiusd_listen_handle_packet(struct radiusd_listen *listn,
|
||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check the request authenticator if accounting */
|
||||||
|
if ((req_code == RADIUS_CODE_ACCOUNTING_REQUEST ||
|
||||||
|
listn->accounting) && radius_check_accounting_request_authenticator(
|
||||||
|
packet, client->secret) != 0) {
|
||||||
|
log_warnx("Received %s(code=%d) from %s id=%d: bad request "
|
||||||
|
"authenticator", radius_code_string(req_code), req_code,
|
||||||
|
peerstr, req_id);
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check the client's Message-Authenticator */
|
/* Check the client's Message-Authenticator */
|
||||||
if (client->msgauth_required && !radius_has_attr(packet,
|
if (client->msgauth_required && !listn->accounting &&
|
||||||
RADIUS_TYPE_MESSAGE_AUTHENTICATOR)) {
|
!radius_has_attr(packet, RADIUS_TYPE_MESSAGE_AUTHENTICATOR)) {
|
||||||
log_warnx("Received %s(code=%d) from %s id=%d: no message "
|
log_warnx("Received %s(code=%d) from %s id=%d: no message "
|
||||||
"authenticator", radius_code_string(req_code), req_code,
|
"authenticator", radius_code_string(req_code), req_code,
|
||||||
peerstr, req_id);
|
peerstr, req_id);
|
||||||
|
@ -485,6 +521,13 @@ radiusd_listen_handle_packet(struct radiusd_listen *listn,
|
||||||
|
|
||||||
switch (req_code) {
|
switch (req_code) {
|
||||||
case RADIUS_CODE_ACCESS_REQUEST:
|
case RADIUS_CODE_ACCESS_REQUEST:
|
||||||
|
if (listn->accounting) {
|
||||||
|
log_info("Received %s(code=%d) from %s id=%d: "
|
||||||
|
"ignored because the port is for authentication",
|
||||||
|
radius_code_string(req_code), req_code, peerstr,
|
||||||
|
req_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Find a matching `authenticate' entry
|
* Find a matching `authenticate' entry
|
||||||
*/
|
*/
|
||||||
|
@ -521,6 +564,47 @@ radiusd_listen_handle_packet(struct radiusd_listen *listn,
|
||||||
|
|
||||||
raidus_query_access_request(q);
|
raidus_query_access_request(q);
|
||||||
return;
|
return;
|
||||||
|
case RADIUS_CODE_ACCOUNTING_REQUEST:
|
||||||
|
if (!listn->accounting) {
|
||||||
|
log_info("Received %s(code=%d) from %s id=%d: "
|
||||||
|
"ignored because the port is for accounting",
|
||||||
|
radius_code_string(req_code), req_code, peerstr,
|
||||||
|
req_id);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (radius_get_uint32_attr(q->req, RADIUS_TYPE_ACCT_STATUS_TYPE,
|
||||||
|
&acct_status) != 0)
|
||||||
|
acct_status = 0;
|
||||||
|
/*
|
||||||
|
* Find a matching `accounting' entry
|
||||||
|
*/
|
||||||
|
TAILQ_FOREACH(accounting, &listn->radiusd->account, next) {
|
||||||
|
if (acct_status == RADIUS_ACCT_STATUS_TYPE_ACCT_ON ||
|
||||||
|
acct_status == RADIUS_ACCT_STATUS_TYPE_ACCT_OFF) {
|
||||||
|
raidus_query_accounting_request(accounting, q);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (i = 0; accounting->username[i] != NULL; i++) {
|
||||||
|
if (fnmatch(accounting->username[i], username,
|
||||||
|
0) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (accounting->username[i] == NULL)
|
||||||
|
continue;
|
||||||
|
raidus_query_accounting_request(accounting, q);
|
||||||
|
if (accounting->quick)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* pass NULL to hadnle this self without module */
|
||||||
|
raidus_query_accounting_request(NULL, q);
|
||||||
|
|
||||||
|
if ((q->res = radius_new_response_packet(
|
||||||
|
RADIUS_CODE_ACCOUNTING_RESPONSE, q->req)) == NULL)
|
||||||
|
log_warn("%s: radius_new_response_packet() failed",
|
||||||
|
__func__);
|
||||||
|
else
|
||||||
|
radius_query_accounting_response(q);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
log_info("Received %s(code=%d) from %s id=%d: %s is not "
|
log_info("Received %s(code=%d) from %s id=%d: %s is not "
|
||||||
"supported in this implementation", radius_code_string(
|
"supported in this implementation", radius_code_string(
|
||||||
|
@ -609,6 +693,53 @@ on_error:
|
||||||
radiusd_access_request_aborted(q);
|
radiusd_access_request_aborted(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
raidus_query_accounting_request(struct radiusd_accounting *accounting,
|
||||||
|
struct radius_query *q)
|
||||||
|
{
|
||||||
|
int req_code;
|
||||||
|
uint32_t acct_status;
|
||||||
|
char buf0[NI_MAXHOST + NI_MAXSERV + 30];
|
||||||
|
|
||||||
|
if (accounting != NULL) {
|
||||||
|
/* handle by the module */
|
||||||
|
if (MODULE_DO_ACCTREQ(accounting->acct->module))
|
||||||
|
radiusd_module_account_request(accounting->acct->module,
|
||||||
|
q);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
req_code = radius_get_code(q->req);
|
||||||
|
if (radius_get_uint32_attr(q->req, RADIUS_TYPE_ACCT_STATUS_TYPE,
|
||||||
|
&acct_status) != 0)
|
||||||
|
acct_status = 0;
|
||||||
|
log_info("Received %s(code=%d) type=%s(%lu) from %s id=%d username=%s "
|
||||||
|
"q=%u", radius_code_string(req_code), req_code,
|
||||||
|
radius_acct_status_type_string(acct_status), (unsigned long)
|
||||||
|
acct_status, addrport_tostring((struct sockaddr *)&q->clientaddr,
|
||||||
|
q->clientaddrlen, buf0, sizeof(buf0)), q->req_id, q->username,
|
||||||
|
q->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
radius_query_accounting_response(struct radius_query *q)
|
||||||
|
{
|
||||||
|
int sz, res_id, res_code;
|
||||||
|
char buf[NI_MAXHOST + NI_MAXSERV + 30];
|
||||||
|
|
||||||
|
radius_set_response_authenticator(q->res, q->client->secret);
|
||||||
|
res_id = radius_get_id(q->res);
|
||||||
|
res_code = radius_get_code(q->res);
|
||||||
|
|
||||||
|
log_info("Sending %s(code=%d) to %s id=%u q=%u",
|
||||||
|
radius_code_string(res_code), res_code,
|
||||||
|
addrport_tostring((struct sockaddr *)&q->clientaddr,
|
||||||
|
q->clientaddrlen, buf, sizeof(buf)), res_id, q->id);
|
||||||
|
|
||||||
|
if ((sz = sendto(q->listen->sock, radius_get_data(q->res),
|
||||||
|
radius_get_length(q->res), 0,
|
||||||
|
(struct sockaddr *)&q->clientaddr, q->clientaddrlen)) <= 0)
|
||||||
|
log_warn("Sending a RADIUS response failed");
|
||||||
|
}
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* Callback functions from the modules
|
* Callback functions from the modules
|
||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
@ -691,7 +822,7 @@ radiusd_on_sigchld(int fd, short evmask, void *ctx)
|
||||||
struct radiusd *radiusd = ctx;
|
struct radiusd *radiusd = ctx;
|
||||||
struct radiusd_module *module;
|
struct radiusd_module *module;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int status;
|
int status, ndeath = 0;
|
||||||
|
|
||||||
log_debug("Received SIGCHLD");
|
log_debug("Received SIGCHLD");
|
||||||
while ((pid = wait3(&status, WNOHANG, NULL)) != 0) {
|
while ((pid = wait3(&status, WNOHANG, NULL)) != 0) {
|
||||||
|
@ -707,6 +838,7 @@ radiusd_on_sigchld(int fd, short evmask, void *ctx)
|
||||||
log_warnx("module `%s'(pid=%d) exited "
|
log_warnx("module `%s'(pid=%d) exited "
|
||||||
"by signal %d", module->name,
|
"by signal %d", module->name,
|
||||||
(int)pid, WTERMSIG(status));
|
(int)pid, WTERMSIG(status));
|
||||||
|
ndeath++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -721,6 +853,10 @@ radiusd_on_sigchld(int fd, short evmask, void *ctx)
|
||||||
WTERMSIG(status));
|
WTERMSIG(status));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ndeath > 0) {
|
||||||
|
radiusd->error++;
|
||||||
|
event_loopbreak();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
@ -749,6 +885,29 @@ radius_code_string(int code)
|
||||||
return ("Unknown");
|
return ("Unknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
radius_acct_status_type_string(uint32_t type)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
struct _typestrings {
|
||||||
|
uint32_t type;
|
||||||
|
const char *string;
|
||||||
|
} typestrings[] = {
|
||||||
|
{ RADIUS_ACCT_STATUS_TYPE_START, "Start" },
|
||||||
|
{ RADIUS_ACCT_STATUS_TYPE_STOP, "Stop" },
|
||||||
|
{ RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE, "Interim-Update" },
|
||||||
|
{ RADIUS_ACCT_STATUS_TYPE_ACCT_ON, "Accounting-On" },
|
||||||
|
{ RADIUS_ACCT_STATUS_TYPE_ACCT_OFF, "Accounting-Off" },
|
||||||
|
{ -1, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; typestrings[i].string != NULL; i++)
|
||||||
|
if (typestrings[i].type == type)
|
||||||
|
return (typestrings[i].string);
|
||||||
|
|
||||||
|
return ("Unknown");
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
radiusd_conf_init(struct radiusd *conf)
|
radiusd_conf_init(struct radiusd *conf)
|
||||||
{
|
{
|
||||||
|
@ -756,6 +915,7 @@ radiusd_conf_init(struct radiusd *conf)
|
||||||
TAILQ_INIT(&conf->listen);
|
TAILQ_INIT(&conf->listen);
|
||||||
TAILQ_INIT(&conf->module);
|
TAILQ_INIT(&conf->module);
|
||||||
TAILQ_INIT(&conf->authen);
|
TAILQ_INIT(&conf->authen);
|
||||||
|
TAILQ_INIT(&conf->account);
|
||||||
TAILQ_INIT(&conf->client);
|
TAILQ_INIT(&conf->client);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -1085,9 +1245,8 @@ radiusd_module_on_imsg_io(int fd, short evmask, void *ctx)
|
||||||
if (evmask & EV_WRITE)
|
if (evmask & EV_WRITE)
|
||||||
module->writeready = true;
|
module->writeready = true;
|
||||||
|
|
||||||
if (evmask & EV_READ || module->ibuf.r.wpos > IMSG_HEADER_SIZE) {
|
if (evmask & EV_READ) {
|
||||||
if (radiusd_module_imsg_read(module,
|
if (radiusd_module_imsg_read(module) == -1)
|
||||||
(evmask & EV_READ)? true : false) == -1)
|
|
||||||
goto on_error;
|
goto on_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1124,8 +1283,7 @@ radiusd_module_reset_ev_handler(struct radiusd_module *module)
|
||||||
evmask |= EV_WRITE;
|
evmask |= EV_WRITE;
|
||||||
else
|
else
|
||||||
tvp = &tv; /* fire immediately */
|
tvp = &tv; /* fire immediately */
|
||||||
} else if (module->ibuf.r.wpos > IMSG_HEADER_SIZE)
|
}
|
||||||
tvp = &tv; /* fire immediately */
|
|
||||||
|
|
||||||
/* module stopped and no event handler is set */
|
/* module stopped and no event handler is set */
|
||||||
if (evmask & EV_WRITE && tvp == NULL && module->stopped) {
|
if (evmask & EV_WRITE && tvp == NULL && module->stopped) {
|
||||||
|
@ -1144,22 +1302,20 @@ radiusd_module_reset_ev_handler(struct radiusd_module *module)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
radiusd_module_imsg_read(struct radiusd_module *module, bool doread)
|
radiusd_module_imsg_read(struct radiusd_module *module)
|
||||||
{
|
{
|
||||||
int n;
|
int n;
|
||||||
struct imsg imsg;
|
struct imsg imsg;
|
||||||
|
|
||||||
if (doread) {
|
if ((n = imsg_read(&module->ibuf)) == -1 || n == 0) {
|
||||||
if ((n = imsg_read(&module->ibuf)) == -1 || n == 0) {
|
if (n == -1 && errno == EAGAIN)
|
||||||
if (n == -1 && errno == EAGAIN)
|
return (0);
|
||||||
return (0);
|
if (n == -1)
|
||||||
if (n == -1)
|
log_warn("Receiving a message from module `%s' "
|
||||||
log_warn("Receiving a message from module `%s' "
|
"failed: imsg_read", module->name);
|
||||||
"failed: imsg_read", module->name);
|
/* else closed */
|
||||||
/* else closed */
|
radiusd_module_close(module);
|
||||||
radiusd_module_close(module);
|
return (-1);
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((n = imsg_get(&module->ibuf, &imsg)) == -1) {
|
if ((n = imsg_get(&module->ibuf, &imsg)) == -1) {
|
||||||
|
@ -1275,6 +1431,14 @@ radiusd_module_imsg(struct radiusd_module *module, struct imsg *imsg)
|
||||||
module->radpktoff = 0;
|
module->radpktoff = 0;
|
||||||
switch (imsg->hdr.type) {
|
switch (imsg->hdr.type) {
|
||||||
case IMSG_RADIUSD_MODULE_REQDECO_DONE:
|
case IMSG_RADIUSD_MODULE_REQDECO_DONE:
|
||||||
|
if (q->deco == NULL || q->deco->type !=
|
||||||
|
IMSG_RADIUSD_MODULE_REQDECO) {
|
||||||
|
log_warnx("q=%u received %s "
|
||||||
|
"but not requested", q->id, typestr);
|
||||||
|
if (radpkt != NULL)
|
||||||
|
radius_delete_packet(radpkt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (radpkt != NULL) {
|
if (radpkt != NULL) {
|
||||||
radius_delete_packet(q->req);
|
radius_delete_packet(q->req);
|
||||||
q->req = radpkt;
|
q->req = radpkt;
|
||||||
|
@ -1283,7 +1447,7 @@ radiusd_module_imsg(struct radiusd_module *module, struct imsg *imsg)
|
||||||
break;
|
break;
|
||||||
case IMSG_RADIUSD_MODULE_ACCSREQ_ANSWER:
|
case IMSG_RADIUSD_MODULE_ACCSREQ_ANSWER:
|
||||||
if (radpkt == NULL) {
|
if (radpkt == NULL) {
|
||||||
log_warn("q=%u wrong pkt from module",
|
log_warnx("q=%u wrong pkt from module",
|
||||||
q->id);
|
q->id);
|
||||||
radiusd_access_request_aborted(q);
|
radiusd_access_request_aborted(q);
|
||||||
break;
|
break;
|
||||||
|
@ -1292,6 +1456,14 @@ radiusd_module_imsg(struct radiusd_module *module, struct imsg *imsg)
|
||||||
radiusd_access_request_answer(q);
|
radiusd_access_request_answer(q);
|
||||||
break;
|
break;
|
||||||
case IMSG_RADIUSD_MODULE_RESDECO_DONE:
|
case IMSG_RADIUSD_MODULE_RESDECO_DONE:
|
||||||
|
if (q->deco == NULL || q->deco->type !=
|
||||||
|
IMSG_RADIUSD_MODULE_RESDECO) {
|
||||||
|
log_warnx("q=%u received %s but not "
|
||||||
|
"requested", q->id, typestr);
|
||||||
|
if (radpkt != NULL)
|
||||||
|
radius_delete_packet(radpkt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (radpkt != NULL) {
|
if (radpkt != NULL) {
|
||||||
radius_delete_packet(q->res);
|
radius_delete_packet(q->res);
|
||||||
radius_set_request_packet(radpkt,
|
radius_set_request_packet(radpkt,
|
||||||
|
@ -1306,6 +1478,11 @@ radiusd_module_imsg(struct radiusd_module *module, struct imsg *imsg)
|
||||||
}
|
}
|
||||||
case IMSG_RADIUSD_MODULE_ACCSREQ_ABORTED:
|
case IMSG_RADIUSD_MODULE_ACCSREQ_ABORTED:
|
||||||
{
|
{
|
||||||
|
if (datalen < (ssize_t)sizeof(u_int)) {
|
||||||
|
log_warnx("Received ACCSREQ_ABORTED message, but "
|
||||||
|
"length is wrong");
|
||||||
|
break;
|
||||||
|
}
|
||||||
q_id = *((u_int *)imsg->data);
|
q_id = *((u_int *)imsg->data);
|
||||||
q = radiusd_find_query(module->radiusd, q_id);
|
q = radiusd_find_query(module->radiusd, q_id);
|
||||||
if (q == NULL) {
|
if (q == NULL) {
|
||||||
|
@ -1531,6 +1708,8 @@ radiusd_module_request_decoration(struct radiusd_module *module,
|
||||||
radiusd_access_request_aborted(q);
|
radiusd_access_request_aborted(q);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
RADIUSD_ASSERT(q->deco != NULL);
|
||||||
|
q->deco->type = IMSG_RADIUSD_MODULE_REQDECO;
|
||||||
radiusd_module_reset_ev_handler(module);
|
radiusd_module_reset_ev_handler(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1558,9 +1737,34 @@ radiusd_module_response_decoration(struct radiusd_module *module,
|
||||||
radiusd_access_request_aborted(q);
|
radiusd_access_request_aborted(q);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
RADIUSD_ASSERT(q->deco != NULL);
|
||||||
|
q->deco->type = IMSG_RADIUSD_MODULE_RESDECO;
|
||||||
radiusd_module_reset_ev_handler(module);
|
radiusd_module_reset_ev_handler(module);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
radiusd_module_account_request(struct radiusd_module *module,
|
||||||
|
struct radius_query *q)
|
||||||
|
{
|
||||||
|
RADIUS_PACKET *radpkt;
|
||||||
|
|
||||||
|
if ((radpkt = radius_convert_packet(radius_get_data(q->req),
|
||||||
|
radius_get_length(q->req))) == NULL) {
|
||||||
|
log_warn("q=%u Could not send ACCSREQ to `%s'", q->id,
|
||||||
|
module->name);
|
||||||
|
radiusd_access_request_aborted(q);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (imsg_compose_radius_packet(&module->ibuf,
|
||||||
|
IMSG_RADIUSD_MODULE_ACCTREQ, q->id, radpkt) == -1) {
|
||||||
|
log_warn("q=%u Could not send ACCTREQ to `%s'", q->id,
|
||||||
|
module->name);
|
||||||
|
radiusd_access_request_aborted(q);
|
||||||
|
}
|
||||||
|
radiusd_module_reset_ev_handler(module);
|
||||||
|
radius_delete_packet(radpkt);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
imsg_compose_radius_packet(struct imsgbuf *ibuf, uint32_t type, u_int q_id,
|
imsg_compose_radius_packet(struct imsgbuf *ibuf, uint32_t type, u_int q_id,
|
||||||
RADIUS_PACKET *radpkt)
|
RADIUS_PACKET *radpkt)
|
||||||
|
@ -1593,3 +1797,17 @@ imsg_compose_radius_packet(struct imsgbuf *ibuf, uint32_t type, u_int q_id,
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
close_stdio(void)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if ((fd = open(_PATH_DEVNULL, O_RDWR)) != -1) {
|
||||||
|
dup2(fd, STDIN_FILENO);
|
||||||
|
dup2(fd, STDOUT_FILENO);
|
||||||
|
dup2(fd, STDERR_FILENO);
|
||||||
|
if (fd > STDERR_FILENO)
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.\" $OpenBSD: radiusd.conf.5,v 1.18 2023/09/14 09:55:28 yasuoka Exp $
|
.\" $OpenBSD: radiusd.conf.5,v 1.22 2024/07/02 00:35:56 yasuoka Exp $
|
||||||
.\"
|
.\"
|
||||||
.\" Copyright (c) 2014 Esdenera Networks GmbH
|
.\" Copyright (c) 2014 Esdenera Networks GmbH
|
||||||
.\" Copyright (c) 2014, 2023 Internet Initiative Japan Inc.
|
.\" Copyright (c) 2014, 2023 Internet Initiative Japan Inc.
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: September 14 2023 $
|
.Dd $Mdocdate: July 2 2024 $
|
||||||
.Dt RADIUSD.CONF 5
|
.Dt RADIUSD.CONF 5
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
|
@ -35,14 +35,18 @@ Keywords may be specified multiple times within the configuration file.
|
||||||
The configuration options are as follows:
|
The configuration options are as follows:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Xo
|
.It Xo
|
||||||
.Ic listen on Ar address
|
.Ic listen on Ar address Oo Ic accounting Oc Ic port Ar port
|
||||||
.Ic port Ar port
|
|
||||||
.Xc
|
.Xc
|
||||||
Specify an
|
Specify an
|
||||||
.Ar address
|
.Ar address
|
||||||
and a
|
and a
|
||||||
.Ar port
|
.Ar port
|
||||||
to listen on.
|
to listen on.
|
||||||
|
When
|
||||||
|
.Ar accouting
|
||||||
|
is specified,
|
||||||
|
it is used for waiting for RADIUS accounting messages.
|
||||||
|
The default port number is 1812 for authentication and 1813 for accounting.
|
||||||
.It Ic client Ar address/mask Brq ...
|
.It Ic client Ar address/mask Brq ...
|
||||||
Allow access to a client with the specified
|
Allow access to a client with the specified
|
||||||
.Ar address
|
.Ar address
|
||||||
|
@ -57,40 +61,46 @@ This option cannot be omitted.
|
||||||
Specify if message authentication is required.
|
Specify if message authentication is required.
|
||||||
The default is to require message authentication.
|
The default is to require message authentication.
|
||||||
.El
|
.El
|
||||||
.It Ic module load Ar name path
|
.It Ic module Ar name Oo Ar path Oc Op Brq ...
|
||||||
Load a module
|
Load a module.
|
||||||
from
|
Specify one of the predefined names for
|
||||||
.Ar path
|
.Ar name ,
|
||||||
and name it with the given
|
or specify
|
||||||
.Ar name .
|
.Ar name
|
||||||
The following modules are available:
|
and
|
||||||
.Bl -column "/usr/libexec/radiusd/radiusd_bsdauthXXX"
|
.Ar path .
|
||||||
.It Sy "Path" Ta Sy "Description"
|
When multiple modules of the same path are loaded with different names,
|
||||||
.It Pa /usr/libexec/radiusd/radiusd_bsdauth Ta Do bsdauth Dc module
|
each module can have configurations respectively and work independently.
|
||||||
.It Pa /usr/libexec/radiusd/radiusd_radius Ta Do radius Dc module
|
.Pp
|
||||||
.It Pa /usr/libexec/radiusd/radiusd_standard Ta Do standard Dc module
|
The following module are predefined:
|
||||||
.El
|
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Do bsdauth Dc module
|
.It Do bsdauth Dc module
|
||||||
The
|
The
|
||||||
.Dq bsdauth
|
.Dq bsdauth
|
||||||
module provides authentication from the local system's
|
module
|
||||||
|
provides authentication from the local system's
|
||||||
.Xr authenticate 3
|
.Xr authenticate 3
|
||||||
interface,
|
interface.
|
||||||
known as
|
See
|
||||||
.Dq bsd auth .
|
.Xr radiusd_bsdauth 8 .
|
||||||
It only supports PAP, password based authentication.
|
|
||||||
.It Do radius Dc module
|
.It Do radius Dc module
|
||||||
The
|
The
|
||||||
.Dq radius
|
.Dq radius
|
||||||
module provides authentication from upstream RADIUS servers.
|
module provides authentication from upstream RADIUS servers.
|
||||||
|
See
|
||||||
|
.Xr radiusd_radius 8 .
|
||||||
.It Do standard Dc module
|
.It Do standard Dc module
|
||||||
The
|
The
|
||||||
.Dq standard
|
.Dq standard
|
||||||
module provides standard decorations for Access-Request messages or its
|
module provides standard decorations for RADIUS messages.
|
||||||
response messages.
|
See
|
||||||
|
.Xr radiusd_standard 8 .
|
||||||
.El
|
.El
|
||||||
.It Ic module set Ar module key value ...
|
.Pp
|
||||||
|
It is optionally followed by a block of options enclosed in curly brackets.
|
||||||
|
The following option can be used in the block:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic set Ar key value ...
|
||||||
Configure the module specific configurations by
|
Configure the module specific configurations by
|
||||||
.Ar key
|
.Ar key
|
||||||
and
|
and
|
||||||
|
@ -98,92 +108,18 @@ and
|
||||||
for the module specified by
|
for the module specified by
|
||||||
.Ar module .
|
.Ar module .
|
||||||
Notice that
|
Notice that
|
||||||
.Ar module ,
|
|
||||||
.Ar key ,
|
.Ar key ,
|
||||||
and
|
and
|
||||||
.Ar value
|
.Ar value
|
||||||
must be quoted to be distinguished from the reserved word (e.g.\&
|
must be quoted to be distinguished from the reserved word if needed.
|
||||||
.Dq secret )
|
|
||||||
if needed.
|
|
||||||
.Pp
|
|
||||||
The
|
|
||||||
.Dq bsdauth
|
|
||||||
module supports the following configuration key and value:
|
|
||||||
.Bl -tag -width Ds -offset indent
|
|
||||||
.It Ic restrict-group Ar group ...
|
|
||||||
Restrict login only if the user is a member of the specified groups.
|
|
||||||
.El
|
.El
|
||||||
.Pp
|
.It Ic authenticate Ar username-pattern ... Ic by Ar auth Oo Ic decorated-by \
|
||||||
The
|
Ar deco ... Oc
|
||||||
.Dq radius
|
|
||||||
module supports the following configuration key and value:
|
|
||||||
.Bl -tag -width Ds -offset indent
|
|
||||||
.It Ic server Ar address Ns Op : Ns Ar port
|
|
||||||
Specify the upstream server's address and port.
|
|
||||||
If
|
|
||||||
.Ar port
|
|
||||||
is omitted, 1812 is used.
|
|
||||||
This configuration can be specified multiple times.
|
|
||||||
.It Ic secret Ar secret
|
|
||||||
Specify the shared secret with the servers.
|
|
||||||
This configuration cannot be omitted.
|
|
||||||
.It Ic max-tries Ar number
|
|
||||||
Specify the maximum number of retransmissions for a server.
|
|
||||||
.Xr radiusd 8
|
|
||||||
will retransmit 2, 6, 14, 22, and 30 seconds after the first transmission
|
|
||||||
and subsequent retransmissions will occur every 8 seconds.
|
|
||||||
If the number of retransmissions per server reaches this value,
|
|
||||||
the current server is marked as
|
|
||||||
.Dq fail ,
|
|
||||||
and the next server is used for subsequent requests.
|
|
||||||
The default value is 3.
|
|
||||||
.It Ic max-failovers Ar number
|
|
||||||
If a positive number is specified,
|
|
||||||
.Xr radiusd 8
|
|
||||||
will failover to the next server
|
|
||||||
when the current server is marked
|
|
||||||
.Dq fail .
|
|
||||||
This key and value specifies the maximum number of failovers.
|
|
||||||
The default value is 0.
|
|
||||||
.It Ic request-timeout Ar sec
|
|
||||||
Specify the request timeout in seconds.
|
|
||||||
If this value is specified,
|
|
||||||
.Ar max-tries
|
|
||||||
and
|
|
||||||
.Ar max-failover
|
|
||||||
will not be used.
|
|
||||||
.El
|
|
||||||
.Pp
|
|
||||||
The
|
|
||||||
.Dq standard
|
|
||||||
module supports the following configuration key and value:
|
|
||||||
.Pp
|
|
||||||
.Bl -tag -width Ds -offset indent -compact
|
|
||||||
.It Ic strip-atmark-realm Ar true | false
|
|
||||||
Remove the realm part which starts with @
|
|
||||||
.Pq atmark
|
|
||||||
from the User-Name attribute of the Access-Request.
|
|
||||||
.Pp
|
|
||||||
.It Ic strip-nt-domain Ar true | false
|
|
||||||
Remove NT domain which ends with \\
|
|
||||||
.Pq backslash
|
|
||||||
from the User-Name attribute of the Access-Request.
|
|
||||||
.Pp
|
|
||||||
.It Cm remove-request-attribute Oo Ar vendor Oc Ar type
|
|
||||||
.It Cm remove-response-attribute Oo Ar vendor Oc Ar type
|
|
||||||
Remove all the specified attributes from request or response
|
|
||||||
messages of Access-Request.
|
|
||||||
Specify
|
|
||||||
.Ar type
|
|
||||||
of the attribute in a decimal number.
|
|
||||||
To specify a vendor attribute,
|
|
||||||
specify the Vendor-Id
|
|
||||||
in a decimal number for
|
|
||||||
.Ar vendor .
|
|
||||||
.El
|
|
||||||
.It Ic authenticate Ar username-pattern ... Brq ...
|
|
||||||
Specify an authentication configuration for the users specified by
|
Specify an authentication configuration for the users specified by
|
||||||
.Ar username-pattern .
|
.Ar username-pattern.
|
||||||
|
The users matched by the pattern is authenticated by the module
|
||||||
|
specified by
|
||||||
|
.Ar auth .
|
||||||
Use shell globbing rules for the pattern;
|
Use shell globbing rules for the pattern;
|
||||||
multiple patterns can be specified by separating with space characters.
|
multiple patterns can be specified by separating with space characters.
|
||||||
When multiple
|
When multiple
|
||||||
|
@ -193,60 +129,78 @@ lines are specified, the first
|
||||||
setting whose
|
setting whose
|
||||||
.Ar username-pattern
|
.Ar username-pattern
|
||||||
matches an authenticating user is used.
|
matches an authenticating user is used.
|
||||||
It is followed by a block of options enclosed in curly brackets:
|
.Pp
|
||||||
.Bl -tag -width Ds
|
Optionally decoration modules can be specified by
|
||||||
.It Ic authenticate-by Ar module
|
.Ar deco .
|
||||||
Specify the module name.
|
The specified modules decorate the RADIUS messages in the configured order.
|
||||||
.It Ic decorate-by Ar module
|
.It Ic account Oo Ic quick Oc Ar username-pattern ... Ic to Ar module \
|
||||||
Specify the module name.
|
Oo Ic decoratd by Ar deco ... Oc
|
||||||
.El
|
Specify an accounting configuration for the users specified by
|
||||||
|
.Ar username-pattern .
|
||||||
|
The accounting messages for the users matched by the pattern are handled
|
||||||
|
by the module specified by the
|
||||||
|
.Ar module .
|
||||||
|
Use shell globbing rules for the patterns;
|
||||||
|
multiple patterns can be determined by separating them with space characters.
|
||||||
|
When multiple
|
||||||
|
.Ic account
|
||||||
|
lines are selected,
|
||||||
|
all account settings whose
|
||||||
|
.Ar username-pattern
|
||||||
|
matches an accounting users are used.
|
||||||
|
until the user matches the setting with the
|
||||||
|
.Ar quick
|
||||||
|
option.
|
||||||
|
.Pp
|
||||||
|
Optionally decoration modules can be specified by
|
||||||
|
.Ar deco .
|
||||||
|
The specified modules decorate the RADIUS messages in the configured order.
|
||||||
.El
|
.El
|
||||||
.Sh FILES
|
.Sh FILES
|
||||||
.Bl -tag -width "/usr/libexec/radiusd/radiusd_bsdauth" -compact
|
.Bl -tag -width "/etc/examples/radiusd.conf" -compact
|
||||||
.It Pa /etc/radiusd.conf
|
.It Pa /etc/radiusd.conf
|
||||||
Default
|
Default
|
||||||
.Xr radiusd 8
|
.Xr radiusd 8
|
||||||
configuration file.
|
configuration file.
|
||||||
.It Pa /etc/examples/radiusd.conf
|
.It Pa /etc/examples/radiusd.conf
|
||||||
Example configuration file.
|
Example configuration file.
|
||||||
.It Pa /usr/libexec/radiusd/radiusd_bsdauth
|
|
||||||
.Dq bsdauth
|
|
||||||
module executable.
|
|
||||||
.It Pa /usr/libexec/radiusd/radiusd_radius
|
|
||||||
.Dq radius
|
|
||||||
module executable.
|
|
||||||
.El
|
.El
|
||||||
.Sh EXAMPLES
|
.Sh EXAMPLES
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
listen on 0.0.0.0
|
listen on 0.0.0.0
|
||||||
|
listen on 0.0.0.0 accounting
|
||||||
listen on ::
|
listen on ::
|
||||||
|
listen on :: accounting
|
||||||
|
|
||||||
client 127.0.0.1/32 {
|
client 127.0.0.1/32 {
|
||||||
secret "secret"
|
secret "secret"
|
||||||
msgauth-required no
|
msgauth-required no
|
||||||
}
|
}
|
||||||
client 192.168.0.0/24 {
|
client 192.168.0.0/24 {
|
||||||
secret "secret"
|
secret "secret"
|
||||||
}
|
}
|
||||||
|
|
||||||
module load bsdauth "/usr/libexec/radiusd/radiusd_bsdauth"
|
module bsdauth {
|
||||||
module set bsdauth restrict-group operator
|
set restrict-group operator
|
||||||
|
|
||||||
module load radius "/usr/libexec/radiusd/radiusd_radius"
|
|
||||||
module set radius secret "testing123"
|
|
||||||
module set radius server "127.0.0.1"
|
|
||||||
|
|
||||||
module load strip-realm "/usr/libexec/radiusd/radiusd_standard"
|
|
||||||
module set strip-realm strip-atmark-realm true
|
|
||||||
|
|
||||||
authenticate *@local {
|
|
||||||
authenticate-by bsdauth
|
|
||||||
decorate-by strip-realm
|
|
||||||
}
|
}
|
||||||
authenticate * {
|
|
||||||
authenticate-by radius
|
module radius {
|
||||||
|
set secret "testing123"
|
||||||
|
set server "127.0.0.1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module strip-realm "/usr/libexec/radiusd/radiusd_standard" {
|
||||||
|
set strip-atmark-realm true
|
||||||
|
}
|
||||||
|
|
||||||
|
authenticate *@local by bsdauth decorate-by strip-realm
|
||||||
|
|
||||||
|
authenticate * by radius
|
||||||
|
|
||||||
|
account * to standard
|
||||||
.Ed
|
.Ed
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr authenticate 3 ,
|
.Xr radiusd 8 ,
|
||||||
.Xr radiusd 8
|
.Xr radiusd_bsdauth 8 ,
|
||||||
|
.Xr radiusd_radius 8 ,
|
||||||
|
.Xr radiusd_standard 8
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: radiusd.h,v 1.6 2024/01/08 04:16:48 yasuoka Exp $ */
|
/* $OpenBSD: radiusd.h,v 1.7 2024/07/02 00:33:51 yasuoka Exp $ */
|
||||||
|
|
||||||
#ifndef RADIUSD_H
|
#ifndef RADIUSD_H
|
||||||
#define RADIUSD_H 1
|
#define RADIUSD_H 1
|
||||||
|
@ -45,16 +45,18 @@ enum imsg_type {
|
||||||
IMSG_RADIUSD_MODULE_RESDECO0_REQ, /* request pkt for RESDECO */
|
IMSG_RADIUSD_MODULE_RESDECO0_REQ, /* request pkt for RESDECO */
|
||||||
IMSG_RADIUSD_MODULE_RESDECO,
|
IMSG_RADIUSD_MODULE_RESDECO,
|
||||||
IMSG_RADIUSD_MODULE_RESDECO_DONE,
|
IMSG_RADIUSD_MODULE_RESDECO_DONE,
|
||||||
IMSG_RADIUSD_MODULE_STOP
|
IMSG_RADIUSD_MODULE_ACCTREQ,
|
||||||
|
IMSG_RADIUSD_MODULE_STOP,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Module sends LOAD when it becomes ready */
|
/* Module sends LOAD when it becomes ready */
|
||||||
struct radiusd_module_load_arg {
|
struct radiusd_module_load_arg {
|
||||||
uint32_t cap; /* module capabity bits */
|
uint32_t cap; /* module capabity bits */
|
||||||
#define RADIUSD_MODULE_CAP_USERPASS 0x1
|
#define RADIUSD_MODULE_CAP_USERPASS 0x01
|
||||||
#define RADIUSD_MODULE_CAP_ACCSREQ 0x2
|
#define RADIUSD_MODULE_CAP_ACCSREQ 0x02
|
||||||
#define RADIUSD_MODULE_CAP_REQDECO 0x4
|
#define RADIUSD_MODULE_CAP_REQDECO 0x04
|
||||||
#define RADIUSD_MODULE_CAP_RESDECO 0x8
|
#define RADIUSD_MODULE_CAP_RESDECO 0x08
|
||||||
|
#define RADIUSD_MODULE_CAP_ACCTREQ 0x10
|
||||||
};
|
};
|
||||||
|
|
||||||
struct radiusd_module_object {
|
struct radiusd_module_object {
|
||||||
|
|
61
usr.sbin/radiusd/radiusd_bsdauth.8
Normal file
61
usr.sbin/radiusd/radiusd_bsdauth.8
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
.\" $OpenBSD: radiusd_bsdauth.8,v 1.1 2024/07/02 00:00:12 yasuoka Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 2014 Esdenera Networks GmbH
|
||||||
|
.\" Copyright (c) 2014, 2024 Internet Initiative Japan Inc.
|
||||||
|
.\"
|
||||||
|
.\" Permission to use, copy, modify, and distribute this software for any
|
||||||
|
.\" purpose with or without fee is hereby granted, provided that the above
|
||||||
|
.\" copyright notice and this permission notice appear in all copies.
|
||||||
|
.\"
|
||||||
|
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
.\"
|
||||||
|
.\" The following requests are required for all man pages.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: July 2 2024 $
|
||||||
|
.Dt RADIUSD_BSDAUTH 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm radiusd_bsdauth
|
||||||
|
.Nd provide authentication by BSD authentication system
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm radiusd_bsdauth
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility is executed by
|
||||||
|
.Xr radiusd 8
|
||||||
|
as a module to provide authentication from the local system's
|
||||||
|
.Xr authenticate 3
|
||||||
|
interface,
|
||||||
|
known as
|
||||||
|
.Dq bsd auth .
|
||||||
|
It only supports PAP, password based authentication.
|
||||||
|
.Sh CONFIGURATIONS
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
supports the following configuration key and value:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic restrict-group Ar group ...
|
||||||
|
Restrict login only if the user is a member of the specified groups.
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width "/usr/libexec/radiusd/radiusd_bsdauth" -compact
|
||||||
|
.It Pa /usr/libexec/radiusd/radiusd_bsdauth
|
||||||
|
.Dq bsdauth
|
||||||
|
module executable.
|
||||||
|
.El
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr authenticate 3 ,
|
||||||
|
.Xr radiusd 8 ,
|
||||||
|
.Xr radiusd.conf 5
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
daemon first appeared in
|
||||||
|
.Ox 5.8 .
|
|
@ -1,9 +1,9 @@
|
||||||
# $OpenBSD: Makefile,v 1.2 2024/01/28 18:38:16 deraadt Exp $
|
# $OpenBSD: Makefile,v 1.3 2024/07/02 00:00:12 yasuoka Exp $
|
||||||
PROG= radiusd_bsdauth
|
PROG= radiusd_bsdauth
|
||||||
BINDIR= /usr/libexec/radiusd
|
BINDIR= /usr/libexec/radiusd
|
||||||
SRCS= radiusd_bsdauth.c radiusd_module.c imsg_subr.c
|
SRCS= radiusd_bsdauth.c radiusd_module.c imsg_subr.c
|
||||||
LDADD+= -lradius -lcrypto -lutil
|
LDADD+= -lradius -lcrypto -lutil
|
||||||
DPADD+= ${LIBRADIUS} ${LIBCRYPTO} ${LIBUTIL}
|
DPADD+= ${LIBRADIUS} ${LIBCRYPTO} ${LIBUTIL}
|
||||||
NOMAN= #
|
MAN= radiusd_bsdauth.8
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: radiusd_local.h,v 1.7 2024/05/21 05:00:48 jsg Exp $ */
|
/* $OpenBSD: radiusd_local.h,v 1.11 2024/07/02 00:33:51 yasuoka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013 Internet Initiative Japan Inc.
|
* Copyright (c) 2013 Internet Initiative Japan Inc.
|
||||||
|
@ -44,6 +44,7 @@ struct radiusd_listen {
|
||||||
struct radiusd *radiusd;
|
struct radiusd *radiusd;
|
||||||
struct event ev;
|
struct event ev;
|
||||||
int sock;
|
int sock;
|
||||||
|
int accounting;
|
||||||
union {
|
union {
|
||||||
struct sockaddr_in ipv4;
|
struct sockaddr_in ipv4;
|
||||||
struct sockaddr_in6 ipv6;
|
struct sockaddr_in6 ipv6;
|
||||||
|
@ -85,17 +86,26 @@ struct radiusd_module {
|
||||||
|
|
||||||
struct radiusd_module_ref {
|
struct radiusd_module_ref {
|
||||||
struct radiusd_module *module;
|
struct radiusd_module *module;
|
||||||
|
unsigned int type;
|
||||||
TAILQ_ENTRY(radiusd_module_ref) next;
|
TAILQ_ENTRY(radiusd_module_ref) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct radiusd_authentication {
|
struct radiusd_authentication {
|
||||||
char **username;
|
char **username;
|
||||||
char *secret;
|
|
||||||
struct radiusd_module_ref *auth;
|
struct radiusd_module_ref *auth;
|
||||||
TAILQ_HEAD(,radiusd_module_ref) deco;
|
TAILQ_HEAD(,radiusd_module_ref) deco;
|
||||||
TAILQ_ENTRY(radiusd_authentication) next;
|
TAILQ_ENTRY(radiusd_authentication) next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct radiusd_accounting {
|
||||||
|
char **username;
|
||||||
|
char *secret;
|
||||||
|
struct radiusd_module_ref *acct;
|
||||||
|
int quick;
|
||||||
|
TAILQ_HEAD(,radiusd_module_ref) deco;
|
||||||
|
TAILQ_ENTRY(radiusd_accounting) next;
|
||||||
|
};
|
||||||
|
|
||||||
struct radiusd {
|
struct radiusd {
|
||||||
struct radiusd_listen_head listen;
|
struct radiusd_listen_head listen;
|
||||||
struct event ev_sigterm;
|
struct event ev_sigterm;
|
||||||
|
@ -104,8 +114,10 @@ struct radiusd {
|
||||||
struct event ev_sigchld;
|
struct event ev_sigchld;
|
||||||
TAILQ_HEAD(,radiusd_module) module;
|
TAILQ_HEAD(,radiusd_module) module;
|
||||||
TAILQ_HEAD(,radiusd_authentication) authen;
|
TAILQ_HEAD(,radiusd_authentication) authen;
|
||||||
|
TAILQ_HEAD(,radiusd_accounting) account;
|
||||||
TAILQ_HEAD(,radiusd_client) client;
|
TAILQ_HEAD(,radiusd_client) client;
|
||||||
TAILQ_HEAD(,radius_query) query;
|
TAILQ_HEAD(,radius_query) query;
|
||||||
|
int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct radius_query {
|
struct radius_query {
|
||||||
|
@ -150,6 +162,9 @@ struct radius_query {
|
||||||
#define MODULE_DO_ACCSREQ(_m) \
|
#define MODULE_DO_ACCSREQ(_m) \
|
||||||
((_m)->fd >= 0 && \
|
((_m)->fd >= 0 && \
|
||||||
((_m)->capabilities & RADIUSD_MODULE_CAP_ACCSREQ) != 0)
|
((_m)->capabilities & RADIUSD_MODULE_CAP_ACCSREQ) != 0)
|
||||||
|
#define MODULE_DO_ACCTREQ(_m) \
|
||||||
|
((_m)->fd >= 0 && \
|
||||||
|
((_m)->capabilities & RADIUSD_MODULE_CAP_ACCTREQ) != 0)
|
||||||
#define MODULE_DO_REQDECO(_m) \
|
#define MODULE_DO_REQDECO(_m) \
|
||||||
((_m)->fd >= 0 && \
|
((_m)->fd >= 0 && \
|
||||||
((_m)->capabilities & RADIUSD_MODULE_CAP_REQDECO) != 0)
|
((_m)->capabilities & RADIUSD_MODULE_CAP_REQDECO) != 0)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: radiusd_module.c,v 1.16 2024/02/09 07:41:32 yasuoka Exp $ */
|
/* $OpenBSD: radiusd_module.c,v 1.17 2024/07/02 00:33:51 yasuoka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
|
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
|
||||||
|
@ -50,6 +50,8 @@ static void (*module_request_decoration) (void *, u_int, const u_char *,
|
||||||
size_t) = NULL;
|
size_t) = NULL;
|
||||||
static void (*module_response_decoration) (void *, u_int, const u_char *,
|
static void (*module_response_decoration) (void *, u_int, const u_char *,
|
||||||
size_t, const u_char *, size_t) = NULL;
|
size_t, const u_char *, size_t) = NULL;
|
||||||
|
static void (*module_accounting_request) (void *, u_int, const u_char *,
|
||||||
|
size_t) = NULL;
|
||||||
|
|
||||||
struct module_base {
|
struct module_base {
|
||||||
void *ctx;
|
void *ctx;
|
||||||
|
@ -98,6 +100,7 @@ module_create(int sock, void *ctx, struct module_handlers *handler)
|
||||||
module_config_set = handler->config_set;
|
module_config_set = handler->config_set;
|
||||||
module_request_decoration = handler->request_decoration;
|
module_request_decoration = handler->request_decoration;
|
||||||
module_response_decoration = handler->response_decoration;
|
module_response_decoration = handler->response_decoration;
|
||||||
|
module_accounting_request = handler->accounting_request;
|
||||||
module_start_module = handler->start;
|
module_start_module = handler->start;
|
||||||
module_stop_module = handler->stop;
|
module_stop_module = handler->stop;
|
||||||
|
|
||||||
|
@ -156,6 +159,8 @@ module_load(struct module_base *base)
|
||||||
load.cap |= RADIUSD_MODULE_CAP_REQDECO;
|
load.cap |= RADIUSD_MODULE_CAP_REQDECO;
|
||||||
if (module_response_decoration != NULL)
|
if (module_response_decoration != NULL)
|
||||||
load.cap |= RADIUSD_MODULE_CAP_RESDECO;
|
load.cap |= RADIUSD_MODULE_CAP_RESDECO;
|
||||||
|
if (module_accounting_request != NULL)
|
||||||
|
load.cap |= RADIUSD_MODULE_CAP_ACCTREQ;
|
||||||
imsg_compose(&base->ibuf, IMSG_RADIUSD_MODULE_LOAD, 0, 0, -1, &load,
|
imsg_compose(&base->ibuf, IMSG_RADIUSD_MODULE_LOAD, 0, 0, -1, &load,
|
||||||
sizeof(load));
|
sizeof(load));
|
||||||
imsg_flush(&base->ibuf);
|
imsg_flush(&base->ibuf);
|
||||||
|
@ -447,6 +452,7 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
|
||||||
case IMSG_RADIUSD_MODULE_REQDECO:
|
case IMSG_RADIUSD_MODULE_REQDECO:
|
||||||
case IMSG_RADIUSD_MODULE_RESDECO0_REQ:
|
case IMSG_RADIUSD_MODULE_RESDECO0_REQ:
|
||||||
case IMSG_RADIUSD_MODULE_RESDECO:
|
case IMSG_RADIUSD_MODULE_RESDECO:
|
||||||
|
case IMSG_RADIUSD_MODULE_ACCTREQ:
|
||||||
{
|
{
|
||||||
struct radiusd_module_radpkt_arg *accessreq;
|
struct radiusd_module_radpkt_arg *accessreq;
|
||||||
int chunklen;
|
int chunklen;
|
||||||
|
@ -459,6 +465,13 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
typestr = "ACCSREQ";
|
typestr = "ACCSREQ";
|
||||||
|
} else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_ACCTREQ) {
|
||||||
|
if (module_accounting_request == NULL) {
|
||||||
|
syslog(LOG_ERR, "Received ACCTREQ message, but "
|
||||||
|
"module doesn't support");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
typestr = "ACCTREQ";
|
||||||
} else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_REQDECO) {
|
} else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_REQDECO) {
|
||||||
if (module_request_decoration == NULL) {
|
if (module_request_decoration == NULL) {
|
||||||
syslog(LOG_ERR, "Received REQDECO message, but "
|
syslog(LOG_ERR, "Received REQDECO message, but "
|
||||||
|
@ -539,14 +552,16 @@ module_imsg_handler(struct module_base *base, struct imsg *imsg)
|
||||||
}
|
}
|
||||||
memcpy(base->radpkt2, base->radpkt, base->radpktoff);
|
memcpy(base->radpkt2, base->radpkt, base->radpktoff);
|
||||||
base->radpkt2len = base->radpktoff;
|
base->radpkt2len = base->radpktoff;
|
||||||
} else {
|
} else if (imsg->hdr.type == IMSG_RADIUSD_MODULE_RESDECO) {
|
||||||
module_response_decoration(base->ctx, accessreq->q_id,
|
module_response_decoration(base->ctx, accessreq->q_id,
|
||||||
base->radpkt2, base->radpkt2len, base->radpkt,
|
base->radpkt2, base->radpkt2len, base->radpkt,
|
||||||
base->radpktoff);
|
base->radpktoff);
|
||||||
base->radpkt2len = 0;
|
base->radpkt2len = 0;
|
||||||
}
|
} else
|
||||||
|
module_accounting_request(base->ctx, accessreq->q_id,
|
||||||
|
base->radpkt, base->radpktoff);
|
||||||
base->radpktoff = 0;
|
base->radpktoff = 0;
|
||||||
accsreq_out:
|
accsreq_out:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "radiusd.h"
|
#include "radiusd.h"
|
||||||
|
|
||||||
struct module_ctx;
|
struct module_ctx;
|
||||||
|
struct imsg;
|
||||||
|
|
||||||
struct module_handlers {
|
struct module_handlers {
|
||||||
/* Should send IMSG_OK or IMSG_NG */
|
/* Should send IMSG_OK or IMSG_NG */
|
||||||
|
@ -42,6 +43,11 @@ struct module_handlers {
|
||||||
|
|
||||||
void (*response_decoration)(void *ctx, u_int query_id,
|
void (*response_decoration)(void *ctx, u_int query_id,
|
||||||
const u_char *req, size_t reqlen, const u_char *res, size_t reslen);
|
const u_char *req, size_t reqlen, const u_char *res, size_t reslen);
|
||||||
|
|
||||||
|
void (*accounting_request)(void *ctx, u_int query_id, const u_char *pkt,
|
||||||
|
size_t pktlen);
|
||||||
|
|
||||||
|
void (*dispatch_control)(void *ctx, struct imsg *);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SYNTAX_ASSERT(_cond, _msg) \
|
#define SYNTAX_ASSERT(_cond, _msg) \
|
||||||
|
@ -77,6 +83,10 @@ int module_reqdeco_done(struct module_base *, u_int,
|
||||||
const u_char *, size_t);
|
const u_char *, size_t);
|
||||||
int module_resdeco_done(struct module_base *, u_int,
|
int module_resdeco_done(struct module_base *, u_int,
|
||||||
const u_char *, size_t);
|
const u_char *, size_t);
|
||||||
|
int module_imsg_compose(struct module_base *, uint32_t,
|
||||||
|
uint32_t, pid_t, int, const void *, size_t);
|
||||||
|
int module_imsg_composev(struct module_base *, uint32_t,
|
||||||
|
uint32_t, pid_t, int, const struct iovec *, int);
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|
84
usr.sbin/radiusd/radiusd_radius.8
Normal file
84
usr.sbin/radiusd/radiusd_radius.8
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
.\" $OpenBSD: radiusd_radius.8,v 1.1 2024/07/02 00:00:12 yasuoka Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 2014 Esdenera Networks GmbH
|
||||||
|
.\" Copyright (c) 2014, 2024 Internet Initiative Japan Inc.
|
||||||
|
.\"
|
||||||
|
.\" Permission to use, copy, modify, and distribute this software for any
|
||||||
|
.\" purpose with or without fee is hereby granted, provided that the above
|
||||||
|
.\" copyright notice and this permission notice appear in all copies.
|
||||||
|
.\"
|
||||||
|
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
.\"
|
||||||
|
.\" The following requests are required for all man pages.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: July 2 2024 $
|
||||||
|
.Dt RADIUSD_RADIUS 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm radiusd_radius
|
||||||
|
.Nd provide authentication from upstream RADIUS servers
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm radiusd_radius
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility is executed by
|
||||||
|
.Xr radiusd 8
|
||||||
|
as a module to provide authentication from upstream RADIUS servers.
|
||||||
|
.Sh CONFIGURATIONS
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
supports the following configuration key and value:
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic server Ar address Ns Op : Ns Ar port
|
||||||
|
Specify the upstream server's address and port.
|
||||||
|
If
|
||||||
|
.Ar port
|
||||||
|
is omitted, 1812 is used.
|
||||||
|
This configuration can be specified multiple times.
|
||||||
|
.It Ic secret Ar secret
|
||||||
|
Specify the shared secret with the servers.
|
||||||
|
This configuration cannot be omitted.
|
||||||
|
.It Ic max-tries Ar number
|
||||||
|
Specify the maximum number of retransmissions for a server.
|
||||||
|
.Xr radiusd 8
|
||||||
|
will retransmit 2, 6, 14, 22, and 30 seconds after the first transmission
|
||||||
|
and subsequent retransmissions will occur every 8 seconds.
|
||||||
|
If the number of retransmissions per server reaches this value,
|
||||||
|
the current server is marked as
|
||||||
|
.Dq fail ,
|
||||||
|
and the next server is used for subsequent requests.
|
||||||
|
The default value is 3.
|
||||||
|
.It Ic max-failovers Ar number
|
||||||
|
If a positive number is specified,
|
||||||
|
.Xr radiusd 8
|
||||||
|
will failover to the next server
|
||||||
|
when the current server is marked
|
||||||
|
.Dq fail .
|
||||||
|
This key and value specifies the maximum number of failovers.
|
||||||
|
The default value is 0.
|
||||||
|
.It Ic request-timeout Ar sec
|
||||||
|
Specify the request timeout in seconds.
|
||||||
|
If this value is specified,
|
||||||
|
.Ar max-tries
|
||||||
|
and
|
||||||
|
.Ar max-failover
|
||||||
|
will not be used.
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width "/usr/libexec/radiusd/radiusd_radius" -compact
|
||||||
|
.It Pa /usr/libexec/radiusd/radiusd_radius
|
||||||
|
.Dq radius
|
||||||
|
module executable.
|
||||||
|
.El
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
daemon first appeared in
|
||||||
|
.Ox 5.8 .
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: radiusd_radius.c,v 1.20 2024/02/09 07:41:32 yasuoka Exp $ */
|
/* $OpenBSD: radiusd_radius.c,v 1.21 2024/07/01 03:17:00 yasuoka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013 Internet Initiative Japan Inc.
|
* Copyright (c) 2013 Internet Initiative Japan Inc.
|
||||||
|
@ -613,8 +613,7 @@ module_radius_req_reset_msgauth(struct module_radius_req *req)
|
||||||
if (radius_has_attr(req->q_pkt, RADIUS_TYPE_MESSAGE_AUTHENTICATOR))
|
if (radius_has_attr(req->q_pkt, RADIUS_TYPE_MESSAGE_AUTHENTICATOR))
|
||||||
radius_del_attr_all(req->q_pkt,
|
radius_del_attr_all(req->q_pkt,
|
||||||
RADIUS_TYPE_MESSAGE_AUTHENTICATOR);
|
RADIUS_TYPE_MESSAGE_AUTHENTICATOR);
|
||||||
radius_put_message_authenticator(req->q_pkt,
|
radius_put_message_authenticator(req->q_pkt, req->module->secret);
|
||||||
req->module->secret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
# $OpenBSD: Makefile,v 1.2 2024/01/28 18:38:16 deraadt Exp $
|
# $OpenBSD: Makefile,v 1.3 2024/07/02 00:00:12 yasuoka Exp $
|
||||||
PROG= radiusd_radius
|
PROG= radiusd_radius
|
||||||
BINDIR= /usr/libexec/radiusd
|
BINDIR= /usr/libexec/radiusd
|
||||||
SRCS= radiusd_radius.c radiusd_module.c util.c imsg_subr.c log.c
|
SRCS= radiusd_radius.c radiusd_module.c util.c imsg_subr.c log.c
|
||||||
CFLAGS+= -DUSE_LIBEVENT
|
CFLAGS+= -DUSE_LIBEVENT
|
||||||
LDADD+= -lradius -lcrypto -lutil -levent
|
LDADD+= -lradius -lcrypto -lutil -levent
|
||||||
DPADD+= ${LIBRADIUS} ${LIBCRYPTO} ${LIBUTIL} ${LIBEVENT}
|
DPADD+= ${LIBRADIUS} ${LIBCRYPTO} ${LIBUTIL} ${LIBEVENT}
|
||||||
NOMAN= #
|
MAN= radiusd_radius.8
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
|
77
usr.sbin/radiusd/radiusd_standard.8
Normal file
77
usr.sbin/radiusd/radiusd_standard.8
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
.\" $OpenBSD: radiusd_standard.8,v 1.2 2024/07/02 00:33:51 yasuoka Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 2014 Esdenera Networks GmbH
|
||||||
|
.\" Copyright (c) 2014, 2024 Internet Initiative Japan Inc.
|
||||||
|
.\"
|
||||||
|
.\" Permission to use, copy, modify, and distribute this software for any
|
||||||
|
.\" purpose with or without fee is hereby granted, provided that the above
|
||||||
|
.\" copyright notice and this permission notice appear in all copies.
|
||||||
|
.\"
|
||||||
|
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
.\"
|
||||||
|
.\" The following requests are required for all man pages.
|
||||||
|
.\"
|
||||||
|
.Dd $Mdocdate: July 2 2024 $
|
||||||
|
.Dt RADIUSD_STANDARD 8
|
||||||
|
.Os
|
||||||
|
.Sh NAME
|
||||||
|
.Nm radiusd_standard
|
||||||
|
.Nd provide standard decorations for RADIUS messages
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm radiusd_standard
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
utility is executed by
|
||||||
|
.Xr radiusd 8
|
||||||
|
as a module to provide various standard functionalities.
|
||||||
|
It can be configured as a module for decoration which modifies request and
|
||||||
|
response RADIUS messages.
|
||||||
|
Also it can be configured as an accounting module that logs accounting
|
||||||
|
information through
|
||||||
|
.Xr syslog 3 .
|
||||||
|
.Sh CONFIGURATIONS
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
module supports the following configuration key and value:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -width Ds
|
||||||
|
.It Ic strip-atmark-realm Ar true | false
|
||||||
|
Remove the realm part which starts with @
|
||||||
|
.Pq atmark
|
||||||
|
from the User-Name attribute of the Access-Request.
|
||||||
|
.Pp
|
||||||
|
.It Ic strip-nt-domain Ar true | false
|
||||||
|
Remove NT domain which ends with \\
|
||||||
|
.Pq backslash
|
||||||
|
from the User-Name attribute of the Access-Request.
|
||||||
|
.Pp
|
||||||
|
.It Cm remove-request-attribute Oo Ar vendor Oc Ar type
|
||||||
|
.It Cm remove-response-attribute Oo Ar vendor Oc Ar type
|
||||||
|
Remove all the specified attributes from request or response
|
||||||
|
messages of Access-Request.
|
||||||
|
Specify
|
||||||
|
.Ar type
|
||||||
|
of the attribute in a decimal number.
|
||||||
|
To specify a vendor attribute,
|
||||||
|
specify the Vendor-Id
|
||||||
|
in a decimal number for
|
||||||
|
.Ar vendor .
|
||||||
|
.El
|
||||||
|
.Sh FILES
|
||||||
|
.Bl -tag -width "/usr/libexec/radiusd/radiusd_standard" -compact
|
||||||
|
.It Pa /usr/libexec/radiusd/radiusd_standard
|
||||||
|
.Dq standard
|
||||||
|
module executable.
|
||||||
|
.El
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
daemon first appeared in
|
||||||
|
.Ox 5.8 .
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: radiusd_standard.c,v 1.5 2024/04/23 13:34:51 jsg Exp $ */
|
/* $OpenBSD: radiusd_standard.c,v 1.6 2024/07/02 00:33:51 yasuoka Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2013, 2023 Internet Initiative Japan Inc.
|
* Copyright (c) 2013, 2023 Internet Initiative Japan Inc.
|
||||||
|
@ -17,6 +17,8 @@
|
||||||
*/
|
*/
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/queue.h>
|
#include <sys/queue.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
|
||||||
#include <err.h>
|
#include <err.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -49,11 +51,34 @@ struct module_standard {
|
||||||
struct attrs remove_resattrs;
|
struct attrs remove_resattrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct radius_const_str {
|
||||||
|
const unsigned constval;
|
||||||
|
const char *label;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void radius_const_print(FILE *, RADIUS_PACKET *, uint8_t,
|
||||||
|
const char *, struct radius_const_str *);
|
||||||
static void module_standard_config_set(void *, const char *, int,
|
static void module_standard_config_set(void *, const char *, int,
|
||||||
char * const *);
|
char * const *);
|
||||||
static void module_standard_reqdeco(void *, u_int, const u_char *, size_t);
|
static void module_standard_reqdeco(void *, u_int, const u_char *, size_t);
|
||||||
static void module_standard_resdeco(void *, u_int, const u_char *, size_t,
|
static void module_standard_resdeco(void *, u_int, const u_char *, size_t,
|
||||||
const u_char *, size_t);
|
const u_char *, size_t);
|
||||||
|
static void module_accounting_request(void *, u_int, const u_char *,
|
||||||
|
size_t);
|
||||||
|
static void radius_u32_print(FILE *, RADIUS_PACKET *, uint8_t,
|
||||||
|
const char *);
|
||||||
|
static void radius_str_print(FILE *, RADIUS_PACKET *, uint8_t,
|
||||||
|
const char *);
|
||||||
|
static void radius_ipv4_print(FILE *, RADIUS_PACKET *, uint8_t,
|
||||||
|
const char *);
|
||||||
|
static void radius_ipv6_print(FILE *, RADIUS_PACKET *, uint8_t,
|
||||||
|
const char *);
|
||||||
|
|
||||||
|
static struct radius_const_str
|
||||||
|
nas_port_type_consts[], tunnel_type_consts[],
|
||||||
|
service_type_consts[], framed_protocol_consts[],
|
||||||
|
acct_status_type_consts[], acct_authentic_consts[],
|
||||||
|
terminate_cause_consts[], tunnel_medium_type_consts[];
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
|
@ -62,7 +87,8 @@ main(int argc, char *argv[])
|
||||||
struct module_handlers handlers = {
|
struct module_handlers handlers = {
|
||||||
.config_set = module_standard_config_set,
|
.config_set = module_standard_config_set,
|
||||||
.request_decoration = module_standard_reqdeco,
|
.request_decoration = module_standard_reqdeco,
|
||||||
.response_decoration = module_standard_resdeco
|
.response_decoration = module_standard_resdeco,
|
||||||
|
.accounting_request = module_accounting_request
|
||||||
};
|
};
|
||||||
struct attr *attr;
|
struct attr *attr;
|
||||||
|
|
||||||
|
@ -298,3 +324,286 @@ module_standard_resdeco(void *ctx, u_int q_id, const u_char *req, size_t reqlen,
|
||||||
if (radres != NULL)
|
if (radres != NULL)
|
||||||
radius_delete_packet(radres);
|
radius_delete_packet(radres);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
module_accounting_request(void *ctx, u_int query_id, const u_char *pkt,
|
||||||
|
size_t pktlen)
|
||||||
|
{
|
||||||
|
RADIUS_PACKET *radpkt = NULL;
|
||||||
|
struct module_standard *module = ctx;
|
||||||
|
FILE *fp;
|
||||||
|
char *buf = NULL;
|
||||||
|
size_t size = 0;
|
||||||
|
|
||||||
|
if ((radpkt = radius_convert_packet(pkt, pktlen)) == NULL) {
|
||||||
|
syslog(LOG_ERR,
|
||||||
|
"%s: radius_convert_packet() failed: %m", __func__);
|
||||||
|
module_stop(module->base);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((fp = open_memstream(&buf, &size)) == NULL) {
|
||||||
|
syslog(LOG_ERR, "%s: open_memstream() failed: %m", __func__);
|
||||||
|
module_stop(module->base);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
radius_const_print(fp, radpkt, RADIUS_TYPE_ACCT_STATUS_TYPE,
|
||||||
|
"Acct-Status-Type", acct_status_type_consts);
|
||||||
|
|
||||||
|
radius_ipv4_print(fp, radpkt, RADIUS_TYPE_NAS_IP_ADDRESS,
|
||||||
|
"NAS-IP-Address");
|
||||||
|
radius_ipv6_print(fp, radpkt, RADIUS_TYPE_NAS_IPV6_ADDRESS,
|
||||||
|
"NAS-IPv6-Address");
|
||||||
|
radius_const_print(fp, radpkt, RADIUS_TYPE_NAS_PORT_TYPE,
|
||||||
|
"NAS-Port-Type", nas_port_type_consts);
|
||||||
|
radius_u32_print(fp, radpkt, RADIUS_TYPE_NAS_PORT, "NAS-Port");
|
||||||
|
radius_str_print(fp, radpkt, RADIUS_TYPE_NAS_IDENTIFIER,
|
||||||
|
"NAS-Identifier");
|
||||||
|
radius_str_print(fp, radpkt, RADIUS_TYPE_CALLING_STATION_ID,
|
||||||
|
"Calling-Station-ID");
|
||||||
|
radius_str_print(fp, radpkt, RADIUS_TYPE_CALLED_STATION_ID,
|
||||||
|
"Called-Station-ID");
|
||||||
|
|
||||||
|
radius_const_print(fp, radpkt, RADIUS_TYPE_TUNNEL_MEDIUM_TYPE,
|
||||||
|
"Tunnel-Medium-Type", tunnel_medium_type_consts);
|
||||||
|
radius_str_print(fp, radpkt, RADIUS_TYPE_TUNNEL_CLIENT_ENDPOINT,
|
||||||
|
"Tunnel-Client-Endpoint");
|
||||||
|
radius_str_print(fp, radpkt, RADIUS_TYPE_TUNNEL_SERVER_ENDPOINT,
|
||||||
|
"Tunnel-Server-Endpoint");
|
||||||
|
radius_str_print(fp, radpkt, RADIUS_TYPE_TUNNEL_ASSIGNMENT_ID,
|
||||||
|
"Tunnel-Assignment-ID");
|
||||||
|
radius_str_print(fp, radpkt, RADIUS_TYPE_ACCT_TUNNEL_CONNECTION,
|
||||||
|
"Acct-Tunnel-Connection");
|
||||||
|
|
||||||
|
radius_u32_print(fp, radpkt, RADIUS_TYPE_ACCT_SESSION_TIME,
|
||||||
|
"Acct-Session-Time");
|
||||||
|
radius_const_print(fp, radpkt,
|
||||||
|
RADIUS_TYPE_TUNNEL_TYPE, "Tunnel-Type", tunnel_type_consts);
|
||||||
|
radius_str_print(fp, radpkt, RADIUS_TYPE_USER_NAME, "User-Name");
|
||||||
|
radius_const_print(fp, radpkt,
|
||||||
|
RADIUS_TYPE_SERVICE_TYPE, "Service-Type", service_type_consts);
|
||||||
|
radius_const_print(fp, radpkt, RADIUS_TYPE_FRAMED_PROTOCOL,
|
||||||
|
"Framed-Protocol", framed_protocol_consts);
|
||||||
|
radius_ipv4_print(fp, radpkt, RADIUS_TYPE_FRAMED_IP_ADDRESS,
|
||||||
|
"Framed-IP-Address");
|
||||||
|
radius_u32_print(fp, radpkt, RADIUS_TYPE_ACCT_DELAY_TIME,
|
||||||
|
"Acct-Delay-Time");
|
||||||
|
radius_u32_print(fp, radpkt, RADIUS_TYPE_ACCT_INPUT_OCTETS,
|
||||||
|
"Acct-Input-Octets");
|
||||||
|
radius_u32_print(fp, radpkt, RADIUS_TYPE_ACCT_OUTPUT_OCTETS,
|
||||||
|
"Acct-Output-Octets");
|
||||||
|
radius_str_print(fp, radpkt, RADIUS_TYPE_ACCT_SESSION_ID,
|
||||||
|
"Acct-Session-ID");
|
||||||
|
radius_const_print(fp, radpkt, RADIUS_TYPE_ACCT_AUTHENTIC,
|
||||||
|
"Acct-Authentic", acct_authentic_consts);
|
||||||
|
radius_u32_print(fp, radpkt, RADIUS_TYPE_ACCT_SESSION_TIME,
|
||||||
|
"Acct-Sesion-Time");
|
||||||
|
radius_u32_print(fp, radpkt, RADIUS_TYPE_ACCT_INPUT_PACKETS,
|
||||||
|
"Acct-Input-Packets");
|
||||||
|
radius_u32_print(fp, radpkt, RADIUS_TYPE_ACCT_OUTPUT_PACKETS,
|
||||||
|
"Acct-Output-Packets");
|
||||||
|
radius_const_print(fp, radpkt, RADIUS_TYPE_ACCT_TERMINATE_CAUSE,
|
||||||
|
"Acct-Terminate-Cause", terminate_cause_consts);
|
||||||
|
radius_u32_print(fp, radpkt, RADIUS_TYPE_ACCT_INPUT_GIGAWORDS,
|
||||||
|
"Acct-Input-Gigawords");
|
||||||
|
radius_u32_print(fp, radpkt, RADIUS_TYPE_ACCT_OUTPUT_GIGAWORDS,
|
||||||
|
"Acct-Output-Gigawords");
|
||||||
|
|
||||||
|
fputc('\0', fp);
|
||||||
|
fclose(fp);
|
||||||
|
syslog(LOG_INFO, "Accounting q=%u %s", query_id, buf + 1);
|
||||||
|
out:
|
||||||
|
radius_delete_packet(radpkt);
|
||||||
|
freezero(buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* print RADIUS attribute
|
||||||
|
***********************************************************************/
|
||||||
|
static void
|
||||||
|
radius_const_print(FILE *fout, RADIUS_PACKET *radpkt, uint8_t attr_type,
|
||||||
|
const char *attr_name, struct radius_const_str *consts)
|
||||||
|
{
|
||||||
|
struct radius_const_str *const_;
|
||||||
|
uint32_t u32val;
|
||||||
|
|
||||||
|
if (radius_get_uint32_attr(radpkt, attr_type, &u32val) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const_ = consts; const_->label != NULL; const_++) {
|
||||||
|
if (const_->constval == u32val)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(fout, " %s=%s(%u)", attr_name, (const_ != NULL)? const_->label
|
||||||
|
: "unknown", (unsigned)u32val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
radius_u32_print(FILE *fout, RADIUS_PACKET *radpkt, uint8_t attr_type,
|
||||||
|
const char *attr_name)
|
||||||
|
{
|
||||||
|
uint32_t u32val;
|
||||||
|
|
||||||
|
if (radius_get_uint32_attr(radpkt, attr_type, &u32val) != 0)
|
||||||
|
return;
|
||||||
|
fprintf(fout, " %s=%u", attr_name, u32val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
radius_str_print(FILE *fout, RADIUS_PACKET *radpkt, uint8_t attr_type,
|
||||||
|
const char *attr_name)
|
||||||
|
{
|
||||||
|
char strval[256];
|
||||||
|
|
||||||
|
if (radius_get_string_attr(radpkt, attr_type, strval, sizeof(strval))
|
||||||
|
!= 0)
|
||||||
|
return;
|
||||||
|
fprintf(fout, " %s=%s", attr_name, strval);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
radius_ipv4_print(FILE *fout, RADIUS_PACKET *radpkt, uint8_t attr_type,
|
||||||
|
const char *attr_name)
|
||||||
|
{
|
||||||
|
struct in_addr ipv4;
|
||||||
|
char buf[128];
|
||||||
|
|
||||||
|
if (radius_get_ipv4_attr(radpkt, attr_type, &ipv4) != 0)
|
||||||
|
return;
|
||||||
|
fprintf(fout, " %s=%s", attr_name,
|
||||||
|
inet_ntop(AF_INET, &ipv4, buf, sizeof(buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
radius_ipv6_print(FILE *fout, RADIUS_PACKET *radpkt, uint8_t attr_type,
|
||||||
|
const char *attr_name)
|
||||||
|
{
|
||||||
|
struct in6_addr ipv6;
|
||||||
|
char buf[128];
|
||||||
|
|
||||||
|
if (radius_get_ipv6_attr(radpkt, attr_type, &ipv6) != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fprintf(fout, " %s=%s", attr_name,
|
||||||
|
inet_ntop(AF_INET6, &ipv6, buf, sizeof(buf)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct radius_const_str nas_port_type_consts[] = {
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_ASYNC, "\"Async\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_SYNC, "\"Sync\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_ISDN_SYNC, "\"ISDN Sync\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_ISDN_ASYNC_V120, "\"ISDN Async V.120\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_ISDN_ASYNC_V110, "\"ISDN Async V.110\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_VIRTUAL, "\"Virtual\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_PIAFS, "\"PIAFS\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_HDLC_CLEAR_CHANNEL, "\"HDLC Clear Channel\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_X_25, "\"X.25\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_X_75, "\"X.75\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_G3_FAX, "\"G.3 Fax\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_SDSL, "\"SDSL\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_ADSL_CAP, "\"ADSL-CAP\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_ADSL_DMT, "\"ADSL-DMT\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_IDSL, "\"IDSL\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_ETHERNET, "\"Ethernet\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_XDSL, "\"xDSL\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_CABLE, "\"Cable\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_WIRELESS, "\"Wireless\"" },
|
||||||
|
{ RADIUS_NAS_PORT_TYPE_WIRELESS_802_11, "\"Wireless - IEEE 802.11\"" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct radius_const_str tunnel_type_consts[] = {
|
||||||
|
{ RADIUS_TUNNEL_TYPE_PPTP, "PPTP" },
|
||||||
|
{ RADIUS_TUNNEL_TYPE_L2F, "L2F" },
|
||||||
|
{ RADIUS_TUNNEL_TYPE_L2TP, "L2TP" },
|
||||||
|
{ RADIUS_TUNNEL_TYPE_ATMP, "ATMP" },
|
||||||
|
{ RADIUS_TUNNEL_TYPE_VTP, "VTP" },
|
||||||
|
{ RADIUS_TUNNEL_TYPE_AH, "AH" },
|
||||||
|
{ RADIUS_TUNNEL_TYPE_IP, "IP" },
|
||||||
|
{ RADIUS_TUNNEL_TYPE_MOBILE, "MIN-IP-IP" },
|
||||||
|
{ RADIUS_TUNNEL_TYPE_ESP, "ESP" },
|
||||||
|
{ RADIUS_TUNNEL_TYPE_GRE, "GRE" },
|
||||||
|
{ RADIUS_TUNNEL_TYPE_VDS, "DVS" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct radius_const_str service_type_consts[] = {
|
||||||
|
{ RADIUS_SERVICE_TYPE_LOGIN, "\"Login\"" },
|
||||||
|
{ RADIUS_SERVICE_TYPE_FRAMED, "\"Framed\"" },
|
||||||
|
{ RADIUS_SERVICE_TYPE_CB_LOGIN, "\"Callback Login\"" },
|
||||||
|
{ RADIUS_SERVICE_TYPE_CB_FRAMED, "\"Callback Framed\"" },
|
||||||
|
{ RADIUS_SERVICE_TYPE_OUTBOUND, "\"Outbound\"" },
|
||||||
|
{ RADIUS_SERVICE_TYPE_ADMINISTRATIVE, "\"Administrative\"" },
|
||||||
|
{ RADIUS_SERVICE_TYPE_NAS_PROMPT, "\"NAS Propmt\"" },
|
||||||
|
/* there had been a typo in radius.h */
|
||||||
|
#if !defined(RADIUS_SERVICE_TYPE_CB_NAS_PROMPT) && \
|
||||||
|
defined(RADIUS_SERVICE_TYPE_CB_NAS_PROMPTi)
|
||||||
|
#define RADIUS_SERVICE_TYPE_CB_NAS_PROMPT RADIUS_SERVICE_TYPE_CB_NAS_PROMPTi
|
||||||
|
#endif
|
||||||
|
{ RADIUS_SERVICE_TYPE_AUTHENTICAT_ONLY, "\"Authenticat Only\"" },
|
||||||
|
{ RADIUS_SERVICE_TYPE_CB_NAS_PROMPT, "\"Callback NAS Prompt\"" },
|
||||||
|
{ RADIUS_SERVICE_TYPE_CALL_CHECK, "\"Call Check\"" },
|
||||||
|
{ RADIUS_SERVICE_TYPE_CB_ADMINISTRATIVE, "\"Callback Administrative\"" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct radius_const_str framed_protocol_consts[] = {
|
||||||
|
{ RADIUS_FRAMED_PROTOCOL_PPP, "PPP" },
|
||||||
|
{ RADIUS_FRAMED_PROTOCOL_SLIP, "SLIP" },
|
||||||
|
{ RADIUS_FRAMED_PROTOCOL_ARAP, "ARAP" },
|
||||||
|
{ RADIUS_FRAMED_PROTOCOL_GANDALF, "Gandalf" },
|
||||||
|
{ RADIUS_FRAMED_PROTOCOL_XYLOGICS, "Xylogics" },
|
||||||
|
{ RADIUS_FRAMED_PROTOCOL_X75, "X.75" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct radius_const_str acct_status_type_consts[] = {
|
||||||
|
{ RADIUS_ACCT_STATUS_TYPE_START, "Start" },
|
||||||
|
{ RADIUS_ACCT_STATUS_TYPE_STOP, "Stop" },
|
||||||
|
{ RADIUS_ACCT_STATUS_TYPE_INTERIM_UPDATE, "Interim-Update" },
|
||||||
|
{ RADIUS_ACCT_STATUS_TYPE_ACCT_ON, "Accounting-On" },
|
||||||
|
{ RADIUS_ACCT_STATUS_TYPE_ACCT_OFF, "Accounting-Off" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct radius_const_str acct_authentic_consts[] = {
|
||||||
|
{ RADIUS_ACCT_AUTHENTIC_RADIUS, "RADIUS" },
|
||||||
|
{ RADIUS_ACCT_AUTHENTIC_LOCAL, "Local" },
|
||||||
|
{ RADIUS_ACCT_AUTHENTIC_REMOTE, "Remote" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct radius_const_str terminate_cause_consts[] = {
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_USER_REQUEST, "\"User Request\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_LOST_CARRIER, "\"Lost Carrier\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_LOST_SERVICE, "\"Lost Service\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_IDLE_TIMEOUT, "\"Idle Timeout\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_SESSION_TIMEOUT, "\"Session Timeout\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_ADMIN_RESET, "\"Admin Reset\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_ADMIN_REBOOT, "\"Admin Reboot\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_PORT_ERROR, "\"Port Error\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_NAS_ERROR, "\"NAS Error\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_NAS_RESET, "\"NAS Request\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_NAS_REBOOT, "\"NAS Reboot\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_PORT_UNNEEDED, "\"Port Unneeded\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_PORT_PREEMPTED, "\"Port Preempted\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_PORT_SUSPENDED, "\"Port Suspended\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_SERVICE_UNAVAIL, "\"Service Unavailable\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_CALLBACK, "\"Callback\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_USER_ERROR, "\"User Error\"" },
|
||||||
|
{ RADIUS_TERMNATE_CAUSE_HOST_REQUEST, "\"Host Request\"" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct radius_const_str tunnel_medium_type_consts[] = {
|
||||||
|
{ RADIUS_TUNNEL_MEDIUM_TYPE_IPV4, "IPv4" },
|
||||||
|
{ RADIUS_TUNNEL_MEDIUM_TYPE_IPV6, "IPv6" },
|
||||||
|
{ RADIUS_TUNNEL_MEDIUM_TYPE_NSAP, "NSAP" },
|
||||||
|
{ RADIUS_TUNNEL_MEDIUM_TYPE_HDLC, "HDLC" },
|
||||||
|
{ RADIUS_TUNNEL_MEDIUM_TYPE_BBN1822, "BBN1822" },
|
||||||
|
{ RADIUS_TUNNEL_MEDIUM_TYPE_802, "802" },
|
||||||
|
{ RADIUS_TUNNEL_MEDIUM_TYPE_E163, "E.163" },
|
||||||
|
{ RADIUS_TUNNEL_MEDIUM_TYPE_E164, "E.164" },
|
||||||
|
{ 0, NULL }
|
||||||
|
};
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
# $OpenBSD: Makefile,v 1.1 2023/09/08 05:56:22 yasuoka Exp $
|
# $OpenBSD: Makefile,v 1.2 2024/07/02 00:00:12 yasuoka Exp $
|
||||||
PROG= radiusd_standard
|
PROG= radiusd_standard
|
||||||
BINDIR= /usr/libexec/radiusd
|
BINDIR= /usr/libexec/radiusd
|
||||||
SRCS= radiusd_standard.c radiusd_module.c
|
SRCS= radiusd_standard.c radiusd_module.c
|
||||||
LDADD= -lutil -lradius -lcrypto
|
LDADD= -lutil -lradius -lcrypto
|
||||||
NOMAN= #
|
MAN= radiusd_standard.8
|
||||||
|
|
||||||
.include <bsd.prog.mk>
|
.include <bsd.prog.mk>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $OpenBSD: syslogd.c,v 1.281 2024/06/29 11:29:55 jsg Exp $ */
|
/* $OpenBSD: syslogd.c,v 1.282 2024/07/01 12:06:45 bluhm Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2014-2021 Alexander Bluhm <bluhm@genua.de>
|
* Copyright (c) 2014-2021 Alexander Bluhm <bluhm@genua.de>
|
||||||
|
@ -314,6 +314,7 @@ int reserve_accept4(int, int, struct event *,
|
||||||
void tcp_acceptcb(int, short, void *);
|
void tcp_acceptcb(int, short, void *);
|
||||||
void tls_acceptcb(int, short, void *);
|
void tls_acceptcb(int, short, void *);
|
||||||
void acceptcb(int, short, void *, int);
|
void acceptcb(int, short, void *, int);
|
||||||
|
void tls_handshakecb(struct bufferevent *, void *);
|
||||||
int octet_counting(struct evbuffer *, char **, int);
|
int octet_counting(struct evbuffer *, char **, int);
|
||||||
int non_transparent_framing(struct evbuffer *, char **);
|
int non_transparent_framing(struct evbuffer *, char **);
|
||||||
void tcp_readcb(struct bufferevent *, void *);
|
void tcp_readcb(struct bufferevent *, void *);
|
||||||
|
@ -1188,6 +1189,7 @@ acceptcb(int lfd, short event, void *arg, int usetls)
|
||||||
close(fd);
|
close(fd);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
p->p_bufev->readcb = tls_handshakecb;
|
||||||
buffertls_set(&p->p_buftls, p->p_bufev, p->p_ctx, fd);
|
buffertls_set(&p->p_buftls, p->p_bufev, p->p_ctx, fd);
|
||||||
buffertls_accept(&p->p_buftls, fd);
|
buffertls_accept(&p->p_buftls, fd);
|
||||||
log_debug("tcp accept callback: tls context success");
|
log_debug("tcp accept callback: tls context success");
|
||||||
|
@ -1209,6 +1211,17 @@ acceptcb(int lfd, short event, void *arg, int usetls)
|
||||||
p->p_ctx ? "tls" : "tcp", peername);
|
p->p_ctx ? "tls" : "tcp", peername);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
tls_handshakecb(struct bufferevent *bufev, void *arg)
|
||||||
|
{
|
||||||
|
struct peer *p = arg;
|
||||||
|
|
||||||
|
log_debug("Completed tls handshake");
|
||||||
|
|
||||||
|
bufev->readcb = tcp_readcb;
|
||||||
|
tcp_readcb(bufev, p);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Syslog over TCP RFC 6587 3.4.1. Octet Counting
|
* Syslog over TCP RFC 6587 3.4.1. Octet Counting
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue