bin/112764: [ patch ] ppp(8): allow changing NAS_PORT_ID behavior

Roman Bogorodskiy novel at FreeBSD.org
Fri May 18 13:50:11 UTC 2007


>Number:         112764
>Category:       bin
>Synopsis:       [ patch ] ppp(8): allow changing NAS_PORT_ID behavior
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri May 18 13:50:11 GMT 2007
>Closed-Date:
>Last-Modified:
>Originator:     Roman Bogorodskiy
>Release:        FreeBSD 6.0-STABLE i386
>Organization:
>Environment:
>Description:
	
I'd like to propose a patch for ppp(8) which allows to change the
behaviour of keeping port id unique. That maybe useful in case of using
external packages, e.g. when using poptop (net/poptop), ppp(8) doesn't
define NAS-Port-Id in RADIUS query. And it's not possible to do anything 
about it by changing ppp.conf, etc.

There's one more reason why this patch may be useful. Devices by such 
vendors as Cisco, DLink and others define NAS-Port-Id as line number,
which can be used then to drop the user from the line. However, it's
not possible to do the same thing for VPN (PPPoE, PPTP) on FreeBSD.

This patch allows to change the way of NAS-Port-Id gets defined by ppp(8).
It adds a new option for ppp.conf: set rad_port_id. Possible values are:

* set rad_port_id pid
 PID of the corresponding tunnel. Very nice to for dropping the line using
 kill(1) (or kill(2) if you want)

* set rad_port_id tunnum
 tun(4) interface number

* set rad_port_id ifnum
 index of the interface as of returned by if_nametoindex(3)

* set rad_port_id default
 keeps the default behavior (i.e. the way ppp(8) works without this patch).
 Could be useful if the default behavior suits user or to keep ppp(8)
 compatible with legacy software. This is used in case when rad_port_id
 is not defined.

>How-To-Repeat:
>Fix:
--- ppp_rad_port_id_20070518_CURRENT.diff begins here ---
Index: command.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ppp/command.c,v
retrieving revision 1.306
diff -u -r1.306 command.c
--- command.c	6 Sep 2006 06:33:39 -0000	1.306
+++ command.c	18 May 2007 05:56:18 -0000
@@ -144,6 +144,7 @@
 #define	VAR_IPV6CPRETRY	37
 #define	VAR_RAD_ALIVE	38
 #define	VAR_PPPOE	39
+#define	VAR_PORT_ID	40
 
 /* ``accept|deny|disable|enable'' masks */
 #define NEG_HISMASK (1)
@@ -2311,6 +2312,29 @@
     }
     break;
 
+#ifndef NORADIUS
+  case VAR_PORT_ID:
+    if (strcasecmp(argp, "default") == 0)
+	    arg->bundle->radius.port_id_type = RPI_DEFAULT;
+    else if (strcasecmp(argp, "pid") == 0)
+	    arg->bundle->radius.port_id_type = RPI_PID;
+    else if (strcasecmp(argp, "ifnum") == 0)
+	    arg->bundle->radius.port_id_type = RPI_IFNUM; 
+    else if (strcasecmp(argp, "tunnum") == 0)
+	    arg->bundle->radius.port_id_type = RPI_TUNNUM;
+    else {
+	   log_Printf(LogWARN,
+		"RADIUS port id must be one of \"default\", \"pid\", \"ifnum\" or \"tunnum\"\n");
+	   res = 1;
+    }
+
+    if (arg->bundle->radius.port_id_type && !arg->bundle->radius.cfg.file) {
+	    log_Printf(LogWARN, "rad_port_id requires radius to be configured\n");
+	    res = 1;
+    }
+
+    break;
+#endif
   }
 
   return res;
@@ -2415,7 +2439,9 @@
   "RADIUS Config", "set radius cfgfile", (const void *)VAR_RADIUS},
   {"rad_alive", NULL, SetVariable, LOCAL_AUTH,
   "Raduis alive interval", "set rad_alive value",
-  (const void *)VAR_RAD_ALIVE},  
+  (const void *)VAR_RAD_ALIVE},
+  {"rad_port_id", NULL, SetVariable, LOCAL_AUTH,
+  "NAS-Port-Id", "set rad_port_id [default|pid|ifnum|tunnum]", (const void *)VAR_PORT_ID},
 #endif
   {"reconnect", NULL, datalink_SetReconnect, LOCAL_AUTH | LOCAL_CX,
   "Reconnect timeout", "set reconnect value ntries", NULL},
Index: radius.c
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ppp/radius.c,v
retrieving revision 1.53
diff -u -r1.53 radius.c
--- radius.c	1 Mar 2007 16:13:56 -0000	1.53
+++ radius.c	18 May 2007 05:56:21 -0000
@@ -95,6 +95,7 @@
 #include "ncp.h"
 #include "bundle.h"
 #include "proto.h"
+#include "iface.h"
 
 #ifndef NODES
 struct mschap_response {
@@ -825,7 +826,7 @@
 }
 
 static int
-radius_put_physical_details(struct rad_handle *rad, struct physical *p)
+radius_put_physical_details(struct radius *rad, struct physical *p)
 {
   int slot, type;
 
@@ -853,16 +854,32 @@
         break;
     }
 
-  if (rad_put_int(rad, RAD_NAS_PORT_TYPE, type) != 0) {
-    log_Printf(LogERROR, "rad_put: rad_put_int: %s\n", rad_strerror(rad));
-    rad_close(rad);
+  if (rad_put_int(rad->cx.rad, RAD_NAS_PORT_TYPE, type) != 0) {
+    log_Printf(LogERROR, "rad_put: rad_put_int: %s\n", rad_strerror(rad->cx.rad));
+    rad_close(rad->cx.rad);
     return 0;
   }
 
-  if ((slot = physical_Slot(p)) >= 0)
-    if (rad_put_int(rad, RAD_NAS_PORT, slot) != 0) {
-      log_Printf(LogERROR, "rad_put: rad_put_int: %s\n", rad_strerror(rad));
-      rad_close(rad);
+  slot = physical_Slot(p);
+  switch (rad->port_id_type) {
+    case RPI_PID:
+      slot = (int)getpid();
+      break;
+    case RPI_IFNUM:
+      slot = p->dl->bundle->iface->index;
+      break;
+    case RPI_TUNNUM:
+      slot =  p->dl->bundle->unit;
+      break;
+    case RPI_DEFAULT:
+    default:
+      break;
+   }
+  
+  if (slot >= 0)
+    if (rad_put_int(rad->cx.rad, RAD_NAS_PORT, slot) != 0) {
+      log_Printf(LogERROR, "rad_put: rad_put_int: %s\n", rad_strerror(rad->cx.rad));
+      rad_close(rad->cx.rad);
       return 0;
     }
 
@@ -1031,7 +1048,7 @@
     return 0;
   }
 
-  radius_put_physical_details(r->cx.rad, authp->physical);
+  radius_put_physical_details(r, authp->physical);
 
   log_Printf(LogRADIUS, "Radius(auth): %s data sent for %s\n", what, name);
 
@@ -1209,7 +1226,7 @@
     }
   }
 
-  radius_put_physical_details(r->cx.rad, dl->physical);
+  radius_put_physical_details(r, dl->physical);
 
   if (rad_put_int(r->cx.rad, RAD_ACCT_STATUS_TYPE, acct_type) != 0 ||
       rad_put_string(r->cx.rad, RAD_ACCT_SESSION_ID, ac->session_id) != 0 ||
Index: radius.h
===================================================================
RCS file: /home/ncvs/src/usr.sbin/ppp/radius.h,v
retrieving revision 1.21
diff -u -r1.21 radius.h
--- radius.h	27 Jan 2005 14:09:33 -0000	1.21
+++ radius.h	18 May 2007 05:56:21 -0000
@@ -32,6 +32,11 @@
 #define	MPPE_TYPE_40BIT		2
 #define	MPPE_TYPE_128BIT	4
 
+#define	RPI_DEFAULT		1
+#define	RPI_PID			2
+#define	RPI_IFNUM		3
+#define	RPI_TUNNUM		4
+
 struct radius {
   struct fdescriptor desc;	/* We're a sort of (selectable) fdescriptor */
   struct {
@@ -70,6 +75,7 @@
     struct pppTimer timer;	/* for this long */
     int interval;
   } alive;
+  short unsigned int port_id_type;
 };
 
 struct radacct {
--- ppp_rad_port_id_20070518_CURRENT.diff ends here ---


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list