shithub: riscv

Download patch

ref: 5649042bff26fa0594217432d085b9f96b923298
parent: 91d3af942aeb9f102f3799b848f1798cc23ee002
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Jan 25 02:49:50 EST 2015

factotum: implement proto=mschapv2 client role

this is used for wpa2 enterprise peap/mschapv2. server role
is not implemented as that would require changing the
wire format on the auth server.

the naming is unfortunate as we already have proto=mschap2 which
really refers to ntlmv2.

--- a/sys/src/cmd/auth/factotum/chap.c
+++ b/sys/src/cmd/auth/factotum/chap.c
@@ -24,6 +24,7 @@
 	MShashlen = 16,
 	MSchallen = 8,
 	MSresplen = 24,
+	MSchallenv2 = 16,
 
 	Chapreplylen = MD5LEN+1,
 	MSchapreplylen = 24+24,
@@ -86,6 +87,9 @@
 	if((iscli = isclient(_strfindattr(fss->attr, "role"))) < 0)
 		return failure(fss, nil);
 
+	if(!iscli && p == &mschapv2)
+		return failure(fss, "role must be client");
+
 	s = emalloc(sizeof *s);
 	s->nresp = 0;
 	s->nsecret = 0;
@@ -92,7 +96,7 @@
 	fss->phasename = phasenames;
 	fss->maxphase = Maxphase;
 	s->asfd = -1;
-	if(p == &mschap || p == &mschap2){
+	if(p == &mschap || p == &mschapv2 || p == &mschap2){
 		s->astype = AuthMSchap;
 	}else {
 		s->astype = AuthChap;
@@ -173,8 +177,35 @@
 				if(dom == nil)
 					dom = "";
 				s->nresp = domschap2(v, user, dom, (uchar*)a, s->resp, sizeof(s->resp));
-			} else
+			}
+			else if(fss->proto == &mschapv2 || n == MSchallenv2){
+				uchar pchal[MSchallenv2];
+				DigestState *ds;
+
+				if(n < MSchallenv2)
+					break;
+				user = _strfindattr(fss->attr, "user");
+				if(user == nil)
+					break;
+
+				memrandom(pchal, MSchallenv2);
+
+				/* ChallengeHash() */
+				ds = sha1(pchal, MSchallenv2, nil, nil);
+				ds = sha1((uchar*)a, MSchallenv2, nil, ds);
+				sha1((uchar*)user, strlen(user), reply, ds);
+
+				s->nresp = domschap(v, reply, s->resp, sizeof(s->resp));
+				if(s->nresp <= 0)
+					break;
+
+				mcr = (MSchapreply*)s->resp;
+				memset(mcr->LMresp, 0, sizeof(mcr->LMresp));
+				memmove(mcr->LMresp, pchal, MSchallenv2);
+			}
+			else {
 				s->nresp = domschap(v, (uchar*)a, s->resp, sizeof(s->resp));
+			}
 			break;
 		case AuthChap:
 			if(n < ChapChallen+1)
@@ -379,8 +410,18 @@
 .keyprompt= "!password?"
 };
 
+Proto mschapv2 = {
+.name=	"mschapv2",
+.init=	chapinit,
+.write=	chapwrite,
+.read=	chapread,
+.close=	chapclose,
+.addkey= replacekey,
+.keyprompt= "user? !password?"
+};
+
 Proto mschap2 = {
-.name=	"mschap2",
+.name=	"mschap2",	/* really NTLMv2 */
 .init=	chapinit,
 .write=	chapwrite,
 .read=	chapread,
--- a/sys/src/cmd/auth/factotum/dat.h
+++ b/sys/src/cmd/auth/factotum/dat.h
@@ -225,7 +225,7 @@
 /* protocols */
 extern Proto apop, cram;		/* apop.c */
 extern Proto p9any, p9sk1, p9sk2;	/* p9sk.c */
-extern Proto chap, mschap, mschap2;	/* chap.c */
+extern Proto chap, mschap, mschapv2, mschap2;	/* chap.c */
 extern Proto p9cr, vnc;			/* p9cr.c */
 extern Proto pass;			/* pass.c */
 extern Proto rsa;			/* rsa.c */
--- a/sys/src/cmd/auth/factotum/fs.c
+++ b/sys/src/cmd/auth/factotum/fs.c
@@ -31,6 +31,7 @@
 	&cram,
 	&httpdigest,
 	&mschap,
+	&mschapv2,
 	&mschap2,
 	&p9any,
 	&p9cr,