diff -r fce5d1b1fdfc sys/src/cmd/auth/authsrv.c --- a/sys/src/cmd/auth/authsrv.c Sun May 20 03:48:33 2018 +0200 +++ b/sys/src/cmd/auth/authsrv.c Sun May 20 18:28:59 2018 +0200 @@ -776,6 +776,7 @@ } if(ntbloblen > 0){ + /* NTLMv2 */ getname(MsvAvNbDomainName, ntblob, ntbloblen, windom, sizeof(windom)); for(;;){ ntv2hash(hash, secret, tr->uid, windom); @@ -807,6 +808,7 @@ } dupe = 0; } else if(nchal == MSchallenv2){ + /* MSCHAPv2 */ s = sha1((uchar*)reply.LMresp, nchal, nil, nil); s = sha1(chal, nchal, nil, s); sha1((uchar*)tr->uid, strlen(tr->uid), chash, s); @@ -815,7 +817,27 @@ mschalresp(resp, hash, chash); ntok = lmok = tsmemcmp(resp, reply.NTresp, MSresplen) == 0; dupe = 0; + } else if(tsmemcmp(reply.NTresp, zeros, MSresplen) == 0){ + /* LMv2 */ + safecpy(windom, tr->authdom, sizeof(windom)); + for(;;){ + ntv2hash(hash, secret, tr->uid, windom); + + /* + * LmResponse = Cat(HMAC_MD5(LmHash, Cat(SC, CC)), CC) + */ + s = hmac_md5(chal, nchal, hash, MShashlen, nil, nil); + hmac_md5((uchar*)reply.LMresp+16, nchal, hash, MShashlen, resp, s); + lmok = ntok = tsmemcmp(resp, reply.LMresp, 16) == 0; + + if(lmok || windom[0] == '\0') + break; + + windom[0] = '\0'; /* try NIL domain */ + } + dupe = 0; } else { + /* LM+NTLM */ lmhash(hash, secret); mschalresp(resp, hash, chal); lmok = tsmemcmp(resp, reply.LMresp, MSresplen) == 0;