add radius_bind_{min,max} options
authorbodea <bodea>
Sat, 1 Jul 2006 12:40:10 +0000 (12:40 +0000)
committerbodea <bodea>
Sat, 1 Jul 2006 12:40:10 +0000 (12:40 +0000)
Changes
Docs/manual/manual.xml
Docs/startup-config.5
l2tpns.c
l2tpns.h
l2tpns.spec
radius.c

diff --git a/Changes b/Changes
index 319091e..f125011 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,4 +1,4 @@
-* Fri Jun 23 2006 Brendan O'Dea <bod@optus.net> 2.2.0
+* Sat Jul 1 2006 Brendan O'Dea <bod@optus.net> 2.2.0
 - Only poll clifd if successfully bound.
 - Add "Practical VPNs" document from Liran Tal as Docs/vpn .
 - Add Multilink support from Khaled Al Hamwi.
 - Only poll clifd if successfully bound.
 - Add "Practical VPNs" document from Liran Tal as Docs/vpn .
 - Add Multilink support from Khaled Al Hamwi.
@@ -8,6 +8,7 @@
 - Add session/idle timeouts (Graham Maltby).
 - Use result code AVP to set Acct-Terminate-Cause is disconnect cause
   AVP is not present.
 - Add session/idle timeouts (Graham Maltby).
 - Use result code AVP to set Acct-Terminate-Cause is disconnect cause
   AVP is not present.
+- Add radius_bind_{min,max} to simplify firewalling of RADIUS ports.
 
 * Tue Apr 18 2006 Brendan O'Dea <bod@optus.net> 2.1.18
 - Don't shutdown on TerminateReq, wait for CDN.
 
 * Tue Apr 18 2006 Brendan O'Dea <bod@optus.net> 2.1.18
 - Don't shutdown on TerminateReq, wait for CDN.
index cb26b54..38e7b81 100644 (file)
@@ -390,6 +390,19 @@ set boolean true
          </listitem>
        </varlistentry>
 
          </listitem>
        </varlistentry>
 
+       <varlistentry>
+         <term><literal>radius_bind_min</literal> (short)</term>
+         <term><literal>radius_bind_max</literal> (short)</term>
+         <listitem>
+           <para>
+             Define a port range in which to bind sockets used to
+             send and receive RADIUS packets.  Must be at least
+             RADIUS_FDS (64) wide.  Simplifies firewalling of RADIUS
+             ports (default: dynamically assigned).
+           </para>
+         </listitem>
+       </varlistentry>
+
        <varlistentry>
          <term><literal>radius_dae_port</literal> (short)</term>
          <listitem>
        <varlistentry>
          <term><literal>radius_dae_port</literal> (short)</term>
          <listitem>
index 174a253..6c2cf28 100644 (file)
@@ -2,7 +2,7 @@
 .de Id
 .ds Dt \\$4 \\$5
 ..
 .de Id
 .ds Dt \\$4 \\$5
 ..
-.Id $Id: startup-config.5,v 1.17 2006/04/27 14:38:14 bodea Exp $
+.Id $Id: startup-config.5,v 1.18 2006/07/01 12:40:17 bodea Exp $
 .TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
 .SH NAME
 startup\-config \- configuration file for l2tpns
 .TH STARTUP-CONFIG 5 "\*(Dt" L2TPNS "File Formats and Conventions"
 .SH NAME
 startup\-config \- configuration file for l2tpns
@@ -77,17 +77,17 @@ Number of configure requests to send before giving up (default: 10).
 Number of Configure-Nak requests to send before sending a
 Configure-Reject (default: 5).
 .TP
 Number of Configure-Nak requests to send before sending a
 Configure-Reject (default: 5).
 .TP
-.BR primary_dns , " secondary_dns"
+.BR primary_dns ", " secondary_dns
 Whenever a PPP connection is established, DNS servers will be sent to the
 user, both a primary and a secondary.  If either is set to 0.0.0.0, then that
 one will not be sent.
 .TP
 Whenever a PPP connection is established, DNS servers will be sent to the
 user, both a primary and a secondary.  If either is set to 0.0.0.0, then that
 one will not be sent.
 .TP
-.BR primary_radius , " secondary_radius"
+.BR primary_radius ", " secondary_radius
 Sets the RADIUS servers used for both authentication and accounting. 
 If the primary server does not respond, then the secondary RADIUS
 server will be tried.
 .TP
 Sets the RADIUS servers used for both authentication and accounting. 
 If the primary server does not respond, then the secondary RADIUS
 server will be tried.
 .TP
-.BR primary_radius_port , " secondary_radius_port"
+.BR primary_radius_port ", " secondary_radius_port
 Sets the authentication ports for the primary and secondary RADIUS
 servers.  The accounting port is one more than the authentication
 port.  If no ports are given, authentication defaults to 1645, and
 Sets the authentication ports for the primary and secondary RADIUS
 servers.  The accounting port is one more than the authentication
 port.  If no ports are given, authentication defaults to 1645, and
@@ -118,6 +118,11 @@ A comma separated list of supported RADIUS authentication methods
 Port for DAE RADIUS (Packet of Death/Disconnect, Change of Authorization)
 requests (default: 3799).
 .TP
 Port for DAE RADIUS (Packet of Death/Disconnect, Change of Authorization)
 requests (default: 3799).
 .TP
+.BR radius_bind_min ", " radius_bind_max
+Define a port range in which to bind sockets used to send and receive
+RADIUS packets.  Must be at least RADIUS_FDS (64) wide.  Simplifies
+firewalling of RADIUS ports (default: dynamically assigned).
+.TP
 .B allow_duplicate_users
 Allow multiple logins with the same username.  If false (the default),
 any prior session with the same username will be dropped when a new
 .B allow_duplicate_users
 Allow multiple logins with the same username.  If false (the default),
 any prior session with the same username will be dropped when a new
index 8fccdfc..d70786b 100644 (file)
--- a/l2tpns.c
+++ b/l2tpns.c
@@ -4,7 +4,7 @@
 // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
 // vim: sw=8 ts=8
 
 // Copyright (c) 2002 FireBrick (Andrews & Arnold Ltd / Watchfront Ltd) - GPL licenced
 // vim: sw=8 ts=8
 
-char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.168 2006/06/22 15:30:29 bodea Exp $";
+char const *cvs_id_l2tpns = "$Id: l2tpns.c,v 1.169 2006/07/01 12:40:17 bodea Exp $";
 
 #include <arpa/inet.h>
 #include <assert.h>
 
 #include <arpa/inet.h>
 #include <assert.h>
@@ -126,6 +126,8 @@ config_descriptt config_values[] = {
        CONFIG("radius_secret", radiussecret, STRING),
        CONFIG("radius_authtypes", radius_authtypes_s, STRING),
        CONFIG("radius_dae_port", radius_dae_port, SHORT),
        CONFIG("radius_secret", radiussecret, STRING),
        CONFIG("radius_authtypes", radius_authtypes_s, STRING),
        CONFIG("radius_dae_port", radius_dae_port, SHORT),
+       CONFIG("radius_bind_min", radius_bind_min, SHORT),
+       CONFIG("radius_bind_max", radius_bind_max, SHORT),
        CONFIG("allow_duplicate_users", allow_duplicate_users, BOOL),
        CONFIG("guest_account", guest_user, STRING),
        CONFIG("bind_address", bind_address, IPv4),
        CONFIG("allow_duplicate_users", allow_duplicate_users, BOOL),
        CONFIG("guest_account", guest_user, STRING),
        CONFIG("bind_address", bind_address, IPv4),
@@ -625,7 +627,7 @@ static void initudp(void)
                int flags = fcntl(udpfd, F_GETFL, 0);
                fcntl(udpfd, F_SETFL, flags | O_NONBLOCK);
        }
                int flags = fcntl(udpfd, F_GETFL, 0);
                fcntl(udpfd, F_SETFL, flags | O_NONBLOCK);
        }
-       if (bind(udpfd, (void *) &addr, sizeof(addr)) < 0)
+       if (bind(udpfd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
        {
                LOG(0, 0, 0, "Error in UDP bind: %s\n", strerror(errno));
                exit(1);
        {
                LOG(0, 0, 0, "Error in UDP bind: %s\n", strerror(errno));
                exit(1);
@@ -638,7 +640,7 @@ static void initudp(void)
        controlfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        setsockopt(controlfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
        setsockopt(controlfd, SOL_IP, IP_PKTINFO, &on, sizeof(on)); // recvfromto
        controlfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        setsockopt(controlfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
        setsockopt(controlfd, SOL_IP, IP_PKTINFO, &on, sizeof(on)); // recvfromto
-       if (bind(controlfd, (void *) &addr, sizeof(addr)) < 0)
+       if (bind(controlfd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
        {
                LOG(0, 0, 0, "Error in control bind: %s\n", strerror(errno));
                exit(1);
        {
                LOG(0, 0, 0, "Error in control bind: %s\n", strerror(errno));
                exit(1);
@@ -651,7 +653,7 @@ static void initudp(void)
        daefd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        setsockopt(daefd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
        setsockopt(daefd, SOL_IP, IP_PKTINFO, &on, sizeof(on)); // recvfromto
        daefd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        setsockopt(daefd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
        setsockopt(daefd, SOL_IP, IP_PKTINFO, &on, sizeof(on)); // recvfromto
-       if (bind(daefd, (void *) &addr, sizeof(addr)) < 0)
+       if (bind(daefd, (struct sockaddr *) &addr, sizeof(addr)) < 0)
        {
                LOG(0, 0, 0, "Error in DAE bind: %s\n", strerror(errno));
                exit(1);
        {
                LOG(0, 0, 0, "Error in DAE bind: %s\n", strerror(errno));
                exit(1);
index 2c760f2..45c231a 100644 (file)
--- a/l2tpns.h
+++ b/l2tpns.h
@@ -1,5 +1,5 @@
 // L2TPNS Global Stuff
 // L2TPNS Global Stuff
-// $Id: l2tpns.h,v 1.117 2006/06/11 12:46:18 bodea Exp $
+// $Id: l2tpns.h,v 1.118 2006/07/01 12:40:17 bodea Exp $
 
 #ifndef __L2TPNS_H__
 #define __L2TPNS_H__
 
 #ifndef __L2TPNS_H__
 #define __L2TPNS_H__
@@ -638,7 +638,9 @@ typedef struct
        uint16_t        radiusport[MAXRADSERVER];       // radius base ports
        uint8_t         numradiusservers;               // radius server count
 
        uint16_t        radiusport[MAXRADSERVER];       // radius base ports
        uint8_t         numradiusservers;               // radius server count
 
-       uint16_t        radius_dae_port;                // local port for radius dae
+       uint16_t        radius_dae_port;                // port for radius DAE
+       uint16_t        radius_bind_min;                // port range for udp sockets used to send/recv radius packets
+       uint16_t        radius_bind_max;
 
        char            radius_authtypes_s[32];         // list of valid authentication types (chap, pap) in order of preference
        int             radius_authtypes;
 
        char            radius_authtypes_s[32];         // list of valid authentication types (chap, pap) in order of preference
        int             radius_authtypes;
index e3b34c1..e7fb9fb 100644 (file)
@@ -43,5 +43,5 @@ rm -rf %{buildroot}
 %attr(644,root,root) /usr/share/man/man[58]/*
 
 %changelog
 %attr(644,root,root) /usr/share/man/man[58]/*
 
 %changelog
-* Fri Jun 23 2006 Brendan O'Dea <bod@optus.net> 2.2.0-1
+* Sat Jul 1 2006 Brendan O'Dea <bod@optus.net> 2.2.0-1
 - 2.2.0 release, see /usr/share/doc/l2tpns-2.2.0/Changes
 - 2.2.0 release, see /usr/share/doc/l2tpns-2.2.0/Changes
index fdb54a1..60b97a4 100644 (file)
--- a/radius.c
+++ b/radius.c
@@ -1,6 +1,6 @@
 // L2TPNS Radius Stuff
 
 // L2TPNS Radius Stuff
 
-char const *cvs_id_radius = "$Id: radius.c,v 1.51 2006/06/11 12:46:18 bodea Exp $";
+char const *cvs_id_radius = "$Id: radius.c,v 1.52 2006/07/01 12:40:17 bodea Exp $";
 
 #include <time.h>
 #include <stdio.h>
 
 #include <time.h>
 #include <stdio.h>
@@ -45,6 +45,25 @@ static void calc_auth(const void *buf, size_t len, const uint8_t *in, uint8_t *o
 void initrad(void)
 {
        int i;
 void initrad(void)
 {
        int i;
+       uint16_t port = 0;
+       uint16_t min = config->radius_bind_min;
+       uint16_t max = config->radius_bind_max;
+       int inc = 1;
+       struct sockaddr_in addr;
+
+       if (min)
+       {
+               port = min;
+               if (!max)
+                       max = ~0 - 1;
+       }
+       else if (max) /* no minimum specified, bind from max down */
+       {
+               port = max;
+               min = 1;
+               inc = -1;
+       }
+
        LOG(3, 0, 0, "Creating %d sockets for RADIUS queries\n", RADIUS_FDS);
        radfds = calloc(sizeof(int), RADIUS_FDS);
        for (i = 0; i < RADIUS_FDS; i++)
        LOG(3, 0, 0, "Creating %d sockets for RADIUS queries\n", RADIUS_FDS);
        radfds = calloc(sizeof(int), RADIUS_FDS);
        for (i = 0; i < RADIUS_FDS; i++)
@@ -53,6 +72,27 @@ void initrad(void)
                radfds[i] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
                flags = fcntl(radfds[i], F_GETFL, 0);
                fcntl(radfds[i], F_SETFL, flags | O_NONBLOCK);
                radfds[i] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
                flags = fcntl(radfds[i], F_GETFL, 0);
                fcntl(radfds[i], F_SETFL, flags | O_NONBLOCK);
+
+               if (port)
+               {
+                       int b;
+
+                       memset(&addr, 0, sizeof(addr));
+                       addr.sin_family = AF_INET;
+                       addr.sin_addr.s_addr = INADDR_ANY;
+
+                       do {
+                               addr.sin_port = htons(port);
+                               if ((b = bind(radfds[i], (struct sockaddr *) &addr, sizeof(addr))) < 0)
+                               {
+                                       if ((port += inc) < min || port > max)
+                                       {
+                                               LOG(0, 0, 0, "Can't bind RADIUS socket in range %u-%u\n", min, max);
+                                               exit(1);
+                                       }
+                               }
+                       } while (b < 0);
+               }
        }
 }
 
        }
 }