From owner-freebsd-isdn Mon Jul 3 10:37:18 2000 Delivered-To: freebsd-isdn@freebsd.org Received: from mout0.freenet.de (mout0.freenet.de [194.97.50.131]) by hub.freebsd.org (Postfix) with ESMTP id 1A1FA37C05C; Mon, 3 Jul 2000 10:36:56 -0700 (PDT) (envelope-from se@freebsd.org) Received: from [194.97.50.136] (helo=mx3.freenet.de) by mout0.freenet.de with esmtp (Exim 3.14 #3) id 139A9O-0007Pt-00; Mon, 03 Jul 2000 19:36:54 +0200 Received: from [213.6.99.71] (helo=StefanEsser.FreeBSD.org) by mx3.freenet.de with esmtp (Exim 3.14 #3) id 139A9L-00025d-00; Mon, 03 Jul 2000 19:36:51 +0200 Received: by StefanEsser.FreeBSD.org (Postfix, from userid 200) id 551F8D55; Mon, 3 Jul 2000 19:29:17 +0200 (CEST) Date: Mon, 3 Jul 2000 19:29:17 +0200 From: Stefan Esser To: freebsd-isdn@FreeBSD.org Cc: joerg@freebsd.org, hm@hcs.de, Stefan Esser Subject: [Patch] PPP auth config from isdnd.rc Message-ID: <20000703192917.A10288@StefanEsser.FreeBSD.org> Reply-To: Stefan Esser Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit User-Agent: Mutt/1.2i Sender: owner-freebsd-isdn@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org 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 */ + + 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 +#include +#include + +#include +#include +#include + +#include + #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