diff options
author | brian <brian@cvs.openbsd.org> | 1999-02-11 10:14:51 +0000 |
---|---|---|
committer | brian <brian@cvs.openbsd.org> | 1999-02-11 10:14:51 +0000 |
commit | c0289a1d3852169634e87eaf8587cbf32749351b (patch) | |
tree | fe16687d30779724ba37e21f67adf7e1ea69be34 /usr.sbin/ppp | |
parent | 816aa8c83d540009c2ec48103fa86ffdb1213382 (diff) |
When resending chap challenges, resend the same challenge
each time rather than making up a new one.
Increase the authname/authkey max sizes to 100 characters.
Allow ``authkey'' specifications beginning with ``!''.
When a challenge is received, the text following the
``!'' is executed as a program (expanding stuff in the same
way that ``sh'' and ``!bg'' do). The program is passed the
peer name, peer challenge and local ``authname'' on standard
input and is expected to output the name/key combination that
should be used to build the CHAP response.
This provides support for Secure ID cards (guess what I was
given at work recently!) using CHAP.
Examples will follow.
Diffstat (limited to 'usr.sbin/ppp')
-rw-r--r-- | usr.sbin/ppp/ppp/chap.c | 271 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/chap.h | 16 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/command.c | 14 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/command.h | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/datalink.c | 26 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/defs.h | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/descriptor.h | 3 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/hdlc.c | 4 | ||||
-rw-r--r-- | usr.sbin/ppp/ppp/ppp.8 | 62 |
9 files changed, 348 insertions, 56 deletions
diff --git a/usr.sbin/ppp/ppp/chap.c b/usr.sbin/ppp/ppp/chap.c index ffb204b2563..5036b53e9fc 100644 --- a/usr.sbin/ppp/ppp/chap.c +++ b/usr.sbin/ppp/ppp/chap.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: chap.c,v 1.4 1999/02/07 13:56:19 brian Exp $ + * $Id: chap.c,v 1.5 1999/02/11 10:14:49 brian Exp $ * * TODO: */ @@ -27,13 +27,19 @@ #include <netinet/ip.h> #include <sys/un.h> +#include <errno.h> +#include <fcntl.h> #ifdef HAVE_DES #include <md4.h> #include <string.h> #endif #include <md5.h> +#include <paths.h> +#include <signal.h> #include <stdlib.h> +#include <sys/wait.h> #include <termios.h> +#include <unistd.h> #include "mbuf.h" #include "log.h" @@ -45,10 +51,10 @@ #include "lqr.h" #include "hdlc.h" #include "auth.h" -#include "chap.h" #include "async.h" #include "throughput.h" #include "descriptor.h" +#include "chap.h" #include "iplist.h" #include "slcompress.h" #include "ipcp.h" @@ -63,6 +69,7 @@ #include "bundle.h" #include "chat.h" #include "cbcp.h" +#include "command.h" #include "datalink.h" #ifdef HAVE_DES #include "chap_ms.h" @@ -175,34 +182,230 @@ chap_BuildAnswer(char *name, char *key, u_char id, char *challenge, int MSChap) } static void +chap_StartChild(struct chap *chap, char *prog, const char *name) +{ + char *argv[MAXARGS], *nargv[MAXARGS]; + int argc, fd; + int in[2], out[2]; + + if (chap->child.fd != -1) { + log_Printf(LogWARN, "Chap: %s: Program already running\n", prog); + return; + } + + if (pipe(in) == -1) { + log_Printf(LogERROR, "Chap: pipe: %s\n", strerror(errno)); + return; + } + + if (pipe(out) == -1) { + log_Printf(LogERROR, "Chap: pipe: %s\n", strerror(errno)); + close(in[0]); + close(in[1]); + return; + } + + switch ((chap->child.pid = fork())) { + case -1: + log_Printf(LogERROR, "Chap: fork: %s\n", strerror(errno)); + close(in[0]); + close(in[1]); + close(out[0]); + close(out[1]); + chap->child.pid = 0; + return; + + case 0: + timer_TermService(); + close(in[1]); + close(out[0]); + if (out[1] == STDIN_FILENO) { + fd = dup(out[1]); + close(out[1]); + out[1] = fd; + } + dup2(in[0], STDIN_FILENO); + dup2(out[1], STDOUT_FILENO); + if ((fd = open(_PATH_DEVNULL, O_RDWR)) == -1) { + log_Printf(LogALERT, "Chap: Failed to open %s: %s\n", + _PATH_DEVNULL, strerror(errno)); + exit(1); + } + dup2(fd, STDERR_FILENO); + fcntl(3, F_SETFD, 1); /* Set close-on-exec flag */ + + setuid(geteuid()); + argc = command_Interpret(prog, strlen(prog), argv); + command_Expand(nargv, argc, (char const *const *)argv, + chap->auth.physical->dl->bundle, 0); + execvp(nargv[0], nargv); + + log_Printf(LogWARN, "exec() of %s failed: %s\n", + nargv[0], strerror(errno)); + exit(255); + + default: + close(in[0]); + close(out[1]); + chap->child.fd = out[0]; + chap->child.buf.len = 0; + write(in[1], chap->auth.in.name, strlen(chap->auth.in.name)); + write(in[1], "\n", 1); + write(in[1], chap->challenge + 1, *chap->challenge); + write(in[1], "\n", 1); + write(in[1], name, strlen(name)); + write(in[1], "\n", 1); + close(in[1]); + break; + } +} + +static void +chap_Cleanup(struct chap *chap, int sig) +{ + if (chap->child.pid) { + int status; + + close(chap->child.fd); + chap->child.fd = -1; + if (sig) + kill(chap->child.pid, SIGTERM); + chap->child.pid = 0; + chap->child.buf.len = 0; + + if (wait(&status) == -1) + log_Printf(LogERROR, "Chap: wait: %s\n", strerror(errno)); + else if (WIFSIGNALED(status)) + log_Printf(LogWARN, "Chap: Child received signal %d\n", WTERMSIG(status)); + else if (WIFEXITED(status) && WEXITSTATUS(status)) + log_Printf(LogERROR, "Chap: Child exited %d\n", WEXITSTATUS(status)); + } + *chap->challenge = 0; +} + +static void +chap_SendResponse(struct chap *chap, char *name, char *key) +{ + char *ans; + + ans = chap_BuildAnswer(name, key, chap->auth.id, chap->challenge, 0); + + if (ans) { + ChapOutput(chap->auth.physical, CHAP_RESPONSE, chap->auth.id, + ans, *ans + 1 + strlen(name), name); + free(ans); + } else + ChapOutput(chap->auth.physical, CHAP_FAILURE, chap->auth.id, + "Out of memory!", 14, NULL); +} + +static int +chap_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n) +{ + struct chap *chap = descriptor2chap(d); + + if (r && chap && chap->child.fd != -1) { + FD_SET(chap->child.fd, r); + if (*n < chap->child.fd + 1) + *n = chap->child.fd + 1; + log_Printf(LogTIMER, "Chap: fdset(r) %d\n", chap->child.fd); + return 1; + } + + return 0; +} + +static int +chap_IsSet(struct descriptor *d, const fd_set *fdset) +{ + struct chap *chap = descriptor2chap(d); + + return chap && chap->child.fd != -1 && FD_ISSET(chap->child.fd, fdset); +} + +static void +chap_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +{ + struct chap *chap = descriptor2chap(d); + int got; + + got = read(chap->child.fd, chap->child.buf.ptr + chap->child.buf.len, + sizeof chap->child.buf.ptr - chap->child.buf.len - 1); + if (got == -1) { + log_Printf(LogERROR, "Chap: Read: %s\n", strerror(errno)); + chap_Cleanup(chap, SIGTERM); + } else if (got == 0) { + log_Printf(LogWARN, "Chap: Read: Child terminated connection\n"); + chap_Cleanup(chap, SIGTERM); + } else { + char *name, *key, *end; + + chap->child.buf.len += got; + chap->child.buf.ptr[chap->child.buf.len] = '\0'; + name = chap->child.buf.ptr; + name += strspn(name, " \t"); + if ((key = strchr(name, '\n')) == NULL) + end = NULL; + else + end = strchr(++key, '\n'); + + if (end == NULL) { + if (chap->child.buf.len == sizeof chap->child.buf.ptr - 1) { + log_Printf(LogWARN, "Chap: Read: Input buffer overflow\n"); + chap_Cleanup(chap, SIGTERM); + } + } else { + while (end >= name && strchr(" \t\r\n", *end)) + *end-- = '\0'; + end = key - 1; + while (end >= name && strchr(" \t\r\n", *end)) + *end-- = '\0'; + key += strspn(key, " \t"); + + chap_SendResponse(chap, name, key); + chap_Cleanup(chap, 0); + } + } +} + +static int +chap_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) +{ + /* We never want to write here ! */ + log_Printf(LogALERT, "chap_Write: Internal error: Bad call !\n"); + return 0; +} + +static void chap_Challenge(struct authinfo *authp) { struct chap *chap = auth2chap(authp); int len, i; char *cp; - randinit(); - cp = chap->challenge; + len = strlen(authp->physical->dl->bundle->cfg.auth.name); + + if (!*chap->challenge) { + randinit(); + cp = chap->challenge; #ifndef NORADIUS - if (*authp->physical->dl->bundle->radius.cfg.file) { - /* For radius, our challenge is 16 readable NUL terminated bytes :*/ - *cp++ = 16; - for (i = 0; i < 16; i++) - *cp++ = (random() % 10) + '0'; - } else + if (*authp->physical->dl->bundle->radius.cfg.file) { + /* For radius, our challenge is 16 readable NUL terminated bytes :*/ + *cp++ = 16; + for (i = 0; i < 16; i++) + *cp++ = (random() % 10) + '0'; + } else #endif - { - *cp++ = random() % (CHAPCHALLENGELEN-16) + 16; - for (i = 0; i < *chap->challenge; i++) - *cp++ = random() & 0xff; + { + *cp++ = random() % (CHAPCHALLENGELEN-16) + 16; + for (i = 0; i < *chap->challenge; i++) + *cp++ = random() & 0xff; + } + memcpy(cp, authp->physical->dl->bundle->cfg.auth.name, len); } - - len = strlen(authp->physical->dl->bundle->cfg.auth.name); - memcpy(cp, authp->physical->dl->bundle->cfg.auth.name, len); - cp += len; ChapOutput(authp->physical, CHAP_CHALLENGE, authp->id, chap->challenge, - cp - chap->challenge, NULL); + 1 + *chap->challenge + len, NULL); } static void @@ -232,12 +435,25 @@ chap_Failure(struct authinfo *authp) void chap_Init(struct chap *chap, struct physical *p) { + chap->desc.type = CHAP_DESCRIPTOR; + chap->desc.UpdateSet = chap_UpdateSet; + chap->desc.IsSet = chap_IsSet; + chap->desc.Read = chap_Read; + chap->desc.Write = chap_Write; + chap->child.pid = 0; + chap->child.fd = -1; auth_Init(&chap->auth, p, chap_Challenge, chap_Success, chap_Failure); *chap->challenge = 0; chap->using_MSChap = 0; } void +chap_ReInit(struct chap *chap) +{ + chap_Cleanup(chap, SIGTERM); +} + +void chap_Input(struct physical *p, struct mbuf *bp) { struct chap *chap = &p->dl->chap; @@ -336,17 +552,12 @@ chap_Input(struct physical *p, struct mbuf *bp) switch (chap->auth.in.hdr.code) { case CHAP_CHALLENGE: - name = p->dl->bundle->cfg.auth.name; - nlen = strlen(name); - key = p->dl->bundle->cfg.auth.key; - myans = chap_BuildAnswer(name, key, chap->auth.id, chap->challenge, 0); - if (myans) { - ChapOutput(p, CHAP_RESPONSE, chap->auth.id, myans, - *myans + 1 + nlen, name); - free(myans); - } else - ChapOutput(p, CHAP_FAILURE, chap->auth.id, "Out of memory!", - 14, NULL); + if (*p->dl->bundle->cfg.auth.key == '!') + chap_StartChild(chap, p->dl->bundle->cfg.auth.key + 1, + p->dl->bundle->cfg.auth.name); + else + chap_SendResponse(chap, p->dl->bundle->cfg.auth.name, + p->dl->bundle->cfg.auth.key); break; case CHAP_RESPONSE: diff --git a/usr.sbin/ppp/ppp/chap.h b/usr.sbin/ppp/ppp/chap.h index 213eef4a0cf..b4fdaf4b624 100644 --- a/usr.sbin/ppp/ppp/chap.h +++ b/usr.sbin/ppp/ppp/chap.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: chap.h,v 1.2 1999/02/06 03:22:32 brian Exp $ + * $Id: chap.h,v 1.3 1999/02/11 10:14:49 brian Exp $ * * TODO: */ @@ -29,12 +29,24 @@ struct physical; #define CHAP_FAILURE 4 struct chap { + struct descriptor desc; + struct { + pid_t pid; + int fd; + struct { + char ptr[AUTHLEN * 2 + 3]; /* Allow for \r\n at the end (- NUL) */ + int len; + } buf; + } child; struct authinfo auth; char challenge[CHAPCHALLENGELEN + AUTHLEN]; unsigned using_MSChap : 1; /* A combination of MD4 & DES */ }; -#define auth2chap(a) ((struct chap *)(a)) +#define descriptor2chap(d) \ + ((d)->type == CHAP_DESCRIPTOR ? (struct chap *)(d) : NULL) +#define auth2chap(a) (struct chap *)((char *)a - (int)&((struct chap *)0)->auth) extern void chap_Init(struct chap *, struct physical *); +extern void chap_ReInit(struct chap *); extern void chap_Input(struct physical *, struct mbuf *); diff --git a/usr.sbin/ppp/ppp/command.c b/usr.sbin/ppp/ppp/command.c index ec5c0df6be9..ace4ea088c1 100644 --- a/usr.sbin/ppp/ppp/command.c +++ b/usr.sbin/ppp/ppp/command.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: command.c,v 1.7 1999/02/06 03:22:33 brian Exp $ + * $Id: command.c,v 1.8 1999/02/11 10:14:49 brian Exp $ * */ #include <sys/param.h> @@ -138,7 +138,7 @@ #define NEG_DNS 50 const char Version[] = "2.1"; -const char VersionDate[] = "$Date: 1999/02/06 03:22:33 $"; +const char VersionDate[] = "$Date: 1999/02/11 10:14:49 $"; static int ShowCommand(struct cmdargs const *); static int TerminalCommand(struct cmdargs const *); @@ -388,9 +388,9 @@ subst(char *tgt, const char *oldstr, const char *newstr) return tgt; } -static void -expand(char **nargv, int argc, char const *const *oargv, struct bundle *bundle, - int inc0) +void +command_Expand(char **nargv, int argc, char const *const *oargv, + struct bundle *bundle, int inc0) { int arg; char pid[12]; @@ -484,7 +484,7 @@ ShellCommand(struct cmdargs const *arg, int bg) argc = sizeof argv / sizeof argv[0] - 1; log_Printf(LogWARN, "Truncating shell command to %d args\n", argc); } - expand(argv, argc, arg->argv + arg->argn, arg->bundle, 0); + command_Expand(argv, argc, arg->argv + arg->argn, arg->bundle, 0); if (bg) { pid_t p; @@ -2473,7 +2473,7 @@ SetProcTitle(struct cmdargs const *arg) argc = sizeof argv / sizeof argv[0] - 1; log_Printf(LogWARN, "Truncating proc title to %d args\n", argc); } - expand(argv, argc, arg->argv + arg->argn, arg->bundle, 1); + command_Expand(argv, argc, arg->argv + arg->argn, arg->bundle, 1); ptr = title; remaining = sizeof title - 1; diff --git a/usr.sbin/ppp/ppp/command.h b/usr.sbin/ppp/ppp/command.h index e90e3c078eb..32495e93a91 100644 --- a/usr.sbin/ppp/ppp/command.h +++ b/usr.sbin/ppp/ppp/command.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: command.h,v 1.2 1999/02/06 03:22:34 brian Exp $ + * $Id: command.h,v 1.3 1999/02/11 10:14:50 brian Exp $ * * TODO: */ @@ -54,6 +54,8 @@ struct cmdtab { extern const char Version[]; extern const char VersionDate[]; +extern void command_Expand(char **, int, char const *const *, struct bundle *, + int); extern int command_Interpret(char *, int, char *vector[MAXARGS]); extern void command_Run(struct bundle *, int, char const *const *, struct prompt *, const char *, struct datalink *); diff --git a/usr.sbin/ppp/ppp/datalink.c b/usr.sbin/ppp/ppp/datalink.c index 49b15103e49..3c7636c621f 100644 --- a/usr.sbin/ppp/ppp/datalink.c +++ b/usr.sbin/ppp/ppp/datalink.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: datalink.c,v 1.10 1999/02/06 03:22:34 brian Exp $ + * $Id: datalink.c,v 1.11 1999/02/11 10:14:50 brian Exp $ */ #include <sys/param.h> @@ -335,7 +335,8 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, case DATALINK_AUTH: case DATALINK_CBCP: case DATALINK_OPEN: - result = descriptor_UpdateSet(&dl->physical->desc, r, w, e, n); + result = descriptor_UpdateSet(&dl->chap.desc, r, w, e, n) + + descriptor_UpdateSet(&dl->physical->desc, r, w, e, n); break; } return result; @@ -367,7 +368,8 @@ datalink_IsSet(struct descriptor *d, const fd_set *fdset) case DATALINK_AUTH: case DATALINK_CBCP: case DATALINK_OPEN: - return descriptor_IsSet(&dl->physical->desc, fdset); + return descriptor_IsSet(&dl->chap.desc, fdset) ? 1 : + descriptor_IsSet(&dl->physical->desc, fdset); } return 0; } @@ -393,7 +395,10 @@ datalink_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) case DATALINK_AUTH: case DATALINK_CBCP: case DATALINK_OPEN: - descriptor_Read(&dl->physical->desc, bundle, fdset); + if (descriptor_IsSet(&dl->chap.desc, fdset)) + descriptor_Read(&dl->chap.desc, bundle, fdset); + if (descriptor_IsSet(&dl->physical->desc, fdset)) + descriptor_Read(&dl->physical->desc, bundle, fdset); break; } } @@ -420,7 +425,10 @@ datalink_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset) case DATALINK_AUTH: case DATALINK_CBCP: case DATALINK_OPEN: - result = descriptor_Write(&dl->physical->desc, bundle, fdset); + if (descriptor_IsSet(&dl->chap.desc, fdset)) + result += descriptor_Write(&dl->chap.desc, bundle, fdset); + if (descriptor_IsSet(&dl->physical->desc, fdset)) + result += descriptor_Write(&dl->physical->desc, bundle, fdset); break; } @@ -541,6 +549,7 @@ void datalink_CBCPComplete(struct datalink *dl) { datalink_NewState(dl, DATALINK_LCP); + chap_ReInit(&dl->chap); fsm_Close(&dl->physical->link.lcp.fsm); } @@ -567,6 +576,7 @@ datalink_AuthOk(struct datalink *dl) /* It's not CBCP */ log_Printf(LogPHASE, "%s: Shutdown and await peer callback\n", dl->name); datalink_NewState(dl, DATALINK_LCP); + chap_ReInit(&dl->chap); fsm_Close(&dl->physical->link.lcp.fsm); } else switch (dl->physical->link.lcp.his_callback.opmask) { @@ -591,6 +601,7 @@ datalink_AuthOk(struct datalink *dl) } dl->cbcp.fsm.delay = 0; datalink_NewState(dl, DATALINK_LCP); + chap_ReInit(&dl->chap); fsm_Close(&dl->physical->link.lcp.fsm); break; @@ -603,6 +614,7 @@ datalink_AuthOk(struct datalink *dl) dl->cbcp.required = 1; dl->cbcp.fsm.delay = 0; datalink_NewState(dl, DATALINK_LCP); + chap_ReInit(&dl->chap); fsm_Close(&dl->physical->link.lcp.fsm); break; @@ -610,6 +622,7 @@ datalink_AuthOk(struct datalink *dl) log_Printf(LogPHASE, "%s: Oops - Should have NAK'd peer callback !\n", dl->name); datalink_NewState(dl, DATALINK_LCP); + chap_ReInit(&dl->chap); fsm_Close(&dl->physical->link.lcp.fsm); break; } @@ -619,6 +632,7 @@ void datalink_AuthNotOk(struct datalink *dl) { datalink_NewState(dl, DATALINK_LCP); + chap_ReInit(&dl->chap); fsm_Close(&dl->physical->link.lcp.fsm); } @@ -647,6 +661,7 @@ datalink_LayerDown(void *v, struct fsm *fp) timer_Stop(&dl->chap.auth.authtimer); } datalink_NewState(dl, DATALINK_LCP); + chap_ReInit(&dl->chap); } } @@ -877,6 +892,7 @@ datalink_Close(struct datalink *dl, int how) case DATALINK_CBCP: case DATALINK_AUTH: case DATALINK_LCP: + chap_ReInit(&dl->chap); fsm_Close(&dl->physical->link.lcp.fsm); if (how != CLOSE_NORMAL) { dl->dial_tries = -1; diff --git a/usr.sbin/ppp/ppp/defs.h b/usr.sbin/ppp/ppp/defs.h index 3255f5309a4..8285f90c84f 100644 --- a/usr.sbin/ppp/ppp/defs.h +++ b/usr.sbin/ppp/ppp/defs.h @@ -15,7 +15,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: defs.h,v 1.2 1999/02/06 03:22:35 brian Exp $ + * $Id: defs.h,v 1.3 1999/02/11 10:14:50 brian Exp $ * * TODO: */ @@ -44,7 +44,7 @@ #define DIAL_NEXT_TIMEOUT 3 /* Default Hold time to next number redial */ #define SCRIPT_LEN 512 /* Size of login scripts */ #define LINE_LEN SCRIPT_LEN /* Size of login scripts */ -#define AUTHLEN 50 /* Size of authname/authkey */ +#define AUTHLEN 100 /* Size of authname/authkey */ #define CHAPDIGESTLEN 100 /* Maximum chap digest */ #define CHAPCHALLENGELEN 48 /* Maximum chap challenge */ #define MAXARGS 40 /* How many args per config line */ diff --git a/usr.sbin/ppp/ppp/descriptor.h b/usr.sbin/ppp/ppp/descriptor.h index 875a1a018a8..6a8549b7bdd 100644 --- a/usr.sbin/ppp/ppp/descriptor.h +++ b/usr.sbin/ppp/ppp/descriptor.h @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: descriptor.h,v 1.2 1999/02/06 03:22:36 brian Exp $ + * $Id: descriptor.h,v 1.3 1999/02/11 10:14:50 brian Exp $ */ #define PHYSICAL_DESCRIPTOR (1) @@ -34,6 +34,7 @@ #define BUNDLE_DESCRIPTOR (6) #define MPSERVER_DESCRIPTOR (7) #define RADIUS_DESCRIPTOR (8) +#define CHAP_DESCRIPTOR (9) struct bundle; diff --git a/usr.sbin/ppp/ppp/hdlc.c b/usr.sbin/ppp/ppp/hdlc.c index 56e223e852b..7118e0aeeb1 100644 --- a/usr.sbin/ppp/ppp/hdlc.c +++ b/usr.sbin/ppp/ppp/hdlc.c @@ -17,7 +17,7 @@ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * - * $Id: hdlc.c,v 1.2 1999/02/06 03:22:36 brian Exp $ + * $Id: hdlc.c,v 1.3 1999/02/11 10:14:50 brian Exp $ * * TODO: */ @@ -48,12 +48,12 @@ #include "vjcomp.h" #include "auth.h" #include "pap.h" -#include "chap.h" #include "lcp.h" #include "async.h" #include "ccp.h" #include "link.h" #include "descriptor.h" +#include "chap.h" #include "physical.h" #include "prompt.h" #include "chat.h" diff --git a/usr.sbin/ppp/ppp/ppp.8 b/usr.sbin/ppp/ppp/ppp.8 index 601cf486d9e..78dd54af1f3 100644 --- a/usr.sbin/ppp/ppp/ppp.8 +++ b/usr.sbin/ppp/ppp/ppp.8 @@ -1,4 +1,4 @@ -.\" $Id: ppp.8,v 1.16 1999/02/06 03:22:42 brian Exp $ +.\" $Id: ppp.8,v 1.17 1999/02/11 10:14:50 brian Exp $ .Dd 20 September 1995 .nr XX \w'\fC00' .Os FreeBSD @@ -2854,23 +2854,73 @@ For the XON/XOFF scenario, use .Dq set accmap 000a0000 . .It set authkey|key Ar value This sets the authentication key (or password) used in client mode -PAP or CHAP negotiation to the given value. It can also be used to -specify the password to be used in the dial or login scripts in place -of the '\\P' sequence, preventing the actual password from being logged. If +PAP or CHAP negotiation to the given value. It also specifies the +password to be used in the dial or login scripts in place of the +'\\P' sequence, preventing the actual password from being logged. If .Ar command logging is in effect, .Ar value is logged as .Sq ******** for security reasons. +.Pp +If the first character of +.Ar value +is an exclaimation mark +.Pq Dq \&! , +.Nm +treats the remainder of the string as a program that must be executed +to determine the +.Dq authname +and +.Dq authkey +values. +.Pp +Ignoring the +.Dq \&! , +.Ar value +is parsed as a program to execute in the same was as the +.Dq !bg +command above, substituting special names in the same manner. Once executed, +.Nm +will feed the program three lines of input, each terminated by a newline +character: +.Bl -bullet +.It +The host name as sent in the CHAP challenge. +.It +The challenge string as sent in the CHAP challenge. +.It +The locally defined +.Dq authname . +.El +.Pp +Two lines of output are expected: +.Bl -bullet +.It +The +.Dq authname +to be sent with the CHAP response. +.It +The +.Dq authkey , +which is encrypted with the challenge and request id, the answer being sent +in the CHAP response packet. +.El +.Pp +When configuring +.Nm +in this manner, it's expected that the host challenge is a series of ascii +digits or characters. An encryption device or Secure ID card is usually +required to calculate the secret appropriate for the given challenge. .It set authname Ar id This sets the authentication id used in client mode PAP or CHAP negotiation. .Pp If used in .Fl direct -mode with PAP or CHAP enabled, +mode with CHAP enabled, .Ar id -is used in the initial authentication request and is normally set to +is used in the initial authentication challenge and should normally be set to the local machine name. .It set autoload Ar max-duration max-load [min-duration min-load] These settings apply only in multi-link mode and all default to zero. |