From ff572da00c00fb7bfc6799510e82c2756831fc91 Mon Sep 17 00:00:00 2001 From: rprevot Date: Tue, 5 May 2020 19:49:18 +0200 Subject: [PATCH] Upgrade rlm_jradius for FreeRadius v3.0.x --- .gitignore | 3 + .../jradius/freeradius/RadiusDictionary.java | 25 +- .../attribute/value/Integer64Value.java | 176 ++++ freeradius/rlm_jradius/Makefile | 13 - freeradius/rlm_jradius/all.mk | 11 + freeradius/rlm_jradius/configure | 4 - freeradius/rlm_jradius/rlm_jradius.c | 874 ++++++++++-------- 7 files changed, 718 insertions(+), 388 deletions(-) create mode 100644 core/src/main/java/net/jradius/packet/attribute/value/Integer64Value.java delete mode 100644 freeradius/rlm_jradius/Makefile create mode 100644 freeradius/rlm_jradius/all.mk delete mode 100755 freeradius/rlm_jradius/configure diff --git a/.gitignore b/.gitignore index 0f182a0..37e226d 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,6 @@ *.jar *.war *.ear + +# Maven +target/ diff --git a/core/src/main/java/net/jradius/freeradius/RadiusDictionary.java b/core/src/main/java/net/jradius/freeradius/RadiusDictionary.java index 703b691..5850971 100644 --- a/core/src/main/java/net/jradius/freeradius/RadiusDictionary.java +++ b/core/src/main/java/net/jradius/freeradius/RadiusDictionary.java @@ -423,7 +423,7 @@ public void writeAttrMap(Map map, String pkg, String vName, String cName, String String valueClass = "OctetsValue"; String valueArgs = ""; String extraImport = null; - String extraUtils = null; + String extraUtils = null; int integerLength = 4; (new File(fileSB.toString())).mkdirs(); @@ -443,49 +443,54 @@ public void writeAttrMap(Map map, String pkg, String vName, String cName, String valueClass = "StringValue"; } } - if (desc.type.startsWith("integer")) + else if (desc.type.startsWith("integer64")) + { + valueClass = "Integer64Value"; + } + else if (desc.type.startsWith("integer")) { valueClass = "IntegerValue"; } - if (desc.type.startsWith("singed")) + else if (desc.type.startsWith("singed")) { valueClass = "IntegerValue"; } - if (desc.type.startsWith("date")) + else if (desc.type.startsWith("date")) { valueClass = "DateValue"; extraUtils = "import java.util.Date;\n"; } - if (desc.type.startsWith("ipaddr")) + else if (desc.type.startsWith("ipaddr")) { valueClass = "IPAddrValue"; extraUtils = "import java.net.InetAddress;\n"; } - if (desc.type.startsWith("ipv6addr")) + else if (desc.type.startsWith("ipv6addr")) { valueClass = "IPv6AddrValue"; extraUtils = "import java.net.InetAddress;\n"; } - if (desc.type.startsWith("byte")) + else if (desc.type.startsWith("byte")) { valueClass = "IntegerValue"; integerLength = 1; } - if (desc.type.startsWith("short")) + else if (desc.type.startsWith("short")) { valueClass = "IntegerValue"; integerLength = 2; } // WiMAX: signed - if (desc.type.startsWith("signed")) + else if (desc.type.startsWith("signed")) { valueClass = "SignedValue"; } // WiMAX: combo-ip - if (desc.type.startsWith("combo-ip")) + else if (desc.type.startsWith("combo-ip")) { valueClass = "ComboIPAddrValue"; } + if (desc.values != null) { valueClass = "NamedValue"; diff --git a/core/src/main/java/net/jradius/packet/attribute/value/Integer64Value.java b/core/src/main/java/net/jradius/packet/attribute/value/Integer64Value.java new file mode 100644 index 0000000..12222d6 --- /dev/null +++ b/core/src/main/java/net/jradius/packet/attribute/value/Integer64Value.java @@ -0,0 +1,176 @@ +/** + * JRadius - A RADIUS Server Java Adapter + * Copyright (C) 2004-2006 PicoPoint, B.V. + * + * This library is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at + * your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +package net.jradius.packet.attribute.value; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Serializable; +import java.math.BigInteger; +import java.nio.ByteBuffer; + +import net.jradius.log.RadiusLog; +import net.jradius.packet.Format; + +/** + * The Integer64 attribute value. Uses a BigInteger as the underlying object since + * this is an unsigned long in RADIUS. + */ +public class Integer64Value extends AttributeValue +{ + private static final long serialVersionUID = 0L; + + private int length = 8; + private BigInteger value; + + public Integer64Value() { } + + public Integer64Value(BigInteger i) + { + setValue(i); + } + + public Integer64Value(byte[] bytes) { + setValue(new BigInteger(1, bytes)); + } + + public void copy(AttributeValue value) + { + Integer64Value iValue = (Integer64Value) value; + this.value = iValue.value; + this.length = iValue.length; + } + + public int getLength() + { + return length; + } + + public void getBytes(OutputStream out) throws IOException + { + if (value != null) + { + byte[] bytes = value.toByteArray(); + + for (byte b : bytes) { + out.write(b & 0xFF); + } + } + } + + public void getBytes(ByteBuffer buffer) + { + if (value != null) + { + byte[] bytes = value.toByteArray(); + + for (byte b : bytes) { + Format.putUnsignedByte(buffer, b & 0xFF); + } + } + } + + public void setValue(byte[] bytes) + { + if (bytes == null) return; + setValue(bytes, 0, bytes.length); + } + + public void setValue(byte[] bytes, int off, int len) + { + if (bytes == null) return; + if (len != 8) throw new RuntimeException("Wrong size for integer64 attribute"); + + try + { + byte[] magnitude = new byte[8]; + System.arraycopy(bytes, off, magnitude, 0, len); + value = new BigInteger(1, magnitude); + } + catch (Exception e) + { + RadiusLog.warn("Error during bean initialization [InitializingBean]", e); + } + } + + public void setValue(String value) + { + setValue(new BigInteger(value)); + } + + public BigInteger getValue() + { + return value; + } + + public String toString() + { + if (value != null) + { + return value.toString(); + } + return "[Bad Integer64 Value]"; + } + + public String toXMLString() + { + StringBuffer sb = new StringBuffer(); + sb.append(""); + if (value != null) + { + sb.append(value.toString()); + } + sb.append(""); + return sb.toString(); + } + + public Serializable getValueObject() + { + return value; + } + + public void setValueObject(Serializable o) + { + if (o instanceof BigInteger) + { + setValue((BigInteger) o); + } + else if (o instanceof String) + { + setValue(new BigInteger((String) o)); + } + else if (o instanceof byte[]) + { + setValue(new BigInteger((byte[]) o)); + } + } + + public void setValue(BigInteger value) throws NumberFormatException + { + if (!isValid(value)) throw new NumberFormatException("[bad integer64 value: " + String.valueOf(value) + "]"); + this.value = value; + } + + public static boolean isValid(BigInteger value) + { + return value.signum() >= 0 && value.bitLength() <= 64; + } + +} diff --git a/freeradius/rlm_jradius/Makefile b/freeradius/rlm_jradius/Makefile deleted file mode 100644 index 53295c5..0000000 --- a/freeradius/rlm_jradius/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -TARGET = rlm_jradius -SRCS = rlm_jradius.c -HEADERS = -RLM_CFLAGS = -RLM_LIBS = - -## this uses the RLM_CFLAGS and RLM_LIBS and SRCS defs to make TARGET. -include ../rules.mak - -$(STATIC_OBJS): $(HEADERS) - -$(DYNAMIC_OBJS): $(HEADERS) - diff --git a/freeradius/rlm_jradius/all.mk b/freeradius/rlm_jradius/all.mk new file mode 100644 index 0000000..4d0d795 --- /dev/null +++ b/freeradius/rlm_jradius/all.mk @@ -0,0 +1,11 @@ +TARGETNAME := rlm_jradius + +ifneq "$(TARGETNAME)" "" +TARGET := $(TARGETNAME).a +endif + +SOURCES := $(TARGETNAME).c + +SRC_CFLAGS := +SRC_CFLAGS += -DEXTENDED_FMT +TGT_LDLIBS := \ No newline at end of file diff --git a/freeradius/rlm_jradius/configure b/freeradius/rlm_jradius/configure deleted file mode 100755 index d015c2f..0000000 --- a/freeradius/rlm_jradius/configure +++ /dev/null @@ -1,4 +0,0 @@ -#! /bin/sh - -echo "did nothing" - diff --git a/freeradius/rlm_jradius/rlm_jradius.c b/freeradius/rlm_jradius/rlm_jradius.c index 3e5617a..f84cd4c 100644 --- a/freeradius/rlm_jradius/rlm_jradius.c +++ b/freeradius/rlm_jradius/rlm_jradius.c @@ -1,31 +1,44 @@ +/* + * This program is is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + /** - * rlm_jradius - The FreeRADIUS JRadius Server Module - * Copyright (C) 2004-2006 PicoPoint, B.V. - * Copyright (c) 2007-2010 Coova Technologies, LLC + * $Id$ * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. + * @file rlm_jradius.c + * @brief rlm_jradius - The FreeRADIUS JRadius Server Module * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * This module is used to connect FreeRADIUS to the JRadius server. - * JRadius is a Java RADIUS client and server framework, see doc/rlm_jradius - * and http://www.coova.org/JRadius for more information. + * Copyright (C) 2004-2006 PicoPoint, B.V. + * Copyright (c) 2007-2010 Coova Technologies, LLC + * + * This module is used to connect FreeRADIUS to the JRadius server. + * JRadius is a Java RADIUS client and server framework, see doc/rlm_jradius + * and http://www.coova.org/JRadius for more information. * - * Author(s): David Bird + * Author(s): David Bird * - * Connection pooling code based on rlm_sql, see rlm_sql/sql.c for copyright and license. + * Connection pooling code based on rlm_sql, see rlm_sql/sql.c for copyright and license. */ +#include +#include +#include +#include +#include +#include + #include #include #include @@ -34,15 +47,6 @@ #include #include -#include -RCSID("$Id$") - -#include -#include -#include -#include -#include - #ifdef HAVE_PTHREAD_H #include #endif @@ -75,19 +79,23 @@ static const int JRADIUS_send_coa = 10; #define LOG_PREFIX "rlm_jradius: " #define MAX_HOSTS 4 -typedef struct _byte_array { - unsigned int size; - unsigned int pos; - unsigned int left; - unsigned char * b; -} byte_array; +#define VENDOR_ID(x) (((x) >> 16) & 0xffff) +#define ATTRIBUTE_ID(x) ((x) & 0xffff) +#define ATTRIBUTE_TYPE(h,l) ( ((h) << 16) | ((l) & 0xffff) ) + +typedef struct byte_array +{ + unsigned int size; + unsigned int pos; + unsigned int left; + unsigned char *b; +} byte_array_t; typedef struct jradius_socket { int id; #ifdef HAVE_PTHREAD_H pthread_mutex_t mutex; #endif - struct jradius_socket *next; enum { is_connected, not_connected } state; @@ -95,49 +103,52 @@ typedef struct jradius_socket { int sock; } con; - byte_array * ba; -} JRSOCK; - -typedef struct jradius_inst { - time_t connect_after; - JRSOCK * sock_pool; - JRSOCK * last_used; - - char * name; - char * host [MAX_HOSTS]; - uint32_t ipaddr [MAX_HOSTS]; - int port [MAX_HOSTS]; - int timeout; - int read_timeout; - int write_timeout; - int allow_codechange; - int allow_idchange; - int onfail; - char * onfail_s; - int keepalive; - int jrsock_cnt; -} JRADIUS; - -static CONF_PARSER module_config[] = { - { "name", PW_TYPE_STRING_PTR, offsetof(JRADIUS, name), NULL, "localhost"}, - { "primary", PW_TYPE_STRING_PTR, offsetof(JRADIUS, host[0]), NULL, "localhost"}, - { "secondary", PW_TYPE_STRING_PTR, offsetof(JRADIUS, host[1]), NULL, NULL}, - { "tertiary", PW_TYPE_STRING_PTR, offsetof(JRADIUS, host[2]), NULL, NULL}, - { "timeout", PW_TYPE_INTEGER, offsetof(JRADIUS, timeout), NULL, "5"}, - { "read_timeout", PW_TYPE_INTEGER, offsetof(JRADIUS, read_timeout), NULL, "90"}, - { "write_timeout",PW_TYPE_INTEGER, offsetof(JRADIUS, write_timeout),NULL, "90"}, - { "onfail", PW_TYPE_STRING_PTR, offsetof(JRADIUS, onfail_s), NULL, NULL}, - { "keepalive", PW_TYPE_BOOLEAN, offsetof(JRADIUS, keepalive), NULL, "yes"}, - { "connections", PW_TYPE_INTEGER, offsetof(JRADIUS, jrsock_cnt), NULL, "8"}, - { "allow_codechange", PW_TYPE_BOOLEAN, offsetof(JRADIUS, allow_codechange), NULL, "no"}, - { "allow_idchange", PW_TYPE_BOOLEAN, offsetof(JRADIUS, allow_idchange), NULL, "no"}, - { NULL, -1, 0, NULL, NULL } + byte_array_t* ba; +} jradius_socket_t; + +typedef struct rlm_jradius { + time_t connect_after; + jradius_socket_t *socket_pool; + jradius_socket_t *last_socket_used; + + char const *name; + char const *host[MAX_HOSTS]; + + uint32_t ipaddr[MAX_HOSTS]; + int port[MAX_HOSTS]; + + uint32_t timeout; + uint32_t read_timeout; + uint32_t write_timeout; + + bool allow_codechange; + bool allow_idchange; + + int onfail; + char const *onfail_s; + + bool keepalive; + uint32_t socket_cnt; +} rlm_jradius_t; + +static const CONF_PARSER module_config[] = { + { "name", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_jradius_t, name), "localhost" }, + { "primary", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_jradius_t, host[0]), "localhost" }, + { "secondary", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_jradius_t, host[1]), NULL }, + { "tertiary", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_jradius_t, host[2]), NULL }, + { "timeout", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_jradius_t, timeout), "5" }, + { "read_timeout", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_jradius_t, read_timeout), "90" }, + { "write_timeout", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_jradius_t, write_timeout), "90" }, + { "onfail", FR_CONF_OFFSET(PW_TYPE_STRING, rlm_jradius_t, onfail_s), NULL }, + { "keepalive", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_jradius_t, keepalive), "yes" }, + { "connections", FR_CONF_OFFSET(PW_TYPE_INTEGER, rlm_jradius_t, socket_cnt), "8" }, + { "allow_codechange", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_jradius_t, allow_codechange), "no" }, + { "allow_idchange", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, rlm_jradius_t, allow_idchange), "no" }, + CONF_PARSER_TERMINATOR }; -static int -sock_read(JRADIUS * inst, JRSOCK *jrsock, uint8_t *b, size_t blen) { +static int sock_read(rlm_jradius_t *inst, jradius_socket_t *jrsock, uint8_t *b, size_t blen) { if (jrsock->ba) { - size_t idx = 0; while (idx < blen) { @@ -147,7 +158,6 @@ sock_read(JRADIUS * inst, JRSOCK *jrsock, uint8_t *b, size_t blen) { } return blen; - } else { int fd = jrsock->con.sock; int timeout = inst->read_timeout; @@ -155,9 +165,9 @@ sock_read(JRADIUS * inst, JRSOCK *jrsock, uint8_t *b, size_t blen) { ssize_t c; size_t recd = 0; fd_set fds; - + while (recd < blen) { - + tv.tv_sec = timeout; tv.tv_usec = 0; @@ -165,28 +175,27 @@ sock_read(JRADIUS * inst, JRSOCK *jrsock, uint8_t *b, size_t blen) { FD_SET(fd, &fds); if (select(fd + 1, &fds, (fd_set *) 0, (fd_set *) 0, &tv) == -1) - return -1; + return -1; if (FD_ISSET(fd, &fds)) -#ifdef WIN32 - c = recv(fd, b + recd, blen-recd, 0); -#else - c = read(fd, b + recd, blen-recd); -#endif + #ifdef WIN32 + c = recv(fd, b + recd, blen-recd, 0); + #else + c = read(fd, b + recd, blen-recd); + #endif else - return -1; - + return -1; + if (c <= 0) return -1; recd += c; } - + if (recd < blen) return -1; return recd; } } -static int -sock_write(JRADIUS * inst, JRSOCK *jrsock, char *b, size_t blen) { +static int sock_write(rlm_jradius_t *inst, jradius_socket_t *jrsock, char *b, size_t blen) { int fd = jrsock->con.sock; int timeout = inst->write_timeout; struct timeval tv; @@ -222,7 +231,8 @@ sock_write(JRADIUS * inst, JRSOCK *jrsock, char *b, size_t blen) { return sent; } -static int connect_socket(JRSOCK *jrsock, JRADIUS *inst) { +static int connect_socket(rlm_jradius_t *inst, jradius_socket_t *jrsock) +{ struct sockaddr_in local_addr, serv_addr; int i, connected = 0; char buff[128]; @@ -237,16 +247,15 @@ static int connect_socket(JRSOCK *jrsock, JRADIUS *inst) { * Allocate a TCP socket */ if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - radlog(L_ERR, LOG_PREFIX "could not allocate TCP socket"); + ERROR(LOG_PREFIX "could not allocate TCP socket"); goto failed; } /* * If we have a timeout value set, make the socket non-blocking */ - if (inst->timeout > 0 && - fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK) == -1) { - radlog(L_ERR, LOG_PREFIX "could not set non-blocking on socket"); + if (inst->timeout > 0 && fcntl(sock, F_SETFL, fcntl(sock, F_GETFL, 0) | O_NONBLOCK) == -1) { + ERROR(LOG_PREFIX "could not set non-blocking on socket"); goto failed; } @@ -259,7 +268,7 @@ static int connect_socket(JRSOCK *jrsock, JRADIUS *inst) { local_addr.sin_port = htons(0); if (bind(sock, (struct sockaddr *) &local_addr, sizeof(local_addr)) < 0) { - radlog(L_ERR, LOG_PREFIX "could not locally bind TCP socket"); + ERROR(LOG_PREFIX "could not locally bind TCP socket"); goto failed; } @@ -273,36 +282,35 @@ static int connect_socket(JRSOCK *jrsock, JRADIUS *inst) { if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { if (inst->timeout > 0 && (errno == EINPROGRESS || errno == EWOULDBLOCK)) { - /* - * Wait to see if non-blocking socket connects or times-out - */ - struct pollfd pfd; - memset(&pfd, 0, sizeof(pfd)); - - pfd.fd = sock; - pfd.events = POLLOUT; - - if (poll(&pfd, 1, inst->timeout * 1000) == 1 && pfd.revents) { - /* - * Lets make absolutely sure we are connected - */ - struct sockaddr_in sa; - unsigned int salen = sizeof(sa); - if (getpeername(sock, (struct sockaddr *) &sa, &salen) != -1) { - /* - * CONNECTED! break out of for-loop - */ - connected = 1; - break; - } - } + /* + * Wait to see if non-blocking socket connects or times-out + */ + struct pollfd pfd; + memset(&pfd, 0, sizeof(pfd)); + + pfd.fd = sock; + pfd.events = POLLOUT; + + if (poll(&pfd, 1, inst->timeout * 1000) == 1 && pfd.revents) { + /* + * Lets make absolutely sure we are connected + */ + struct sockaddr_in sa; + unsigned int salen = sizeof(sa); + if (getpeername(sock, (struct sockaddr *) &sa, &salen) != -1) { + /* + * CONNECTED! break out of for-loop + */ + connected = 1; + break; + } + } } /* * Timed-out */ - radlog(L_ERR, LOG_PREFIX "could not connect to %s:%d", - ip_ntoa(buff, inst->ipaddr[i]), inst->port[i]); + ERROR(LOG_PREFIX "could not connect to %s:%d", ip_ntoa(buff, inst->ipaddr[i]), inst->port[i]); } else { /* @@ -319,7 +327,7 @@ static int connect_socket(JRSOCK *jrsock, JRADIUS *inst) { } if (!connected) { - radlog(L_ERR, LOG_PREFIX "could not find any jradius server!"); + ERROR(LOG_PREFIX "could not find any jradius server!"); goto failed; } @@ -330,7 +338,7 @@ static int connect_socket(JRSOCK *jrsock, JRADIUS *inst) { radlog(L_ERR, LOG_PREFIX "could not set blocking on socket"); goto failed; } - */ + */ jrsock->state = is_connected; jrsock->con.sock = sock; @@ -339,11 +347,12 @@ static int connect_socket(JRSOCK *jrsock, JRADIUS *inst) { failed: if (sock > 0) { shutdown(sock, 2); close(sock); } jrsock->state = not_connected; - return 0; + return 0; } -static inline void close_socket(UNUSED JRADIUS * inst, JRSOCK *jrsock) { - radlog(L_INFO, "rlm_jradius: Closing JRadius connection %d", jrsock->id); +static inline void close_socket(UNUSED rlm_jradius_t *inst, jradius_socket_t *jrsock) +{ + INFO(LOG_PREFIX "Closing JRadius connection %d", jrsock->id); if (jrsock->con.sock > 0) { shutdown(jrsock->con.sock, 2); close(jrsock->con.sock); @@ -352,7 +361,7 @@ static inline void close_socket(UNUSED JRADIUS * inst, JRSOCK *jrsock) { jrsock->con.sock = 0; } -static inline void free_socket(JRADIUS * inst, JRSOCK *jrsock) { +static inline void free_socket(rlm_jradius_t *inst, jradius_socket_t *jrsock) { close_socket(inst, jrsock); if (inst->keepalive) { #ifdef HAVE_PTHREAD_H @@ -362,16 +371,17 @@ static inline void free_socket(JRADIUS * inst, JRSOCK *jrsock) { } } -static int init_socketpool(JRADIUS * inst) { - int i, rcode; - int success = 0; - JRSOCK *jrsock; +static int init_socketpool(rlm_jradius_t *inst) +{ + uint32_t i; + int rcode, success = 0; + jradius_socket_t *jrsock; inst->connect_after = 0; - inst->sock_pool = NULL; + inst->socket_pool = NULL; - for (i = 0; i < inst->jrsock_cnt; i++) { - radlog(L_INFO, "rlm_jradius: starting JRadius connection %d", i); + for (i = 0; i < inst->socket_cnt; i++) { + INFO(LOG_PREFIX "starting JRadius connection %d", i); if ((jrsock = rad_malloc(sizeof(*jrsock))) == 0) return -1; @@ -382,46 +392,48 @@ static int init_socketpool(JRADIUS * inst) { #ifdef HAVE_PTHREAD_H rcode = pthread_mutex_init(&jrsock->mutex,NULL); if (rcode != 0) { - radlog(L_ERR, "rlm_jradius: Failed to init lock: %s", strerror(errno)); + ERROR(LOG_PREFIX "Failed to init lock: %s", strerror(errno)); return 0; } #endif if (time(NULL) > inst->connect_after) - if (connect_socket(jrsock, inst)) - success = 1; + if (connect_socket(inst, jrsock)) + success = 1; - jrsock->next = inst->sock_pool; - inst->sock_pool = jrsock; + jrsock->next = inst->socket_pool; + inst->socket_pool = jrsock; } - inst->last_used = NULL; + inst->last_socket_used = NULL; if (!success) { - radlog(L_DBG, "rlm_jradius: Failed to connect to JRadius server."); + DEBUG(LOG_PREFIX "Failed to connect to JRadius server."); } return 1; } -static void free_socketpool(JRADIUS * inst) { - JRSOCK *cur; - JRSOCK *next; +static void free_socketpool(rlm_jradius_t *inst) +{ + jradius_socket_t *cur; + jradius_socket_t *next; - for (cur = inst->sock_pool; cur; cur = next) { + for (cur = inst->socket_pool; cur; cur = next) { next = cur->next; free_socket(inst, cur); } - inst->sock_pool = NULL; + inst->socket_pool = NULL; } -static JRSOCK * get_socket(JRADIUS * inst) { - JRSOCK *cur, *start; +static jradius_socket_t* get_socket(rlm_jradius_t *inst) +{ + jradius_socket_t *cur, *start; int tried_to_connect = 0; int unconnected = 0; - start = inst->last_used; - if (!start) start = inst->sock_pool; + start = inst->last_socket_used; + if (!start) start = inst->socket_pool; cur = start; @@ -433,13 +445,13 @@ static JRSOCK * get_socket(JRADIUS * inst) { #endif if ((cur->state == not_connected) && (time(NULL) > inst->connect_after)) { - radlog(L_INFO, "rlm_jradius: Trying to (re)connect unconnected handle %d", cur->id); + INFO(LOG_PREFIX "Trying to (re)connect unconnected handle %d", cur->id); tried_to_connect++; - connect_socket(cur, inst); + connect_socket(inst, cur); } if (cur->state == not_connected) { - radlog(L_DBG, "rlm_jradius: Ignoring unconnected handle %d", cur->id); + DEBUG(LOG_PREFIX "Ignoring unconnected handle %d", cur->id); unconnected++; #ifdef HAVE_PTHREAD_H pthread_mutex_unlock(&cur->mutex); @@ -447,54 +459,46 @@ static JRSOCK * get_socket(JRADIUS * inst) { goto next; } - radlog(L_DBG, "rlm_jradius: Reserving JRadius socket id: %d", cur->id); + DEBUG(LOG_PREFIX "Reserving JRadius socket id: %d", cur->id); if (unconnected != 0 || tried_to_connect != 0) { - radlog(L_INFO, "rlm_jradius: got socket %d after skipping %d unconnected handles, tried to reconnect %d though", - cur->id, unconnected, tried_to_connect); + INFO(LOG_PREFIX "got socket %d after skipping %d unconnected handles, tried to reconnect %d though", + cur->id, unconnected, tried_to_connect); } - inst->last_used = cur->next; + inst->last_socket_used = cur->next; return cur; next: cur = cur->next; - if (!cur) cur = inst->sock_pool; + if (!cur) cur = inst->socket_pool; if (cur == start) break; } - radlog(L_INFO, "rlm_jradius: There are no sockets to use! skipped %d, tried to connect %d", - unconnected, tried_to_connect); + INFO(LOG_PREFIX "There are no sockets to use! skipped %d, tried to connect %d", unconnected, tried_to_connect); return NULL; } -static inline int release_socket(UNUSED JRADIUS * inst, JRSOCK * jrsock) { +static inline int release_socket(UNUSED rlm_jradius_t *inst, jradius_socket_t *jrsock) +{ #ifdef HAVE_PTHREAD_H pthread_mutex_unlock(&jrsock->mutex); #endif - radlog(L_DBG, "rlm_jradius: Released JRadius socket id: %d", jrsock->id); - + DEBUG(LOG_PREFIX "Released JRadius socket id: %d", jrsock->id); return 0; } - /* * Initialize the jradius module */ -static int jradius_instantiate(CONF_SECTION *conf, void **instance) { - JRADIUS *inst = (JRADIUS *) instance; - char host[128], b[128], *h; +static int mod_instantiate(UNUSED CONF_SECTION *conf, void *instance) +{ + rlm_jradius_t *inst = (rlm_jradius_t *) instance; + char host[128], b[128]; + const char *h; int i, p, idx, port; - inst = rad_malloc(sizeof(JRADIUS)); - memset(inst, 0, sizeof(JRADIUS)); - - if (cf_section_parse(conf, inst, module_config) < 0) { - free(inst); - return -1; - } - for (i = 0, idx = 0; i < MAX_HOSTS; i++) { if (inst->host[i] && strlen(inst->host[i]) < sizeof(host)) { h = inst->host[i]; @@ -504,18 +508,20 @@ static int jradius_instantiate(CONF_SECTION *conf, void **instance) { if (sscanf(b, "%[^:]:%d", host, &port) == 2) { h = host; p = port; } if (h) { - fr_ipaddr_t ipaddr; - if (ip_hton(h, AF_INET, &ipaddr) < 0) { - radlog(L_ERR, "Can't find IP address for host %s", h); - continue; - } - if ((inst->ipaddr[idx] = ipaddr.ipaddr.ip4addr.s_addr) != htonl(INADDR_NONE)) { - inst->port[idx] = p; - radlog(L_INFO, LOG_PREFIX "configuring jradius server %s:%d", h, p); - idx++; - } else { - radlog(L_ERR, LOG_PREFIX "invalid jradius server %s", h); - } + fr_ipaddr_t ipaddr; + + if (ip_hton(&ipaddr, AF_INET, h, false) < 0) { + ERROR(LOG_PREFIX "can't find IP address for host %s", h); + continue; + } + + if ((inst->ipaddr[idx] = ipaddr.ipaddr.ip4addr.s_addr) != htonl(INADDR_NONE)) { + inst->port[idx] = p; + INFO(LOG_PREFIX "configuring jradius server %s:%d", h, p); + idx++; + } else { + ERROR(LOG_PREFIX "invalid jradius server %s", h); + } } } } @@ -529,18 +535,17 @@ static int jradius_instantiate(CONF_SECTION *conf, void **instance) { else if (!strcmp(inst->onfail_s, "REJECT")) inst->onfail = RLM_MODULE_REJECT; else if (!strcmp(inst->onfail_s, "OK")) inst->onfail = RLM_MODULE_OK; else if (!strcmp(inst->onfail_s, "FAIL")) inst->onfail = RLM_MODULE_FAIL; - else radlog(L_ERR, LOG_PREFIX "invalid jradius 'onfail' state %s", inst->onfail_s); + else ERROR(LOG_PREFIX "invalid jradius 'onfail' state %s", inst->onfail_s); } - *instance = inst; - return 0; } /* * Initialize a byte array buffer structure */ -static inline void init_byte_array(byte_array * ba, unsigned char *b, int blen) { +static inline void init_byte_array(byte_array_t *ba, unsigned char *b, int blen) +{ ba->b = b; ba->size = ba->left = blen; ba->pos = 0; @@ -549,7 +554,8 @@ static inline void init_byte_array(byte_array * ba, unsigned char *b, int blen) /* * Pack a single byte into a byte array buffer */ -static inline int pack_byte(byte_array * ba, unsigned char c) { +static inline int pack_byte(byte_array_t *ba, unsigned char c) +{ if (ba->left < 1) return -1; ba->b[ba->pos] = c; @@ -562,7 +568,8 @@ static inline int pack_byte(byte_array * ba, unsigned char c) { /* * Pack an array of bytes into a byte array buffer */ -static inline int pack_bytes(byte_array * ba, unsigned char *d, unsigned int dlen) { +static inline int pack_bytes(byte_array_t *ba, unsigned char *d, unsigned int dlen) +{ if (ba->left < dlen) return -1; memcpy((void *)(ba->b + ba->pos), d, dlen); @@ -572,10 +579,27 @@ static inline int pack_bytes(byte_array * ba, unsigned char *d, unsigned int dle return 0; } +/* + * Pack an integer64 into a byte array buffer (adjusting for byte-order) + */ +static inline int pack_uint64(byte_array_t *ba, uint64_t i) +{ + if (ba->left < 8) return -1; + + i = htonll(i); + + memcpy((void *)(ba->b + ba->pos), (void *)&i, 8); + ba->pos += 8; + ba->left -= 8; + + return 0; +} + /* * Pack an integer into a byte array buffer (adjusting for byte-order) */ -static inline int pack_uint32(byte_array * ba, uint32_t i) { +static inline int pack_uint32(byte_array_t *ba, uint32_t i) +{ if (ba->left < 4) return -1; i = htonl(i); @@ -590,7 +614,8 @@ static inline int pack_uint32(byte_array * ba, uint32_t i) { /* * Pack a short into a byte array buffer (adjusting for byte-order) */ -static inline int pack_uint16(byte_array * ba, uint16_t i) { +static inline int pack_uint16(byte_array_t *ba, uint16_t i) +{ if (ba->left < 2) return -1; i = htons(i); @@ -605,7 +630,8 @@ static inline int pack_uint16(byte_array * ba, uint16_t i) { /* * Pack a byte into a byte array buffer */ -static inline int pack_uint8(byte_array * ba, uint8_t i) { +static inline int pack_uint8(byte_array_t *ba, uint8_t i) +{ if (ba->left < 1) return -1; memcpy((void *)(ba->b + ba->pos), (void *)&i, 1); @@ -618,7 +644,8 @@ static inline int pack_uint8(byte_array * ba, uint8_t i) { /* * Pack one byte array buffer into another byte array buffer */ -static inline int pack_array(byte_array * ba, byte_array * a) { +static inline int pack_array(byte_array_t *ba, byte_array_t * a) +{ if (ba->left < a->pos) return -1; memcpy((void *)(ba->b + ba->pos), (void *)a->b, a->pos); @@ -631,39 +658,83 @@ static inline int pack_array(byte_array * ba, byte_array * a) { /* * Pack radius attributes into a byte array buffer */ -static inline int pack_vps(byte_array * ba, VALUE_PAIR * vps) { +static inline int pack_vps(byte_array_t *ba, VALUE_PAIR *vps) +{ uint32_t i; - VALUE_PAIR * vp; + VALUE_PAIR *vp; + DICT_ATTR const *da; for (vp = vps; vp != NULL; vp = vp->next) { + da = vp->da; + + DEBUG(LOG_PREFIX "packing attribute %s (vendor: %d, id: %d; len: %zu)", da->name, da->vendor, da->attr, vp->vp_length); - radlog(L_DBG, LOG_PREFIX "packing attribute %s (type: %d; len: %d)", - vp->name, vp->attribute, vp->length); - - i = vp->attribute; /* element is int, not uint32_t */ + i = ATTRIBUTE_TYPE(da->vendor, da->attr); if (pack_uint32(ba, i) == -1) return -1; - i = vp->length; + + i = vp->vp_length; if (pack_uint32(ba, i) == -1) return -1; - i = vp->operator; + + i = vp->op; if (pack_uint32(ba, i) == -1) return -1; - switch (vp->type) { + switch (da->type) { case PW_TYPE_BYTE: - if (pack_uint8(ba, vp->lvalue) == -1) return -1; - break; + if (pack_uint8(ba, vp->vp_byte) == -1) return -1; + break; + case PW_TYPE_SHORT: - if (pack_uint16(ba, vp->lvalue) == -1) return -1; - break; + if (pack_uint16(ba, vp->vp_short) == -1) return -1; + break; + case PW_TYPE_INTEGER: - case PW_TYPE_DATE: - if (pack_uint32(ba, vp->lvalue) == -1) return -1; - break; - case PW_TYPE_IPADDR: - if (pack_bytes(ba, (void *)&vp->vp_ipaddr, vp->length) == -1) return -1; - break; - default: - if (pack_bytes(ba, (void *)vp->vp_octets, vp->length) == -1) return -1; - break; + case PW_TYPE_DATE: + if (pack_uint32(ba, vp->vp_integer) == -1) return -1; + break; + + case PW_TYPE_SIGNED: + if (pack_uint32(ba, vp->vp_signed) == -1) return -1; + break; + + case PW_TYPE_INTEGER64: + if (pack_uint64(ba, vp->vp_integer64) == -1) return -1; + break; + + case PW_TYPE_ETHERNET: + if (pack_bytes(ba, (void*) vp->vp_ether, vp->length) == -1) return -1; + break; + + case PW_TYPE_IPV4_ADDR: + if (pack_bytes(ba, (void*) &vp->vp_ipaddr, vp->length) == -1) return -1; + break; + + case PW_TYPE_IPV6_ADDR: + if (pack_bytes(ba, (void*) &vp->vp_ipv6addr, vp->length) == -1) return -1; + break; + + case PW_TYPE_IPV4_PREFIX: + if (pack_bytes(ba, (void*) vp->vp_ipv4prefix, vp->length) == -1) return -1; + break; + + case PW_TYPE_IPV6_PREFIX: + if (pack_bytes(ba, (void*) vp->vp_ipv6prefix, vp->length) == -1) return -1; + break; + + case PW_TYPE_IFID: + if (pack_bytes(ba, (void*) vp->vp_ifid, vp->length) == -1) return -1; + break; + + case PW_TYPE_ABINARY: + if (pack_bytes(ba, (void*) vp->vp_filter, vp->length) == -1) return -1; + break; + + case PW_TYPE_STRING: + if (pack_bytes(ba, (void*) vp->vp_strvalue, vp->length) == -1) return -1; + break; + + default: + if (pack_bytes(ba, (void*) vp->vp_octets, vp->length) == -1) return -1; + break; } } @@ -673,16 +744,16 @@ static inline int pack_vps(byte_array * ba, VALUE_PAIR * vps) { /* * Pack a radius packet into a byte array buffer */ -static inline int pack_packet(byte_array * ba, RADIUS_PACKET * p) { - /*unsigned char code = p->code;*/ +static inline int pack_packet(byte_array_t *ba, RADIUS_PACKET *p) +{ unsigned char buff[HALF_MESSAGE_LEN]; - byte_array pba; + byte_array_t pba; init_byte_array(&pba, buff, sizeof(buff)); if (pack_vps(&pba, p->vps) == -1) return -1; - radlog(L_DBG, LOG_PREFIX "packing packet with code: %d (attr length: %d)", p->code, pba.pos); + DEBUG(LOG_PREFIX "packing packet with code: %d (attr length: %d)", p->code, pba.pos); #ifdef LEGACY_FMT if (pack_byte(ba, p->code) == -1) return -1; @@ -692,19 +763,21 @@ static inline int pack_packet(byte_array * ba, RADIUS_PACKET * p) { if (pack_uint32(ba, p->id) == -1) return -1; #endif if (pack_uint32(ba, pba.pos) == -1) return -1; + if (pba.pos == 0) return 0; if (pack_array(ba, &pba) == -1) return -1; return 0; } -static inline int pack_request(byte_array * ba, REQUEST *r) { +static inline int pack_request(byte_array_t *ba, REQUEST *r) +{ unsigned char buff[HALF_MESSAGE_LEN]; - byte_array pba; + byte_array_t pba; init_byte_array(&pba, buff, sizeof(buff)); - if (pack_vps(&pba, r->config_items) == -1) return -1; + if (pack_vps(&pba, r->config) == -1) return -1; if (pack_uint32(ba, pba.pos) == -1) return -1; if (pba.pos == 0) return 0; if (pack_array(ba, &pba) == -1) return -1; @@ -712,37 +785,47 @@ static inline int pack_request(byte_array * ba, REQUEST *r) { return 0; } -static inline uint32_t unpack_uint32(unsigned char *c) { +static inline uint64_t unpack_uint64(unsigned char *c) +{ + uint64_t ii; + memcpy((void *)&ii, c, 8); + return ntohll(ii); +} + +static inline uint32_t unpack_uint32(unsigned char *c) +{ uint32_t ii; memcpy((void *)&ii, c, 4); return ntohl(ii); } -static inline uint16_t unpack_uint16(unsigned char *c) { +static inline uint16_t unpack_uint16(unsigned char *c) +{ uint16_t ii; memcpy((void *)&ii, c, 2); return ntohs(ii); } -static inline uint8_t unpack_uint8(unsigned char *c) { +static inline uint8_t unpack_uint8(unsigned char *c) +{ uint8_t ii; memcpy((void *)&ii, c, 1); return ii; } - - /* * Read a single byte from socket */ -static inline int read_byte(JRADIUS *inst, JRSOCK *jrsock, uint8_t *b) { +static inline int read_byte(rlm_jradius_t *inst, jradius_socket_t *jrsock, uint8_t *b) +{ return (sock_read(inst, jrsock, b, 1) == 1) ? 0 : -1; } /* * Read an integer from the socket (adjusting for byte-order) */ -static inline int read_uint32(JRADIUS *inst, JRSOCK *jrsock, uint32_t *i) { +static inline int read_uint32(rlm_jradius_t *inst, jradius_socket_t *jrsock, uint32_t *i) +{ uint32_t ii; if (sock_read(inst, jrsock, (uint8_t *)&ii, 4) != 4) return -1; @@ -754,54 +837,67 @@ static inline int read_uint32(JRADIUS *inst, JRSOCK *jrsock, uint32_t *i) { /* * Read a value-pair list from the socket */ -static inline int read_vps(JRADIUS *inst, JRSOCK *jrsock, VALUE_PAIR **pl, int plen) { +static inline int read_vps(rlm_jradius_t *inst, jradius_socket_t *jrsock, void *ctx, VALUE_PAIR **vps, int vps_len) +{ VALUE_PAIR *vp; + DICT_ATTR *da; + unsigned char buff[MESSAGE_LEN]; uint32_t alen, atype, aop; int rlen = 0; - while (rlen < plen) { + while (rlen < vps_len) { if (read_uint32(inst, jrsock, &atype) == -1) return -1; rlen += 4; if (read_uint32(inst, jrsock, &alen) == -1) return -1; rlen += 4; if (read_uint32(inst, jrsock, &aop) == -1) return -1; rlen += 4; - radlog(L_DBG, LOG_PREFIX "reading attribute: type=%d; len=%d", atype, alen); + DEBUG(LOG_PREFIX "reading attribute: type=%d; len=%d", atype, alen); if (alen >= sizeof(buff)) { - radlog(L_ERR, LOG_PREFIX "packet value too large (len: %d)", alen); + ERROR(LOG_PREFIX "packet value too large (len: %d)", alen); return -1; } - if (sock_read(inst, jrsock, buff, alen) != (int)alen) return -1; rlen += alen; + if (sock_read(inst, jrsock, buff, alen) != (int) alen) return -1; rlen += alen; buff[alen]=0; /* * Create new attribute */ - vp = paircreate(atype, -1); - vp->operator = aop; + vp = fr_pair_afrom_num(ctx, ATTRIBUTE_ID(atype), VENDOR_ID(atype)); + DEBUG(LOG_PREFIX "attribute from dict: vendor=%d; id=%d", vp->da->vendor, vp->da->attr); + + if (!vp) { + ERROR(LOG_PREFIX "could not allocate attribute"); + return -1; + } + + vp->op = aop; + vp->vp_length = alen; - if (vp->type == -1) { + da = vp->da; + + if (da->type == PW_TYPE_INVALID) { /* * FreeRADIUS should know about the same attributes that JRadius knows */ - radlog(L_ERR, LOG_PREFIX "received attribute we do not recognize (type: %d)", atype); - pairbasicfree(vp); + ERROR(LOG_PREFIX "received attribute we do not recognize (type: %d)", atype); + fr_pair_list_free(&vp); continue; } - /* + /* * WiMAX combo-ip address * paircreate() cannot recognize the real type of the address. * ..ugly code... */ - if (vp->type==PW_TYPE_COMBO_IP) { - switch (alen) { + if (da->type == PW_TYPE_COMBO_IP_ADDR) { + switch (vp->vp_length) { case 4: - vp->type = PW_TYPE_IPADDR; + da->type = PW_TYPE_IPV4_ADDR; break; case 16: - vp->type = PW_TYPE_IPV6ADDR; + da->type = PW_TYPE_IPV6_ADDR; break; } } @@ -809,39 +905,88 @@ static inline int read_vps(JRADIUS *inst, JRSOCK *jrsock, VALUE_PAIR **pl, int p /* * Fill in the attribute value based on type */ - switch (vp->type) { - case PW_TYPE_BYTE: - vp->lvalue = unpack_uint8(buff); - vp->length = 1; - break; - - case PW_TYPE_SHORT: - vp->lvalue = unpack_uint16(buff); - vp->length = 2; - break; - - case PW_TYPE_INTEGER: + switch (da->type) { + case PW_TYPE_BYTE: + if (vp->vp_length != 1) goto invalid_avp; + vp->vp_byte = unpack_uint8(buff); + break; + + case PW_TYPE_SHORT: + if (vp->vp_length != 2) goto invalid_avp; + vp->vp_short = unpack_uint16(buff); + break; + + case PW_TYPE_INTEGER: case PW_TYPE_DATE: - vp->lvalue = unpack_uint32(buff); - vp->length = 4; - break; + if (vp->vp_length != 4) goto invalid_avp; + vp->vp_integer = unpack_uint32(buff); + break; + + case PW_TYPE_SIGNED: + if (vp->vp_length != 4) goto invalid_avp; + vp->vp_signed = unpack_uint32(buff); + break; + + case PW_TYPE_INTEGER64: + if (vp->vp_length != 8) goto invalid_avp; + vp->vp_integer64 = unpack_uint64(buff); + break; + + case PW_TYPE_ETHERNET: + if (vp->vp_length != 6) goto invalid_avp; + memcpy(vp->vp_ether, buff, vp->vp_length); + break; + + case PW_TYPE_IPV4_ADDR: + if (vp->vp_length != 4) goto invalid_avp; + memcpy(&vp->vp_ipaddr, buff, vp->vp_length); + break; + + case PW_TYPE_IPV6_ADDR: + if (vp->vp_length != 16) goto invalid_avp; + memcpy(&vp->vp_ipv6addr, buff, vp->vp_length); + break; + + case PW_TYPE_IPV4_PREFIX: + if (vp->vp_length > 6) goto invalid_avp; + memcpy(vp->vp_ipv4prefix, buff, vp->vp_length); + break; + + case PW_TYPE_IPV6_PREFIX: + if (vp->vp_length > 18) goto invalid_avp; + memcpy(vp->vp_ipv6prefix, buff, vp->vp_length); + break; + + case PW_TYPE_IFID: + if (vp->vp_length != 8) goto invalid_avp; + memcpy(vp->vp_ifid, buff, vp->vp_length); + break; + + case PW_TYPE_ABINARY: + if (vp->vp_length > sizeof(vp->vp_filter)) { + vp->vp_length = sizeof(vp->vp_filter); + } + memcpy(vp->vp_filter, buff, vp->vp_length); + break; - case PW_TYPE_IPADDR: - memcpy((void *)&vp->vp_ipaddr, buff, 4); - vp->length = 4; - break; + case PW_TYPE_STRING: + fr_pair_value_bstrncpy(vp, buff, vp->vp_length); + break; default: - if (alen >= sizeof(vp->vp_octets)) alen = sizeof(vp->vp_octets) - 1; - memcpy((void *)vp->vp_octets, buff, alen); - vp->length = alen; - break; - } - - /* - * Add the attribute to the packet - */ - pairadd(pl, vp); + fr_pair_value_memcpy(vp, buff, vp->vp_length); + break; + + invalid_avp: + ERROR(LOG_PREFIX "ignoring received attribute with invalid length: type=%d; len=%d", da->type, vp->vp_length); + fr_pair_list_free(&vp); + continue; + } + + /* + * Add the attribute to the packet + */ + fr_pair_add(vps, vp); } return rlen; @@ -850,17 +995,21 @@ static inline int read_vps(JRADIUS *inst, JRSOCK *jrsock, VALUE_PAIR **pl, int p /* * Read a radius packet from the socket */ -static inline int read_packet(JRADIUS * inst, JRSOCK *jrsock, RADIUS_PACKET *p) { +static inline int read_packet(rlm_jradius_t * inst, jradius_socket_t *jrsock, RADIUS_PACKET *p) +{ uint32_t code; uint32_t id; uint32_t plen; #ifdef LEGACY_FMT - { uint8_t c = 0; - if (read_byte(inst, jrsock, &c) == -1) return -1; - code = c; - if (read_byte(inst, jrsock, &c) == -1) return -1; - id = c; } + { + uint8_t c = 0; + if (read_byte(inst, jrsock, &c) == -1) return -1; + code = c; + + if (read_byte(inst, jrsock, &c) == -1) return -1; + id = c; + } #else if (read_uint32(inst, jrsock, &code) == -1) return -1; if (read_uint32(inst, jrsock, &id) == -1) return -1; @@ -868,69 +1017,71 @@ static inline int read_packet(JRADIUS * inst, JRSOCK *jrsock, RADIUS_PACKET *p) if (read_uint32(inst, jrsock, &plen) == -1) return -1; - radlog(L_DBG, LOG_PREFIX "reading packet: code=%d len=%d", (int)code, plen); + DEBUG(LOG_PREFIX "reading packet: code=%d len=%d", (int)code, plen); if (inst->allow_codechange) if (code != p->code) { - radlog(L_INFO, LOG_PREFIX "changing packet code from %d to %d", p->code, code); + INFO(LOG_PREFIX "changing packet code from %d to %d", p->code, code); p->code = code; } if (inst->allow_idchange) if ((int)id != p->id) { - radlog(L_INFO, LOG_PREFIX "changing packet id from %d to %d", p->id, id); + INFO(LOG_PREFIX "changing packet id from %d to %d", p->id, id); p->id = (int)id; } /* * Delete previous attribute list */ - pairfree(&p->vps); + fr_pair_list_free(&p->vps); if (plen == 0) return 0; - if (read_vps(inst, jrsock, &p->vps, plen) == -1) return -1; + if (read_vps(inst, jrsock, p, &p->vps, plen) == -1) return -1; return 0; } -static inline int read_request(JRADIUS *inst, JRSOCK *jrsock, REQUEST *p) +static inline int read_request(rlm_jradius_t *inst, jradius_socket_t *jrsock, REQUEST *p) { unsigned int plen; if (read_uint32(inst, jrsock, &plen) == -1) return -1; - radlog(L_DBG, LOG_PREFIX "reading request: config_item: len=%d", plen); + DEBUG(LOG_PREFIX "reading request: config_item: len=%d", plen); /* * Delete previous attribute list */ - pairfree(&p->config_items); + fr_pair_list_free(&p->config); if (plen == 0) return 0; - if (read_vps(inst, jrsock, &p->config_items, plen) == -1) return -1; + if (read_vps(inst, jrsock, p, &p->config, plen) == -1) return -1; return 0; } -static int rlm_jradius_call(char func, void *instance, REQUEST *req, int isproxy) +static int mod_jradius_call(char func, void *instance, REQUEST *req, int isproxy) { - JRADIUS * inst = instance; - RADIUS_PACKET * request = isproxy ? req->proxy : req->packet; - RADIUS_PACKET * reply = isproxy ? req->proxy_reply : req->reply; - JRSOCK * jrsock = 0; - JRSOCK sjrsock; + rlm_jradius_t *inst = instance; + + RADIUS_PACKET *request = isproxy ? req->proxy : req->packet; + RADIUS_PACKET *reply = isproxy ? req->proxy_reply : req->reply; + + jradius_socket_t *jrsock = 0; + jradius_socket_t sjrsock; int exitstatus = inst->onfail; unsigned char rcode, pcount; unsigned char buff[MESSAGE_LEN]; - byte_array ba; + byte_array_t ba; - char * n = inst->name; + char const *n = inst->name; unsigned int nlen = strlen(n); - const char * err = 0; + const char *err = 0; int rc, attempt2=0; uint32_t len = 0; @@ -956,7 +1107,7 @@ static int rlm_jradius_call(char func, void *instance, REQUEST *req, int isproxy /* * Create byte array to send to jradius */ - if ((rc = pack_uint32 (&ba, 0)) == -1) W_ERR("pack_uint32(0)"); + if ((rc = pack_uint32 (&ba, 0)) == -1) W_ERR("pack_uint32(0)"); if ((rc = pack_uint32 (&ba, nlen)) == -1) W_ERR("pack_uint32(nlen)"); if ((rc = pack_bytes (&ba, (void *)n, nlen)) == -1) W_ERR("pack_bytes(name)"); if ((rc = pack_byte (&ba, func)) == -1) W_ERR("pack_byte(fun)"); @@ -970,31 +1121,30 @@ static int rlm_jradius_call(char func, void *instance, REQUEST *req, int isproxy */ start_over: if (jrsock->state == not_connected) { - if (attempt2) radlog(L_ERR, LOG_PREFIX "reconnecting socket id %d", jrsock->id); - if (!connect_socket(jrsock, inst)) { - if (attempt2) radlog(L_ERR, LOG_PREFIX "could not reconnect socket %d, giving up", jrsock->id); + if (attempt2) ERROR(LOG_PREFIX "reconnecting socket id %d", jrsock->id); + if (!connect_socket(inst, jrsock)) { + if (attempt2) ERROR(LOG_PREFIX "could not reconnect socket %d, giving up", jrsock->id); goto cleanup; } } - radlog(L_DBG, LOG_PREFIX "sending %d bytes to socket %d", ba.pos, jrsock->id); + DEBUG(LOG_PREFIX "sending %d bytes to socket %d", ba.pos, jrsock->id); /* * Set the overall request length */ len = htonl(ba.pos); - memcpy((void *)ba.b, (void *)&len, 4); + memcpy((void*) ba.b, (void*) &len, 4); len = 0; jrsock->ba = 0; - if (sock_write(inst, jrsock, ba.b, ba.pos) != (int)ba.pos || - (rc = read_uint32(inst, jrsock, &len)) == -1) { + if (sock_write(inst, jrsock, ba.b, ba.pos) != (int)ba.pos || (rc = read_uint32(inst, jrsock, &len)) == -1) { /* * With an error on the write or the first read, try closing the socket * and reconnecting to see if that improves matters any (tries this only once) */ - radlog(L_ERR, LOG_PREFIX "error sending request with socket %d", jrsock->id); + ERROR(LOG_PREFIX "error sending request with socket %d", jrsock->id); if (!inst->keepalive || attempt2) W_ERR("socket_send/first_read"); close_socket(inst, jrsock); attempt2 = 1; @@ -1014,20 +1164,19 @@ static int rlm_jradius_call(char func, void *instance, REQUEST *req, int isproxy if (sock_read(inst, jrsock, buff, len) != len) goto parseerror; - radlog(L_DBG, "rlm_jradius: read %d bytes at once", (int) len); + DEBUG(LOG_PREFIX "read %d bytes at once", (int) len); init_byte_array(&ba, buff, sizeof(buff)); jrsock->ba = &ba; - /* * Read result */ - if ((rc = read_byte(inst, jrsock, &rcode)) == -1) R_ERR("read_byte(pcnt)"); + if ((rc = read_byte(inst, jrsock, &rcode)) == -1) R_ERR("read_byte(rcode)"); if ((rc = read_byte(inst, jrsock, &pcount)) == -1) R_ERR("read_byte(pcnt)"); - radlog(L_DBG, LOG_PREFIX "return code %d; receiving %d packets", (int)rcode, (int)pcount); + DEBUG(LOG_PREFIX "return code %d; receiving %d packets", (int)rcode, (int)pcount); if (pcount > 0 && request) if ((rc = read_packet (inst, jrsock, request)) == -1) R_ERR("read_packet(req)"); if (pcount > 1 && reply) if ((rc = read_packet (inst, jrsock, reply)) == -1) R_ERR("read_packet(rep)"); @@ -1039,13 +1188,13 @@ static int rlm_jradius_call(char func, void *instance, REQUEST *req, int isproxy * we need to reconfigure a few pointers in the REQUEST object */ if (req->username) { - req->username = pairfind(request->vps, PW_USER_NAME); + req->username = fr_pair_find_by_num(request->vps, PW_USER_NAME, 0, TAG_ANY); } if (req->password) { - req->password = pairfind(request->vps, PW_PASSWORD); - if (!req->password) req->password = pairfind(request->vps, PW_CHAP_PASSWORD); + req->password = fr_pair_find_by_num(request->vps, PW_USER_PASSWORD, 0, TAG_ANY); + if (!req->password) req->password = fr_pair_find_by_num(request->vps, PW_CHAP_PASSWORD, 0, TAG_ANY); } - + /* * All done, set return code and cleanup */ @@ -1053,12 +1202,12 @@ static int rlm_jradius_call(char func, void *instance, REQUEST *req, int isproxy goto cleanup; parseerror: - radlog(L_ERR, LOG_PREFIX "problem parsing the data [%s]",err); + ERROR(LOG_PREFIX "problem parsing the data [%s]",err); if (inst->keepalive) close_socket(inst, jrsock); goto cleanup; packerror: - radlog(L_ERR, LOG_PREFIX "problem packing the data[%s]",err); + ERROR(LOG_PREFIX "problem packing the data[%s]",err); if (inst->keepalive) close_socket(inst, jrsock); cleanup: @@ -1070,84 +1219,87 @@ static int rlm_jradius_call(char func, void *instance, REQUEST *req, int isproxy return exitstatus; } -static int jradius_authenticate(void *instance, REQUEST *request) +static rlm_rcode_t CC_HINT(nonnull) mod_authenticate(void *instance, REQUEST *request) { - return rlm_jradius_call(JRADIUS_authenticate, instance, request, 0); + return mod_jradius_call(JRADIUS_authenticate, instance, request, 0); } -static int jradius_authorize(void *instance, REQUEST *request) +static rlm_rcode_t CC_HINT(nonnull) mod_authorize(void *instance, REQUEST *request) { - return rlm_jradius_call(JRADIUS_authorize, instance, request, 0); + return mod_jradius_call(JRADIUS_authorize, instance, request, 0); } -static int jradius_preacct(void *instance, REQUEST *request) +static rlm_rcode_t CC_HINT(nonnull) mod_preacct(void *instance, REQUEST *request) { - return rlm_jradius_call(JRADIUS_preacct, instance, request, 0); + return mod_jradius_call(JRADIUS_preacct, instance, request, 0); } -static int jradius_accounting(void *instance, REQUEST *request) +static rlm_rcode_t CC_HINT(nonnull) mod_accounting(void *instance, REQUEST *request) { - return rlm_jradius_call(JRADIUS_accounting, instance, request, 0); + return mod_jradius_call(JRADIUS_accounting, instance, request, 0); } -static int jradius_checksimul(void *instance, REQUEST *request) +static rlm_rcode_t CC_HINT(nonnull) mod_checksimul(void *instance, REQUEST *request) { - return rlm_jradius_call(JRADIUS_checksimul, instance, request, 0); + return mod_jradius_call(JRADIUS_checksimul, instance, request, 0); } -static int jradius_pre_proxy(void *instance, REQUEST *request) +static rlm_rcode_t CC_HINT(nonnull) mod_pre_proxy(void *instance, REQUEST *request) { - return rlm_jradius_call(JRADIUS_pre_proxy, instance, request, 1); + return mod_jradius_call(JRADIUS_pre_proxy, instance, request, 1); } -static int jradius_post_proxy(void *instance, REQUEST *request) +static rlm_rcode_t CC_HINT(nonnull) mod_post_proxy(void *instance, REQUEST *request) { - return rlm_jradius_call(JRADIUS_post_proxy, instance, request, 1); + return mod_jradius_call(JRADIUS_post_proxy, instance, request, 1); } -static int jradius_post_auth(void *instance, REQUEST *request) +static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, REQUEST *request) { - return rlm_jradius_call(JRADIUS_post_auth, instance, request, 0); + return mod_jradius_call(JRADIUS_post_auth, instance, request, 0); } #ifdef WITH_COA -static int jradius_recv_coa(void *instance, REQUEST *request) +static rlm_rcode_t CC_HINT(nonnull) mod_recv_coa(void *instance, REQUEST *request) { - return rlm_jradius_call(JRADIUS_recv_coa, instance, request, 0); + return mod_jradius_call(JRADIUS_recv_coa, instance, request, 0); } -static int jradius_send_coa(void *instance, REQUEST *request) +static rlm_rcode_t CC_HINT(nonnull) mod_send_coa(void *instance, REQUEST *request) { - return rlm_jradius_call(JRADIUS_send_coa, instance, request, 0); + return mod_jradius_call(JRADIUS_send_coa, instance, request, 0); } #endif -static int jradius_detach(void *instance) +static int mod_detach(void *instance) { - JRADIUS *inst = (JRADIUS *) instance; + rlm_jradius_t *inst = (rlm_jradius_t *) instance; free_socketpool(inst); free(inst); return 0; } +extern module_t rlm_jradius; module_t rlm_jradius = { - RLM_MODULE_INIT, - "jradius", - RLM_TYPE_THREAD_SAFE, - jradius_instantiate, - jradius_detach, - { - jradius_authenticate, - jradius_authorize, - jradius_preacct, - jradius_accounting, - jradius_checksimul, - jradius_pre_proxy, - jradius_post_proxy, - jradius_post_auth + .magic = RLM_MODULE_INIT, + .name = "jradius", + .type = RLM_TYPE_THREAD_SAFE, + .inst_size = sizeof(rlm_jradius_t), + .config = module_config, + .instantiate = mod_instantiate, + .detach = mod_detach, + .methods = { + [MOD_AUTHENTICATE] = mod_authenticate, + [MOD_AUTHORIZE] = mod_authorize, + [MOD_PREACCT] = mod_preacct, + [MOD_ACCOUNTING] = mod_accounting, + [MOD_SESSION] = mod_checksimul, + [MOD_PRE_PROXY] = mod_pre_proxy, + [MOD_POST_PROXY] = mod_post_proxy, + [MOD_POST_AUTH] = mod_post_auth, #ifdef WITH_COA - , jradius_recv_coa, - jradius_send_coa -#endif - }, + [MOD_RECV_COA] = mod_recv_coa, + [MOD_SEND_COA] = mod_send_coa +#endif + } };