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.
This commit is contained in:
Brian Somers 1999-02-11 10:14:08 +00:00
parent e4a5d947a3
commit 58330d7bfa
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=43888
10 changed files with 404 additions and 62 deletions

View File

@ -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.41 1999/02/07 13:48:38 brian Exp $
* $Id: chap.c,v 1.42 1999/02/07 13:56:29 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"
@ -174,6 +181,201 @@ chap_BuildAnswer(char *name, char *key, u_char id, char *challenge, int MSChap)
return result;
}
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)
{
@ -181,28 +383,29 @@ chap_Challenge(struct authinfo *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,11 +435,24 @@ 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)
{
@ -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:

View File

@ -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.10 1998/05/21 21:44:27 brian Exp $
* $Id: chap.h,v 1.11 1999/02/06 02:54:44 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 *);

View File

@ -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.178 1999/01/28 01:56:31 brian Exp $
* $Id: command.c,v 1.179 1999/01/28 09:40:15 brian Exp $
*
*/
#include <sys/param.h>
@ -138,7 +138,7 @@
#define NEG_DNS 50
const char Version[] = "2.1";
const char VersionDate[] = "$Date: 1999/01/28 01:56:31 $";
const char VersionDate[] = "$Date: 1999/01/28 09:40:15 $";
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;

View File

@ -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.14 1998/06/15 19:05:42 brian Exp $
* $Id: command.h,v 1.15 1998/06/15 19:06:06 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 *);

View File

@ -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.28 1999/02/02 09:35:17 brian Exp $
* $Id: datalink.c,v 1.29 1999/02/06 02:54:44 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;

View File

@ -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.36 1998/08/25 17:48:42 brian Exp $
* $Id: defs.h,v 1.37 1999/01/28 01:56:31 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 */

View File

@ -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.4 1998/06/24 19:33:31 brian Exp $
* $Id: descriptor.h,v 1.5 1999/02/06 02:54:45 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;

View File

@ -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.37 1999/01/28 01:56:32 brian Exp $
* $Id: hdlc.c,v 1.38 1999/02/06 02:54:45 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"

View File

@ -1,4 +1,4 @@
.\" $Id: ppp.8,v 1.143 1999/01/28 01:56:33 brian Exp $
.\" $Id: ppp.8,v 1.144 1999/01/28 22:55:08 billf 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.

View File

@ -1,4 +1,4 @@
.\" $Id: ppp.8,v 1.143 1999/01/28 01:56:33 brian Exp $
.\" $Id: ppp.8,v 1.144 1999/01/28 22:55:08 billf 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.