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
+ }
};