add radius_bind_{min,max} options
authorBrendan O'Dea <bod@optus.net>
Sat, 1 Jul 2006 12:40:10 +0000 (12:40 +0000)
committerBrendan O'Dea <bod@optus.net>
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.
@@ -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 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.
index cb26b54..38e7b81 100644 (file)
@@ -390,6 +390,19 @@ set boolean true
          </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>
index 07fc79c..77af484 100644 (file)
@@ -2,7 +2,7 @@
 .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
@@ -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
-.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
-.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
-.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
@@ -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
+.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
index 03e780c..0c6c1c0 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
 
-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>
@@ -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_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),
@@ -625,7 +627,7 @@ static void initudp(void)
                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);
@@ -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
-       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);
@@ -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
-       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);
index 48e7b02..29f0710 100644 (file)
--- a/l2tpns.h
+++ b/l2tpns.h
@@ -1,5 +1,5 @@
 // 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__
@@ -638,7 +638,9 @@ typedef struct
        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;
index e3b34c1..e7fb9fb 100644 (file)
@@ -43,5 +43,5 @@ rm -rf %{buildroot}
 %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
index a0a4068..c804023 100644 (file)
--- a/radius.c
+++ b/radius.c
@@ -1,6 +1,6 @@
 // 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>
@@ -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;
+       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++)
@@ -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);
+
+               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);
+               }
        }
 }