func (n *V1ServerSession) ProcessAuthenticateMessage(am *AuthenticateMessage) (err error) { n.authenticateMessage = am n.NegotiateFlags = am.NegotiateFlags n.clientChallenge = am.ClientChallenge() n.encryptedRandomSessionKey = am.EncryptedRandomSessionKey.Payload // Ignore the values used in SetUserInfo and use these instead from the authenticate message // They should always be correct (I hope) n.user = am.UserName.String() n.userDomain = am.DomainName.String() l4g.Info("(ProcessAuthenticateMessage)NTLM v1 User %s Domain %s", n.user, n.userDomain) err = n.fetchResponseKeys() if err != nil { return err } err = n.computeExpectedResponses() if err != nil { return err } err = n.computeSessionBaseKey() if err != nil { return err } err = n.computeKeyExchangeKey() if err != nil { return err } if !bytes.Equal(am.NtChallengeResponseFields.Payload, n.ntChallengeResponse) { // There is a bug with the steps in MS-NLMP. In section 3.2.5.1.2 it says you should fall through // to compare the lmChallengeResponse if the ntChallengeRepsonse fails, but with extended session security // this would *always* pass because the lmChallengeResponse and expectedLmChallengeRepsonse will always // be the same if !bytes.Equal(am.LmChallengeResponse.Payload, n.lmChallengeResponse) || NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY.IsSet(n.NegotiateFlags) { return errors.New("Could not authenticate") } } n.mic = am.Mic am.Mic = zeroBytes(16) err = n.computeExportedSessionKey() if err != nil { return err } if am.Version == nil { //UGH not entirely sure how this could possibly happen, going to put this in for now //TODO investigate if this ever is really happening am.Version = &VersionStruct{ProductMajorVersion: uint8(5), ProductMinorVersion: uint8(1), ProductBuild: uint16(2600), NTLMRevisionCurrent: uint8(15)} l4g.Error("Nil version in ntlmv1") } err = n.calculateKeys(am.Version.NTLMRevisionCurrent) if err != nil { return err } n.clientHandle, err = rc4Init(n.ClientSealingKey) if err != nil { return err } n.serverHandle, err = rc4Init(n.ServerSealingKey) if err != nil { return err } return nil }
func (n *V2ServerSession) ProcessAuthenticateMessage(am *AuthenticateMessage) (err error) { n.authenticateMessage = am n.NegotiateFlags = am.NegotiateFlags n.clientChallenge = am.ClientChallenge() n.encryptedRandomSessionKey = am.EncryptedRandomSessionKey.Payload // Ignore the values used in SetUserInfo and use these instead from the authenticate message // They should always be correct (I hope) n.user = am.UserName.String() n.userDomain = am.DomainName.String() l4g.Info("(ProcessAuthenticateMessage)NTLM v2 User %s Domain %s", n.user, n.userDomain) err = n.fetchResponseKeys() if err != nil { return err } timestamp := am.NtlmV2Response.NtlmV2ClientChallenge.TimeStamp avPairsBytes := am.NtlmV2Response.NtlmV2ClientChallenge.AvPairs.Bytes() err = n.computeExpectedResponses(timestamp, avPairsBytes) if err != nil { return err } if !bytes.Equal(am.NtChallengeResponseFields.Payload, n.ntChallengeResponse) { if !bytes.Equal(am.LmChallengeResponse.Payload, n.lmChallengeResponse) { return errors.New("Could not authenticate") } } err = n.computeKeyExchangeKey() if err != nil { return err } n.mic = am.Mic am.Mic = zeroBytes(16) err = n.computeExportedSessionKey() if err != nil { return err } if am.Version == nil { //UGH not entirely sure how this could possibly happen, going to put this in for now //TODO investigate if this ever is really happening am.Version = &VersionStruct{ProductMajorVersion: uint8(5), ProductMinorVersion: uint8(1), ProductBuild: uint16(2600), NTLMRevisionCurrent: uint8(15)} l4g.Error("Nil version in ntlmv2") } err = n.calculateKeys(am.Version.NTLMRevisionCurrent) if err != nil { return err } n.clientHandle, err = rc4Init(n.ClientSealingKey) if err != nil { return err } n.serverHandle, err = rc4Init(n.ServerSealingKey) if err != nil { return err } return nil }