ppp: mschapv2 support
This commit is contained in:
parent
3004f058f6
commit
98b1f2a75b
|
@ -120,7 +120,7 @@ static void uncresetack(void*, Block*);
|
||||||
static int ipcheck(uchar*, int);
|
static int ipcheck(uchar*, int);
|
||||||
static void hischeck(Uncstate*);
|
static void hischeck(Uncstate*);
|
||||||
|
|
||||||
static void setkey(uchar *key, uchar *startkey);
|
static void setkey(uchar *key, uchar *startkey);
|
||||||
|
|
||||||
Comptype cmppc = {
|
Comptype cmppc = {
|
||||||
compinit,
|
compinit,
|
||||||
|
@ -155,8 +155,8 @@ compinit(PPP *ppp)
|
||||||
|
|
||||||
if(ppp->sendencrypted) {
|
if(ppp->sendencrypted) {
|
||||||
cs->encrypt = 1;
|
cs->encrypt = 1;
|
||||||
memmove(cs->startkey, ppp->key, 16);
|
memmove(cs->startkey, ppp->sendkey, 16);
|
||||||
memmove(cs->key, ppp->key, 16);
|
memmove(cs->key, cs->startkey, 16);
|
||||||
setkey(cs->key, cs->startkey);
|
setkey(cs->key, cs->startkey);
|
||||||
setupRC4state(&cs->rc4key, cs->key, 16);
|
setupRC4state(&cs->rc4key, cs->key, 16);
|
||||||
}
|
}
|
||||||
|
@ -467,8 +467,8 @@ uncinit(PPP *ppp)
|
||||||
s = mallocz(sizeof(Uncstate), 1);
|
s = mallocz(sizeof(Uncstate), 1);
|
||||||
|
|
||||||
s->count = 0xfff; /* count of non existant last packet */
|
s->count = 0xfff; /* count of non existant last packet */
|
||||||
memmove(s->startkey, ppp->key, 16);
|
memmove(s->startkey, ppp->recvkey, 16);
|
||||||
memmove(s->key, ppp->key, 16);
|
memmove(s->key, s->startkey, 16);
|
||||||
setkey(s->key, s->startkey);
|
setkey(s->key, s->startkey);
|
||||||
setupRC4state(&s->rc4key, s->key, 16);
|
setupRC4state(&s->rc4key, s->key, 16);
|
||||||
|
|
||||||
|
@ -577,12 +577,11 @@ netlog("******* bad count - got %ux expected %ux\n", count&0xfff, ecount);
|
||||||
if(count & Pencrypt) {
|
if(count & Pencrypt) {
|
||||||
//netlog("mppc unencrypt count = %ux\n", count);
|
//netlog("mppc unencrypt count = %ux\n", count);
|
||||||
rc4(&s->rc4key, p, n);
|
rc4(&s->rc4key, p, n);
|
||||||
|
fprint(2, "plain=%.*H\n", n, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!(count & Pcompress)) {
|
if(!(count & Pcompress))
|
||||||
//netlog("uncompress blen = %d\n", BLEN(b));
|
return b;
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
bits = 0;
|
bits = 0;
|
||||||
sreg = 0;
|
sreg = 0;
|
||||||
|
@ -729,6 +728,27 @@ uncfini(void *as)
|
||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
getasymkey(uchar *key, uchar *masterkey, int send, int server)
|
||||||
|
{
|
||||||
|
uchar digest[SHA1dlen];
|
||||||
|
uchar pad[40];
|
||||||
|
SHAstate *s;
|
||||||
|
char *m;
|
||||||
|
|
||||||
|
s = sha1(masterkey, 16, nil, nil);
|
||||||
|
memset(pad, 0, 40);
|
||||||
|
sha1(pad, 40, nil, s);
|
||||||
|
if(send ^ server)
|
||||||
|
m = "On the client side, this is the send key; on the server side, it is the receive key.";
|
||||||
|
else
|
||||||
|
m = "On the client side, this is the receive key; on the server side, it is the send key.";
|
||||||
|
sha1((uchar*)m, 84, nil, s);
|
||||||
|
memset(pad, 0xf2, 40);
|
||||||
|
sha1(pad, 40, digest, s);
|
||||||
|
memmove(key, digest, 16);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setkey(uchar *key, uchar *startkey)
|
setkey(uchar *key, uchar *startkey)
|
||||||
{
|
{
|
||||||
|
|
|
@ -114,7 +114,6 @@ static void setphase(PPP*, int);
|
||||||
static void terminate(PPP*, int);
|
static void terminate(PPP*, int);
|
||||||
static int validv4(Ipaddr);
|
static int validv4(Ipaddr);
|
||||||
static void dmppkt(char *s, uchar *a, int na);
|
static void dmppkt(char *s, uchar *a, int na);
|
||||||
static void getauth(PPP*);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
pppopen(PPP *ppp, int mediain, int mediaout, char *net,
|
pppopen(PPP *ppp, int mediain, int mediaout, char *net,
|
||||||
|
@ -191,7 +190,7 @@ init(PPP* ppp)
|
||||||
ppp->chap = mallocz(sizeof(*ppp->chap), 1);
|
ppp->chap = mallocz(sizeof(*ppp->chap), 1);
|
||||||
if(ppp->chap == nil)
|
if(ppp->chap == nil)
|
||||||
abort();
|
abort();
|
||||||
ppp->chap->proto = APmschap;
|
ppp->chap->proto = APmschapv2;
|
||||||
ppp->chap->state = Cunauth;
|
ppp->chap->state = Cunauth;
|
||||||
auth_freechal(ppp->chap->cs);
|
auth_freechal(ppp->chap->cs);
|
||||||
ppp->chap->cs = nil;
|
ppp->chap->cs = nil;
|
||||||
|
@ -252,6 +251,7 @@ setphase(PPP *ppp, int phase)
|
||||||
break;
|
break;
|
||||||
case APmd5:
|
case APmd5:
|
||||||
case APmschap:
|
case APmschap:
|
||||||
|
case APmschapv2:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
setphase(ppp, Pnet);
|
setphase(ppp, Pnet);
|
||||||
|
@ -713,6 +713,7 @@ config(PPP *ppp, Pstate *p, int newid)
|
||||||
syslog(0, "ppp", "requesting %I", ppp->local);
|
syslog(0, "ppp", "requesting %I", ppp->local);
|
||||||
putv4o(b, Oipaddr, ppp->local);
|
putv4o(b, Oipaddr, ppp->local);
|
||||||
}
|
}
|
||||||
|
primary = 1;
|
||||||
if(primary && (p->optmask & Fipdns))
|
if(primary && (p->optmask & Fipdns))
|
||||||
putv4o(b, Oipdns, ppp->dns[0]);
|
putv4o(b, Oipdns, ppp->dns[0]);
|
||||||
if(primary && (p->optmask & Fipdns2))
|
if(primary && (p->optmask & Fipdns2))
|
||||||
|
@ -852,15 +853,15 @@ getopts(PPP *ppp, Pstate *p, Block *b)
|
||||||
}
|
}
|
||||||
if(proto != Pchap)
|
if(proto != Pchap)
|
||||||
break;
|
break;
|
||||||
if(o->data[2] != APmd5 && o->data[2] != APmschap)
|
if(o->data[2] != APmd5
|
||||||
|
&& o->data[2] != APmschap
|
||||||
|
&& o->data[2] != APmschapv2)
|
||||||
break;
|
break;
|
||||||
chapproto = o->data[2];
|
chapproto = o->data[2];
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Pccp:
|
case Pccp:
|
||||||
if(nocompress)
|
|
||||||
break;
|
|
||||||
switch(o->type){
|
switch(o->type){
|
||||||
case Octhwack:
|
case Octhwack:
|
||||||
break;
|
break;
|
||||||
|
@ -880,10 +881,6 @@ getopts(PPP *ppp, Pstate *p, Block *b)
|
||||||
case Ocmppc:
|
case Ocmppc:
|
||||||
x = nhgetl(o->data);
|
x = nhgetl(o->data);
|
||||||
|
|
||||||
// hack for Mac
|
|
||||||
// if(x == 0)
|
|
||||||
// continue;
|
|
||||||
|
|
||||||
/* stop ppp loops */
|
/* stop ppp loops */
|
||||||
if((x&0x41) == 0 || ppp->ctries++ > 5) {
|
if((x&0x41) == 0 || ppp->ctries++ > 5) {
|
||||||
/*
|
/*
|
||||||
|
@ -895,7 +892,7 @@ getopts(PPP *ppp, Pstate *p, Block *b)
|
||||||
}
|
}
|
||||||
if(rejecting)
|
if(rejecting)
|
||||||
continue;
|
continue;
|
||||||
if(x & 1) {
|
if((x & 0x01000001) == 1){
|
||||||
ctype = &cmppc;
|
ctype = &cmppc;
|
||||||
ppp->sendencrypted = (o->data[3]&0x40) == 0x40;
|
ppp->sendencrypted = (o->data[3]&0x40) == 0x40;
|
||||||
continue;
|
continue;
|
||||||
|
@ -1965,6 +1962,20 @@ putlqm(PPP *ppp)
|
||||||
ppp->out.reports++;
|
ppp->out.reports++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char*
|
||||||
|
getaproto(int proto)
|
||||||
|
{
|
||||||
|
switch(proto){
|
||||||
|
case APmd5:
|
||||||
|
return "chap";
|
||||||
|
case APmschap:
|
||||||
|
return "mschap";
|
||||||
|
case APmschapv2:
|
||||||
|
return "mschapv2";
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* init challenge response dialog
|
* init challenge response dialog
|
||||||
*/
|
*/
|
||||||
|
@ -1975,24 +1986,14 @@ chapinit(PPP *ppp)
|
||||||
Lcpmsg *m;
|
Lcpmsg *m;
|
||||||
Chap *c;
|
Chap *c;
|
||||||
int len;
|
int len;
|
||||||
char *aproto;
|
|
||||||
|
|
||||||
getauth(ppp);
|
|
||||||
|
|
||||||
c = ppp->chap;
|
c = ppp->chap;
|
||||||
c->id++;
|
c->id++;
|
||||||
|
if(c->ai != nil){
|
||||||
switch(c->proto){
|
auth_freeAI(c->ai);
|
||||||
default:
|
c->ai = nil;
|
||||||
abort();
|
|
||||||
case APmd5:
|
|
||||||
aproto = "chap";
|
|
||||||
break;
|
|
||||||
case APmschap:
|
|
||||||
aproto = "mschap";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if((c->cs = auth_challenge("proto=%q role=server", aproto)) == nil)
|
if((c->cs = auth_challenge("proto=%q role=server", getaproto(c->proto))) == nil)
|
||||||
sysfatal("auth_challenge: %r");
|
sysfatal("auth_challenge: %r");
|
||||||
syslog(0, LOG, ": remote=%I: sending %d byte challenge", ppp->remote, c->cs->nchal);
|
syslog(0, LOG, ": remote=%I: sending %d byte challenge", ppp->remote, c->cs->nchal);
|
||||||
len = 4 + 1 + c->cs->nchal + strlen(ppp->chapname);
|
len = 4 + 1 + c->cs->nchal + strlen(ppp->chapname);
|
||||||
|
@ -2010,73 +2011,43 @@ chapinit(PPP *ppp)
|
||||||
c->state = Cchalsent;
|
c->state = Cchalsent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* BUG factotum should do this
|
|
||||||
*/
|
|
||||||
enum {
|
|
||||||
MShashlen = 16,
|
|
||||||
MSresplen = 24,
|
|
||||||
MSchallen = 8,
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
desencrypt(uchar data[8], uchar key[7])
|
|
||||||
{
|
|
||||||
ulong ekey[32];
|
|
||||||
|
|
||||||
key_setup(key, ekey);
|
|
||||||
block_cipher(ekey, data, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nthash(uchar hash[MShashlen], char *passwd)
|
|
||||||
{
|
|
||||||
uchar buf[512];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for(i=0; *passwd && i<sizeof(buf); passwd++) {
|
|
||||||
buf[i++] = *passwd;
|
|
||||||
buf[i++] = 0;
|
|
||||||
}
|
|
||||||
memset(hash, 0, 16);
|
|
||||||
md4(buf, i, hash, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
mschalresp(uchar resp[MSresplen], uchar hash[MShashlen], uchar chal[MSchallen])
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
uchar buf[21];
|
|
||||||
|
|
||||||
memset(buf, 0, sizeof(buf));
|
|
||||||
memcpy(buf, hash, MShashlen);
|
|
||||||
|
|
||||||
for(i=0; i<3; i++) {
|
|
||||||
memmove(resp+i*MSchallen, chal, MSchallen);
|
|
||||||
desencrypt(resp+i*MSchallen, buf+i*7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* challenge response dialog
|
* challenge response dialog
|
||||||
*/
|
*/
|
||||||
extern int _asrdresp(int, uchar*, int);
|
static void
|
||||||
|
setppekey(PPP *ppp, int isserver)
|
||||||
|
{
|
||||||
|
Chap *c = ppp->chap;
|
||||||
|
|
||||||
|
switch(c->proto){
|
||||||
|
case APmschap:
|
||||||
|
if(c->ai == nil || c->ai->nsecret != 16)
|
||||||
|
sysfatal("could not get the encryption key");
|
||||||
|
memmove(ppp->sendkey, c->ai->secret, 16);
|
||||||
|
memmove(ppp->recvkey, c->ai->secret, 16);
|
||||||
|
break;
|
||||||
|
case APmschapv2:
|
||||||
|
if(c->ai == nil || c->ai->nsecret != 16+20)
|
||||||
|
sysfatal("could not get the encryption key + authenticator");
|
||||||
|
getasymkey(ppp->sendkey, c->ai->secret, 1, isserver);
|
||||||
|
getasymkey(ppp->recvkey, c->ai->secret, 0, isserver);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
auth_freeAI(c->ai);
|
||||||
|
c->ai = nil;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
getchap(PPP *ppp, Block *b)
|
getchap(PPP *ppp, Block *b)
|
||||||
{
|
{
|
||||||
AuthInfo *ai;
|
|
||||||
Lcpmsg *m;
|
Lcpmsg *m;
|
||||||
int len, vlen, i, id, n, nresp;
|
int len, vlen, i, id, n, nresp;
|
||||||
char md5buf[512], code;
|
char code;
|
||||||
Chap *c;
|
Chap *c;
|
||||||
Chapreply cr;
|
Chapreply cr;
|
||||||
MSchapreply mscr;
|
MSchapreply mscr;
|
||||||
char uid[PATH];
|
char uid[PATH];
|
||||||
uchar digest[16], *p, *resp, sdigest[SHA1dlen];
|
uchar resp[256], *p;
|
||||||
uchar mshash[MShashlen], mshash2[MShashlen];
|
|
||||||
DigestState *s;
|
|
||||||
uchar msresp[2*MSresplen+1];
|
|
||||||
|
|
||||||
m = (Lcpmsg*)b->rptr;
|
m = (Lcpmsg*)b->rptr;
|
||||||
len = nhgets(m->len);
|
len = nhgets(m->len);
|
||||||
|
@ -2087,50 +2058,23 @@ getchap(PPP *ppp, Block *b)
|
||||||
}
|
}
|
||||||
|
|
||||||
qlock(ppp);
|
qlock(ppp);
|
||||||
|
c = ppp->chap;
|
||||||
|
vlen = m->data[0];
|
||||||
switch(m->code){
|
switch(m->code){
|
||||||
case Cchallenge:
|
case Cchallenge:
|
||||||
getauth(ppp);
|
|
||||||
|
|
||||||
vlen = m->data[0];
|
|
||||||
if(vlen > len - 5) {
|
|
||||||
netlog("PPP: chap: bad challenge len\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
id = m->id;
|
id = m->id;
|
||||||
switch(ppp->chap->proto){
|
memset(ppp->chapname, 0, sizeof(ppp->chapname));
|
||||||
default:
|
nresp = auth_respondAI(m->data+1, vlen,
|
||||||
abort();
|
ppp->chapname, sizeof(ppp->chapname),
|
||||||
case APmd5:
|
resp, sizeof(resp), &c->ai,
|
||||||
n = strlen(ppp->secret);
|
auth_getkey,
|
||||||
if(n + vlen + 1 > sizeof(md5buf)) {
|
"proto=%s role=client service=ppp %s", getaproto(c->proto), keyspec);
|
||||||
netlog("PPP: chap: bad challenge len\n");
|
if(nresp < 0)
|
||||||
goto end;
|
sysfatal("auth_respond: %r");
|
||||||
}
|
if(c->proto == APmschap || c->proto == APmschapv2)
|
||||||
md5buf[0] = m->id;
|
while(nresp < 49) resp[nresp++] = 0;
|
||||||
memcpy(md5buf+1, ppp->secret, n);
|
|
||||||
memcpy(md5buf+1+n, m->data+1, vlen);
|
|
||||||
md5((uchar*)md5buf, n + vlen + 1, digest, nil);
|
|
||||||
resp = digest;
|
|
||||||
nresp = 16;
|
|
||||||
break;
|
|
||||||
case APmschap:
|
|
||||||
nthash(mshash, ppp->secret);
|
|
||||||
memset(msresp, 0, sizeof msresp);
|
|
||||||
mschalresp(msresp+MSresplen, mshash, m->data+1);
|
|
||||||
resp = msresp;
|
|
||||||
nresp = sizeof msresp;
|
|
||||||
nthash(mshash, ppp->secret);
|
|
||||||
md4(mshash, 16, mshash2, 0);
|
|
||||||
s = sha1(mshash2, 16, 0, 0);
|
|
||||||
sha1(mshash2, 16, 0, s);
|
|
||||||
sha1(m->data+1, 8, sdigest, s);
|
|
||||||
memmove(ppp->key, sdigest, 16);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
len = 4 + 1 + nresp + strlen(ppp->chapname);
|
|
||||||
freeb(b);
|
freeb(b);
|
||||||
|
len = 4 + 1 + nresp + strlen(ppp->chapname);
|
||||||
b = alloclcp(Cresponse, id, len, &m);
|
b = alloclcp(Cresponse, id, len, &m);
|
||||||
*b->wptr++ = nresp;
|
*b->wptr++ = nresp;
|
||||||
memmove(b->wptr, resp, nresp);
|
memmove(b->wptr, resp, nresp);
|
||||||
|
@ -2138,14 +2082,12 @@ getchap(PPP *ppp, Block *b)
|
||||||
memmove(b->wptr, ppp->chapname, strlen(ppp->chapname));
|
memmove(b->wptr, ppp->chapname, strlen(ppp->chapname));
|
||||||
b->wptr += strlen(ppp->chapname);
|
b->wptr += strlen(ppp->chapname);
|
||||||
hnputs(m->len, len);
|
hnputs(m->len, len);
|
||||||
netlog("PPP: sending response len %d\n", len);
|
netlog("ppp: sending response len %d\n", len);
|
||||||
putframe(ppp, Pchap, b);
|
putframe(ppp, Pchap, b);
|
||||||
break;
|
break;
|
||||||
case Cresponse:
|
case Cresponse:
|
||||||
c = ppp->chap;
|
if(m->id != c->id || c->cs == nil) {
|
||||||
vlen = m->data[0];
|
netlog("ppp: chap: bad response id\n");
|
||||||
if(m->id != c->id) {
|
|
||||||
netlog("PPP: chap: bad response id\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
switch(c->proto) {
|
switch(c->proto) {
|
||||||
|
@ -2153,10 +2095,9 @@ getchap(PPP *ppp, Block *b)
|
||||||
sysfatal("unknown chap protocol: %d", c->proto);
|
sysfatal("unknown chap protocol: %d", c->proto);
|
||||||
case APmd5:
|
case APmd5:
|
||||||
if(vlen > len - 5 || vlen != 16) {
|
if(vlen > len - 5 || vlen != 16) {
|
||||||
netlog("PPP: chap: bad response len\n");
|
netlog("ppp: chap: bad response len\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr.id = m->id;
|
cr.id = m->id;
|
||||||
memmove(cr.resp, m->data+1, 16);
|
memmove(cr.resp, m->data+1, 16);
|
||||||
memset(uid, 0, sizeof(uid));
|
memset(uid, 0, sizeof(uid));
|
||||||
|
@ -2169,8 +2110,9 @@ getchap(PPP *ppp, Block *b)
|
||||||
c->cs->nresp = sizeof cr;
|
c->cs->nresp = sizeof cr;
|
||||||
break;
|
break;
|
||||||
case APmschap:
|
case APmschap:
|
||||||
if(vlen > len - 5 || vlen != 49) {
|
case APmschapv2:
|
||||||
netlog("PPP: chap: bad response len\n");
|
if(vlen > len - 5 || vlen < 48) {
|
||||||
|
netlog("ppp: chap: bad response len\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
memset(&mscr, 0, sizeof(mscr));
|
memset(&mscr, 0, sizeof(mscr));
|
||||||
|
@ -2196,42 +2138,53 @@ getchap(PPP *ppp, Block *b)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
syslog(0, LOG, ": remote=%I vlen %d proto %d response user %s nresp %d", ppp->remote, vlen, c->proto, c->cs->user, c->cs->nresp);
|
syslog(0, LOG, ": remote=%I vlen %d proto %d response user %s nresp %d",
|
||||||
if((ai = auth_response(c->cs)) == nil || auth_chuid(ai, nil) < 0){
|
ppp->remote, vlen, c->proto, c->cs->user, c->cs->nresp);
|
||||||
|
|
||||||
|
if((c->ai = auth_response(c->cs)) == nil || auth_chuid(c->ai, nil) < 0){
|
||||||
c->state = Cunauth;
|
c->state = Cunauth;
|
||||||
code = Cfailure;
|
code = Cfailure;
|
||||||
syslog(0, LOG, ": remote=%I: auth failed: %r, uid=%s", ppp->remote, uid);
|
syslog(0, LOG, ": remote=%I: auth failed: %r, uid=%s",
|
||||||
|
ppp->remote, uid);
|
||||||
}else{
|
}else{
|
||||||
c->state = Cauthok;
|
c->state = Cauthok;
|
||||||
code = Csuccess;
|
code = Csuccess;
|
||||||
syslog(0, LOG, ": remote=%I: auth ok: uid=%s nsecret=%d", ppp->remote, uid, ai->nsecret);
|
syslog(0, LOG, ": remote=%I: auth ok: uid=%s nsecret=%d",
|
||||||
if(c->proto == APmschap){
|
ppp->remote, uid, c->ai->nsecret);
|
||||||
if(ai->nsecret != sizeof(ppp->key))
|
|
||||||
sysfatal("could not get the encryption key");
|
|
||||||
memmove(ppp->key, ai->secret, sizeof(ppp->key));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
auth_freeAI(ai);
|
|
||||||
auth_freechal(c->cs);
|
auth_freechal(c->cs);
|
||||||
c->cs = nil;
|
c->cs = nil;
|
||||||
freeb(b);
|
freeb(b);
|
||||||
|
|
||||||
/* send reply */
|
/* send reply */
|
||||||
len = 4;
|
if(code == Csuccess && c->proto == APmschapv2 && c->ai->nsecret == 16+20){
|
||||||
b = alloclcp(code, c->id, len, &m);
|
b = alloclcp(code, c->id, 4+2+2*20+1, &m);
|
||||||
hnputs(m->len, len);
|
b->wptr += sprint((char*)m->data, "S=%.20H", c->ai->secret+16);
|
||||||
|
} else {
|
||||||
|
b = alloclcp(code, c->id, 4, &m);
|
||||||
|
}
|
||||||
|
hnputs(m->len, BLEN(b));
|
||||||
putframe(ppp, Pchap, b);
|
putframe(ppp, Pchap, b);
|
||||||
|
|
||||||
if(c->state == Cauthok) {
|
if(c->state == Cauthok){
|
||||||
|
setppekey(ppp, 1);
|
||||||
setphase(ppp, Pnet);
|
setphase(ppp, Pnet);
|
||||||
} else {
|
} else {
|
||||||
/* restart chapp negotiation */
|
/* restart chapp negotiation */
|
||||||
chapinit(ppp);
|
chapinit(ppp);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case Csuccess:
|
case Csuccess:
|
||||||
|
if(c->proto == APmschapv2 && c->ai != nil && c->ai->nsecret == 16+20){
|
||||||
|
n = snprint((char*)resp, sizeof(resp), "S=%.20H", c->ai->secret+16);
|
||||||
|
if(len - 4 < n || tsmemcmp(m->data, resp, n) != 0){
|
||||||
|
netlog("ppp: chap: bad authenticator\n");
|
||||||
|
terminate(ppp, 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
netlog("ppp: chap succeeded\n");
|
netlog("ppp: chap succeeded\n");
|
||||||
|
setppekey(ppp, 0);
|
||||||
setphase(ppp, Pnet);
|
setphase(ppp, Pnet);
|
||||||
break;
|
break;
|
||||||
case Cfailure:
|
case Cfailure:
|
||||||
|
@ -2242,7 +2195,6 @@ getchap(PPP *ppp, Block *b)
|
||||||
syslog(0, LOG, "chap code %d?", m->code);
|
syslog(0, LOG, "chap code %d?", m->code);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
end:
|
|
||||||
qunlock(ppp);
|
qunlock(ppp);
|
||||||
freeb(b);
|
freeb(b);
|
||||||
}
|
}
|
||||||
|
@ -2253,27 +2205,32 @@ putpaprequest(PPP *ppp)
|
||||||
Block *b;
|
Block *b;
|
||||||
Lcpmsg *m;
|
Lcpmsg *m;
|
||||||
Chap *c;
|
Chap *c;
|
||||||
|
UserPasswd *up;
|
||||||
int len, nlen, slen;
|
int len, nlen, slen;
|
||||||
|
|
||||||
getauth(ppp);
|
up = auth_getuserpasswd(auth_getkey, "proto=pass service=ppp %s", keyspec);
|
||||||
|
if(up == nil)
|
||||||
|
sysfatal("auth_getuserpasswd: %r");
|
||||||
|
|
||||||
c = ppp->chap;
|
c = ppp->chap;
|
||||||
c->id++;
|
c->id++;
|
||||||
netlog("PPP: pap: send authreq %d %s %s\n", c->id, ppp->chapname, "****");
|
netlog("ppp: pap: send authreq %d %s %s\n", c->id, up->user, "****");
|
||||||
|
|
||||||
nlen = strlen(ppp->chapname);
|
nlen = strlen(up->user);
|
||||||
slen = strlen(ppp->secret);
|
slen = strlen(up->passwd);
|
||||||
len = 4 + 1 + nlen + 1 + slen;
|
len = 4 + 1 + nlen + 1 + slen;
|
||||||
b = alloclcp(Pauthreq, c->id, len, &m);
|
b = alloclcp(Pauthreq, c->id, len, &m);
|
||||||
|
|
||||||
*b->wptr++ = nlen;
|
*b->wptr++ = nlen;
|
||||||
memmove(b->wptr, ppp->chapname, nlen);
|
memmove(b->wptr, up->user, nlen);
|
||||||
b->wptr += nlen;
|
b->wptr += nlen;
|
||||||
*b->wptr++ = slen;
|
*b->wptr++ = slen;
|
||||||
memmove(b->wptr, ppp->secret, slen);
|
memmove(b->wptr, up->passwd, slen);
|
||||||
b->wptr += slen;
|
b->wptr += slen;
|
||||||
hnputs(m->len, len);
|
hnputs(m->len, len);
|
||||||
|
|
||||||
|
free(up);
|
||||||
|
|
||||||
putframe(ppp, Ppasswd, b);
|
putframe(ppp, Ppasswd, b);
|
||||||
freeb(b);
|
freeb(b);
|
||||||
}
|
}
|
||||||
|
@ -2304,13 +2261,13 @@ getpap(PPP *ppp, Block *b)
|
||||||
qlock(ppp);
|
qlock(ppp);
|
||||||
switch(m->code){
|
switch(m->code){
|
||||||
case Pauthreq:
|
case Pauthreq:
|
||||||
netlog("PPP: pap auth request, not supported\n");
|
netlog("ppp: pap auth request, not supported\n");
|
||||||
break;
|
break;
|
||||||
case Pauthack:
|
case Pauthack:
|
||||||
if(ppp->phase == Pauth
|
if(ppp->phase == Pauth
|
||||||
&& ppp->chap->proto == APpasswd
|
&& ppp->chap->proto == APpasswd
|
||||||
&& m->id <= ppp-> chap->id){
|
&& m->id <= ppp-> chap->id){
|
||||||
netlog("PPP: pap succeeded\n");
|
netlog("ppp: pap succeeded\n");
|
||||||
setphase(ppp, Pnet);
|
setphase(ppp, Pnet);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2318,13 +2275,13 @@ getpap(PPP *ppp, Block *b)
|
||||||
if(ppp->phase == Pauth
|
if(ppp->phase == Pauth
|
||||||
&& ppp->chap->proto == APpasswd
|
&& ppp->chap->proto == APpasswd
|
||||||
&& m->id <= ppp-> chap->id){
|
&& m->id <= ppp-> chap->id){
|
||||||
netlog("PPP: pap failed (%d:%.*s)\n",
|
netlog("ppp: pap failed (%d:%.*s)\n",
|
||||||
m->data[0], m->data[0], (char*)m->data+1);
|
m->data[0], m->data[0], (char*)m->data+1);
|
||||||
terminate(ppp, 0);
|
terminate(ppp, 0);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
netlog("PPP: unknown pap messsage %d\n", m->code);
|
netlog("ppp: unknown pap messsage %d\n", m->code);
|
||||||
}
|
}
|
||||||
qunlock(ppp);
|
qunlock(ppp);
|
||||||
freeb(b);
|
freeb(b);
|
||||||
|
@ -2702,6 +2659,7 @@ main(int argc, char **argv)
|
||||||
fmtinstall('I', eipfmt);
|
fmtinstall('I', eipfmt);
|
||||||
fmtinstall('V', eipfmt);
|
fmtinstall('V', eipfmt);
|
||||||
fmtinstall('E', eipfmt);
|
fmtinstall('E', eipfmt);
|
||||||
|
fmtinstall('H', encodefmt);
|
||||||
|
|
||||||
dev = nil;
|
dev = nil;
|
||||||
|
|
||||||
|
@ -2970,18 +2928,3 @@ putndb(PPP *ppp, char *net)
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
getauth(PPP *ppp)
|
|
||||||
{
|
|
||||||
UserPasswd *up;
|
|
||||||
|
|
||||||
if(*ppp->chapname)
|
|
||||||
return;
|
|
||||||
|
|
||||||
up = auth_getuserpasswd(auth_getkey,"proto=pass service=ppp %s", keyspec);
|
|
||||||
if(up != nil){
|
|
||||||
strcpy(ppp->chapname, up->user);
|
|
||||||
strcpy(ppp->secret, up->passwd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -113,6 +113,7 @@ enum {
|
||||||
/* authentication protocols */
|
/* authentication protocols */
|
||||||
APmd5= 5,
|
APmd5= 5,
|
||||||
APmschap= 128,
|
APmschap= 128,
|
||||||
|
APmschapv2= 129,
|
||||||
APpasswd= Ppasswd, /* use Pap, not Chap */
|
APpasswd= Ppasswd, /* use Pap, not Chap */
|
||||||
|
|
||||||
/* lcp flags */
|
/* lcp flags */
|
||||||
|
@ -221,7 +222,8 @@ struct Chap
|
||||||
int state; /* chap state */
|
int state; /* chap state */
|
||||||
uchar id; /* id of current message */
|
uchar id; /* id of current message */
|
||||||
int timeout; /* for current state */
|
int timeout; /* for current state */
|
||||||
Chalstate *cs;
|
AuthInfo *ai;
|
||||||
|
Chalstate *cs;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Qualstats
|
struct Qualstats
|
||||||
|
@ -292,11 +294,11 @@ struct PPP
|
||||||
void *uncstate; /* uncompression state */
|
void *uncstate; /* uncompression state */
|
||||||
|
|
||||||
/* encryption key */
|
/* encryption key */
|
||||||
uchar key[16];
|
uchar sendkey[16];
|
||||||
|
uchar recvkey[16];
|
||||||
int sendencrypted;
|
int sendencrypted;
|
||||||
|
|
||||||
/* authentication */
|
/* authentication */
|
||||||
char secret[256]; /* md5 key */
|
|
||||||
char chapname[256]; /* chap system name */
|
char chapname[256]; /* chap system name */
|
||||||
|
|
||||||
/* link quality monitoring */
|
/* link quality monitoring */
|
||||||
|
@ -374,6 +376,8 @@ extern ushort ptclcsum(Block*, int, int);
|
||||||
extern ushort ptclbsum(uchar*, int);
|
extern ushort ptclbsum(uchar*, int);
|
||||||
extern ushort ipcsum(uchar*);
|
extern ushort ipcsum(uchar*);
|
||||||
|
|
||||||
|
void getasymkey(uchar *key, uchar *masterkey, int send, int server);
|
||||||
|
|
||||||
extern Comptype cmppc;
|
extern Comptype cmppc;
|
||||||
extern Uncomptype uncmppc;
|
extern Uncomptype uncmppc;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue