Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 3 Jul 2000 19:29:17 +0200
From:      Stefan Esser <se@freebsd.org>
To:        freebsd-isdn@FreeBSD.org
Cc:        joerg@freebsd.org, hm@hcs.de, Stefan Esser <se@freebsd.org>
Subject:   [Patch] PPP auth config from isdnd.rc
Message-ID:  <20000703192917.A10288@StefanEsser.FreeBSD.org>

next in thread | raw e-mail | index | archive | help
While spppcontrols works fine for specifying the PAP or CHAP parameters,
it requires to have part of ISDN PPP connection parameters to be specified 
in isdnd.rc, while the parameters to spppcontrol are maintained in some
other place (typically /etc/rc.conf).

The patches attached to this message introduce a number of new configuration
parameters that apply to sections of type ISPPP. If none of these options
are set in isdnd.rc, then the current behaviour is preserved (i.e. the 
name and secret can be set with spppcontrol before or after starting isdnd).

remote-auth-method	= chap		# one of: pap, chap, none
remote-auth-name	= otelo		# whatever name to use or expect
remote-auth-key		= online	# the secret sent or received
remote-auth-required	= no		# remote auth required if we call
remote-auth-rechallenge	= yes		# rechallenge CHAP

local-auth-method	= none		# if none: ignore name and secret
#local-auth-name	= whoknows	# not required for method "none"
#local-auth-secret	= none		# 

An additional advantage is, that the /etc/isdn directory is mode 700 and
thus protected against spotting the secrets.

The check_config and print_config functions know about the new configuration
options and DTRT.

It is of course still possible to check or set authentication parameters 
with spppcontrol, as before.

Please consider these patches for inclusion in i4b.

BTW: The function set_isppp_auth is derived from spppcontrol. Jörg may
wish to check out, whether he considers his copyright to apply. But since
the remaining lines are mostly those that deal with opening the socket and 
doing the ioctls, I do not think that he will recognize much of the code ...

Best regards, STefan


Index: /usr/src/usr.sbin/i4b/isdnd/isdnd.h
===================================================================
RCS file: /usr/cvs/src/usr.sbin/i4b/isdnd/isdnd.h,v
retrieving revision 1.8
diff -u -2 -r1.8 isdnd.h
--- /usr/src/usr.sbin/i4b/isdnd/isdnd.h	2000/05/26 02:08:22	1.8
+++ /usr/src/usr.sbin/i4b/isdnd/isdnd.h	2000/07/03 17:25:29
@@ -336,4 +336,23 @@
 #define DIR_INONLY	1
 #define DIR_OUTONLY	2
+
+	int	local_auth_method;
+	int	remote_auth_method;
+#define AUTH_UNDEF	0
+#define AUTH_NONE	1
+#define AUTH_PAP	2
+#define AUTH_CHAP	3
+
+	int remote_auth_flags;
+#define AUTH_RECHALLENGE 0x01
+#define AUTH_REQUIRED	0x02
+
+#define AUTHNAMELEN	32
+#define AUTHKEYLEN	16
+	char	local_auth_name[AUTHNAMELEN];	/* PPP PAP/CHAP login name */
+	char	remote_auth_name[AUTHNAMELEN];	/* AUTHNAMELEN defined in <net/if_sppp.h> */
+
+	char	local_auth_secret[AUTHKEYLEN];
+	char	remote_auth_secret[AUTHKEYLEN];
 	
 /*===========================================================================*/	
Index: /usr/src/usr.sbin/i4b/isdnd/rc_config.c
===================================================================
RCS file: /usr/cvs/src/usr.sbin/i4b/isdnd/rc_config.c,v
retrieving revision 1.6
diff -u -2 -r1.6 rc_config.c
--- /usr/src/usr.sbin/i4b/isdnd/rc_config.c	1999/12/14 21:07:31	1.6
+++ /usr/src/usr.sbin/i4b/isdnd/rc_config.c	2000/07/03 15:58:29
@@ -41,4 +41,13 @@
 #include <arpa/inet.h>
 
+#include <sys/callout.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+#include <net/if_var.h>
+#include <net/if_sppp.h>
+
+#include <sysexits.h>
+
 #include "isdnd.h"
 #include "y.tab.h"
@@ -203,4 +212,10 @@
 		cep->inout = DIR_INOUT;
 		
+		cep->local_auth_method = AUTH_UNDEF;
+		
+		cep->remote_auth_method = AUTH_UNDEF;
+		
+		cep->remote_auth_flags = AUTH_RECHALLENGE | AUTH_REQUIRED;
+		
 		/* ======== filled in after start, then dynamic */
 
@@ -224,4 +239,100 @@
 }
 
+#define PPP_PAP		0xc023
+#define PPP_CHAP	0xc223
+
+static void
+set_isppp_auth(int entry)
+{
+	cfg_entry_t *cep = &cfg_entry_tab[entry];	/* ptr to config entry */
+
+	struct ifreq ifr;
+	struct spppreq spr;
+	int s;
+	int doioctl = 0;
+
+	if(cep->usrdevicename != BDRV_ISPPP)
+		return;
+
+	if(cep->local_auth_method == AUTH_UNDEF && cep->remote_auth_method == AUTH_UNDEF)
+		return;
+
+	if(cep->local_auth_method == AUTH_NONE || cep->local_auth_method == AUTH_NONE)
+		doioctl = 1;
+
+	if ((cep->local_auth_method == AUTH_CHAP || cep->local_auth_method == AUTH_PAP)
+			&& cep->local_auth_name[0] != 0
+			&& cep->local_auth_secret[0] != 0)
+		doioctl = 1;
+
+	if ((cep->remote_auth_method == AUTH_CHAP || cep->remote_auth_method == AUTH_PAP)
+			&& cep->remote_auth_name[0] != 0
+			&& cep->remote_auth_secret[0] != 0)
+		doioctl = 1;
+
+	if(!doioctl)
+		return;
+
+	snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "isp%d", cep->usrdeviceunit);
+
+	/* use a random AF to create the socket */
+	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
+		err(EX_UNAVAILABLE, "ifconfig: socket");
+
+	spr.cmd = (int)SPPPIOGDEFS;
+	ifr.ifr_data = (caddr_t)&spr;
+
+	if (ioctl(s, SIOCGIFGENERIC, &ifr) == -1)
+		err(EX_OSERR, "SIOCGIFGENERIC(SPPPIOGDEFS)");
+
+	if (cep->local_auth_method != AUTH_UNDEF)
+	{
+		if(cep->local_auth_method == AUTH_NONE)
+		{
+			spr.defs.myauth.proto = 0;
+		}
+		else if ((cep->local_auth_method == AUTH_CHAP || cep->local_auth_method == AUTH_PAP)
+			 && cep->local_auth_name[0] != 0
+			 && cep->local_auth_secret[0] != 0)
+		{
+			spr.defs.myauth.proto = cep->local_auth_method == AUTH_PAP ? PPP_PAP : PPP_CHAP;
+			strncpy(spr.defs.myauth.name, cep->local_auth_name, AUTHNAMELEN);
+			strncpy(spr.defs.myauth.secret, cep->local_auth_secret, AUTHKEYLEN);
+		}
+	}
+	if (cep->remote_auth_method != AUTH_UNDEF)
+	{
+		if(cep->remote_auth_method == AUTH_NONE)
+		{
+			spr.defs.hisauth.proto = 0;
+		}
+		else if ((cep->remote_auth_method == AUTH_CHAP || cep->remote_auth_method == AUTH_PAP)
+			 && cep->remote_auth_name[0] != 0
+			 && cep->remote_auth_secret[0] != 0)
+		{
+			spr.defs.hisauth.proto = cep->remote_auth_method == AUTH_PAP ? PPP_PAP : PPP_CHAP;
+			strncpy(spr.defs.hisauth.name, cep->remote_auth_name, AUTHNAMELEN);
+			strncpy(spr.defs.hisauth.secret, cep->remote_auth_secret, AUTHKEYLEN);
+
+			if(cep->remote_auth_flags & AUTH_REQUIRED)
+				spr.defs.hisauth.flags &= ~AUTHFLAG_NOCALLOUT;
+			else
+				spr.defs.hisauth.flags |= AUTHFLAG_NOCALLOUT;
+
+			if(cep->remote_auth_flags & AUTH_RECHALLENGE)
+				spr.defs.hisauth.flags &= ~AUTHFLAG_NORECHALLENGE;
+			else
+				spr.defs.hisauth.flags |= AUTHFLAG_NORECHALLENGE;
+		}
+	}
+
+	spr.cmd = (int)SPPPIOSDEFS;
+
+	if (ioctl(s, SIOCSIFGENERIC, &ifr) == -1)
+		err(EX_OSERR, "SIOCSIFGENERIC(SPPPIOSDEFS)");
+
+	close(s);
+}
+
 /*---------------------------------------------------------------------------*
  *	extract values from config and fill table
@@ -475,4 +586,33 @@
 			break;
 
+		case LOCAL_AUTH_METHOD:
+			DBGL(DL_RCCF, (log(LL_DBG, "entry %d: local_auth_method = %s", entrycount, yylval.str)));
+			if(!(strcmp(yylval.str, "none")))
+				cfg_entry_tab[entrycount].local_auth_method = AUTH_NONE;
+			else if(!(strcmp(yylval.str, "pap")))
+				cfg_entry_tab[entrycount].local_auth_method = AUTH_PAP;
+			else if(!(strcmp(yylval.str, "chap")))
+				cfg_entry_tab[entrycount].local_auth_method = AUTH_CHAP;
+			else
+			{
+				log(LL_ERR, "ERROR parsing config file: unknown parameter for keyword \"local_auth_method\" at line %d!", lineno);
+				config_error_flag++;
+				break;
+			}
+			set_isppp_auth(entrycount);
+			break;
+
+		case LOCAL_AUTH_NAME:
+			DBGL(DL_RCCF, (log(LL_DBG, "entry %d: local_auth_method = %s", entrycount, yylval.str)));
+			strncpy(cfg_entry_tab[entrycount].local_auth_name, yylval.str, sizeof(cfg_entry_tab[entrycount].local_auth_name) -1);
+			set_isppp_auth(entrycount);
+			break;
+
+		case LOCAL_AUTH_SECRET:
+			DBGL(DL_RCCF, (log(LL_DBG, "entry %d: local_auth_method = %s", entrycount, yylval.str)));
+			strncpy(cfg_entry_tab[entrycount].local_auth_secret, yylval.str, sizeof(cfg_entry_tab[entrycount].local_auth_secret) -1);
+			set_isppp_auth(entrycount);
+			break;
+
 		case LOCAL_PHONE_DIALOUT:
 			DBGL(DL_RCCF, (log(LL_DBG, "entry %d: local_phone_dialout = %s", entrycount, yylval.str)));
@@ -550,4 +690,51 @@
 			break;
 
+		case REMOTE_AUTH_METHOD:
+			DBGL(DL_RCCF, (log(LL_DBG, "entry %d: remote_auth_method = %s", entrycount, yylval.str)));
+			if(!(strcmp(yylval.str, "none")))
+				cfg_entry_tab[entrycount].remote_auth_method = AUTH_NONE;
+			else if(!(strcmp(yylval.str, "pap")))
+				cfg_entry_tab[entrycount].remote_auth_method = AUTH_PAP;
+			else if(!(strcmp(yylval.str, "chap")))
+				cfg_entry_tab[entrycount].remote_auth_method = AUTH_CHAP;
+			else
+			{
+				log(LL_ERR, "ERROR parsing config file: unknown parameter for keyword \"remote_auth_method\" at line %d!", lineno);
+				config_error_flag++;
+				break;
+			}
+			set_isppp_auth(entrycount);
+			break;
+
+		case REMOTE_AUTH_NAME:
+			DBGL(DL_RCCF, (log(LL_DBG, "entry %d: remote_auth_method = %s", entrycount, yylval.str)));
+			strncpy(cfg_entry_tab[entrycount].remote_auth_name, yylval.str, sizeof(cfg_entry_tab[entrycount].remote_auth_name) -1);
+			set_isppp_auth(entrycount);
+			break;
+
+		case REMOTE_AUTH_SECRET:
+			DBGL(DL_RCCF, (log(LL_DBG, "entry %d: remote_auth_method = %s", entrycount, yylval.str)));
+			strncpy(cfg_entry_tab[entrycount].remote_auth_secret, yylval.str, sizeof(cfg_entry_tab[entrycount].remote_auth_secret) -1);
+			set_isppp_auth(entrycount);
+			break;
+
+		case REMOTE_AUTH_RECHALLENGE:
+			DBGL(DL_RCCF, (log(LL_DBG, "entry %d: remote_auth_rechallenge = %d", entrycount, yylval.booln)));
+			if(yylval.booln)
+				cfg_entry_tab[entrycount].remote_auth_flags |= AUTH_RECHALLENGE;
+			else
+				cfg_entry_tab[entrycount].remote_auth_flags &= ~AUTH_RECHALLENGE;
+			set_isppp_auth(entrycount);
+			break;
+
+		case REMOTE_AUTH_REQUIRED:
+			DBGL(DL_RCCF, (log(LL_DBG, "entry %d: remote_auth_required = %d", entrycount, yylval.booln)));
+			if(yylval.booln)
+				cfg_entry_tab[entrycount].remote_auth_flags |= AUTH_REQUIRED;
+			else
+				cfg_entry_tab[entrycount].remote_auth_flags &= ~AUTH_REQUIRED;
+			set_isppp_auth(entrycount);
+			break;
+
 		case REMOTE_PHONE_DIALOUT:
 			if(cfg_entry_tab[entrycount].remote_numbers_count >= MAXRNUMBERS)
@@ -848,4 +1035,31 @@
 			error++;
 		}
+
+		if((cep->remote_auth_method == AUTH_PAP) || (cep->remote_auth_method == AUTH_CHAP))
+		{
+			if(cep->remote_auth_name[0] == 0)
+			{
+				log(LL_ERR, "check_config: no remote authentification name in entry %d!", i);
+				error++;
+			}
+			if(cep->remote_auth_secret[0] == 0)
+			{
+				log(LL_ERR, "check_config: no remote authentification secret in entry %d!", i);
+				error++;
+			}
+		}
+		if((cep->local_auth_method == AUTH_PAP) || (cep->local_auth_method == AUTH_CHAP))
+		{
+			if(cep->local_auth_name[0] == 0)
+			{
+				log(LL_ERR, "check_config: no local authentification name in entry %d!", i);
+				error++;
+			}
+			if(cep->local_auth_secret[0] == 0)
+			{
+				log(LL_ERR, "check_config: no local authentification secret in entry %d!", i);
+				error++;
+			}
+		}
 	}
 	if(error)
@@ -1163,4 +1377,60 @@
 					fprintf(PFILE, "callback\t\t# when remote calls in, i will hangup and call back\n");
 					break;
+			}
+		}
+
+		if(cep->usrdevicename == BDRV_ISPPP)
+		{
+			char *s;
+			switch(cep->remote_auth_method)
+			{
+				case AUTH_NONE:
+					s = "none";
+					break;
+				case AUTH_PAP:
+					s = "pap";
+					break;
+				case AUTH_CHAP:
+					s = "chap";
+					break;
+				default:
+					s = NULL;
+					break;
+			}
+			if(s != NULL)
+			{
+				fprintf(PFILE, "remote_auth_method    = %s\t\t# the auth protocol we use when dialing out (none,pap,chap)\n", s);
+				if(cep->remote_auth_method != AUTH_NONE)
+				{
+					fprintf(PFILE, "remote_auth_name      = %s\t\t# our PPP account used for dial-out\n", cep->remote_auth_name);
+					fprintf(PFILE, "remote_auth_secret    = %s\t\t# the key sent to the other side\n", cep->remote_auth_secret);
+					if(cep->remote_auth_method != AUTH_CHAP)
+						fprintf(PFILE, "remote_auth_rechallenge= %s\t\t# rechallenge CHAP connections once in a while\n", cep->remote_auth_flags & AUTH_RECHALLENGE ? "yes" : "no");
+					fprintf(PFILE, "remote_auth_required  = %s\t\t# do we require remote to authenticate even if we dial out\n", cep->remote_auth_flags & AUTH_REQUIRED ? "yes" : "no");
+				}
+			}
+			switch(cep->local_auth_method)
+			{
+				case AUTH_NONE:
+					s = "none";
+					break;
+				case AUTH_PAP:
+					s = "pap";
+					break;
+				case AUTH_CHAP:
+					s = "chap";
+					break;
+				default:
+					s = NULL;
+					break;
+			}
+			if(s != NULL)
+			{
+				fprintf(PFILE, "local_auth_method     = %s\t\t# the auth protocol we expect to receive on dial-in (none,pap,chap)\n", s);
+				if(cep->local_auth_method != AUTH_NONE)
+				{
+					fprintf(PFILE, "local_auth_name       = %s\t\t# the user name allowed in\n", cep->local_auth_name);
+					fprintf(PFILE, "local_auth_secret     = %s\t\t# the key expected from the other side\n", cep->local_auth_secret);
+				}
 			}
 		}
Index: /usr/src/usr.sbin/i4b/isdnd/rc_parse.y
===================================================================
RCS file: /usr/cvs/src/usr.sbin/i4b/isdnd/rc_parse.y,v
retrieving revision 1.6
diff -u -2 -r1.6 rc_parse.y
--- /usr/src/usr.sbin/i4b/isdnd/rc_parse.y	1999/12/14 21:07:32	1.6
+++ /usr/src/usr.sbin/i4b/isdnd/rc_parse.y	2000/07/03 17:12:49
@@ -107,4 +107,7 @@
 %token		ISDNTXDELIN
 %token		ISDNTXDELOUT
+%token		LOCAL_AUTH_METHOD
+%token		LOCAL_AUTH_NAME
+%token		LOCAL_AUTH_SECRET
 %token		LOCAL_PHONE_DIALOUT
 %token		LOCAL_PHONE_INCOMING
@@ -127,4 +130,9 @@
 %token		REGEXPR
 %token		REGPROG
+%token		REMOTE_AUTH_METHOD
+%token		REMOTE_AUTH_NAME
+%token		REMOTE_AUTH_RECHALLENGE
+%token		REMOTE_AUTH_REQUIRED
+%token		REMOTE_AUTH_SECRET
 %token		REMOTE_NUMBERS_HANDLING
 %token		REMOTE_PHONE_DIALOUT
@@ -393,8 +401,14 @@
 		| DISCONNECTPROG	{ $$ = DISCONNECTPROG; }
 		| IDLE_ALG_OUT		{ $$ = IDLE_ALG_OUT; }
+		| LOCAL_AUTH_METHOD	{ $$ = LOCAL_AUTH_METHOD; }
+		| LOCAL_AUTH_NAME	{ $$ = LOCAL_AUTH_NAME; }
+		| LOCAL_AUTH_SECRET	{ $$ = LOCAL_AUTH_SECRET; }
 		| LOCAL_PHONE_INCOMING	{ $$ = LOCAL_PHONE_INCOMING; }
 		| LOCAL_PHONE_DIALOUT	{ $$ = LOCAL_PHONE_DIALOUT; }
 		| NAME			{ $$ = NAME; }		
 		| REACTION		{ $$ = REACTION; }
+		| REMOTE_AUTH_METHOD	{ $$ = REMOTE_AUTH_METHOD; }
+		| REMOTE_AUTH_NAME	{ $$ = REMOTE_AUTH_NAME; }
+		| REMOTE_AUTH_SECRET	{ $$ = REMOTE_AUTH_SECRET; }
 		| REMOTE_NUMBERS_HANDLING { $$ = REMOTE_NUMBERS_HANDLING; }
 		| REMOTE_PHONE_INCOMING	{ $$ = REMOTE_PHONE_INCOMING; }
@@ -424,4 +438,6 @@
 
 boolkeyword:	  DIALRANDINCR		{ $$ = DIALRANDINCR; }
+		| REMOTE_AUTH_RECHALLENGE { $$ = REMOTE_AUTH_RECHALLENGE; }
+		| REMOTE_AUTH_REQUIRED	{ $$ = REMOTE_AUTH_REQUIRED; }
 		| USEDOWN		{ $$ = USEDOWN; }
 		;
Index: /usr/src/usr.sbin/i4b/isdnd/rc_scan.l
===================================================================
RCS file: /usr/cvs/src/usr.sbin/i4b/isdnd/rc_scan.l,v
retrieving revision 1.6
diff -u -2 -r1.6 rc_scan.l
--- /usr/src/usr.sbin/i4b/isdnd/rc_scan.l	1999/12/14 21:07:32	1.6
+++ /usr/src/usr.sbin/i4b/isdnd/rc_scan.l	2000/07/03 13:33:08
@@ -118,4 +118,7 @@
 isdntxdel-incoming		{ return ISDNTXDELIN; }
 isdntxdel-outgoing		{ return ISDNTXDELOUT; }
+local-auth-method		{ return LOCAL_AUTH_METHOD; }
+local-auth-name			{ return LOCAL_AUTH_NAME; }
+local-auth-secret		{ return LOCAL_AUTH_SECRET; }
 local-phone-dialout		{ return LOCAL_PHONE_DIALOUT; }
 local-phone-incoming		{ return LOCAL_PHONE_INCOMING; }
@@ -143,4 +146,9 @@
 regprog				{ return REGPROG; }
 remdial-handling		{ return REMOTE_NUMBERS_HANDLING; }
+remote-auth-method		{ return REMOTE_AUTH_METHOD; }
+remote-auth-name		{ return REMOTE_AUTH_NAME; }
+remote-auth-rechallenge		{ return REMOTE_AUTH_RECHALLENGE; }
+remote-auth-required		{ return REMOTE_AUTH_REQUIRED; }
+remote-auth-secret		{ return REMOTE_AUTH_SECRET; }
 remote-phone-dialout		{ return REMOTE_PHONE_DIALOUT; }
 remote-phone-incoming		{ return REMOTE_PHONE_INCOMING; }


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-isdn" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20000703192917.A10288>