- ;; check if "negotiate NTLM2 key" flag is set in type 2 message
- (if (not (zerop (logand (aref flags 2) 8)))
- (let (randomString
- sessionHash)
- ;; generate NTLM2 session response data
- (setq randomString (ntlm-string-make-unibyte
- (concat
- (make-string 1 (random 256))
- (make-string 1 (random 256))
- (make-string 1 (random 256))
- (make-string 1 (random 256))
- (make-string 1 (random 256))
- (make-string 1 (random 256))
- (make-string 1 (random 256))
- (make-string 1 (random 256)))))
- (setq sessionHash (ntlm-secure-hash
- 'md5 (concat challengeData randomString)
- nil nil t))
- (setq sessionHash (substring sessionHash 0 8))
-
- (setq lmRespData (concat randomString (make-string 16 0)))
- (setq ntRespData (ntlm-smb-owf-encrypt
- (cadr password-hashes) sessionHash)))
- (progn
+ (unless (and (integerp ntlm-compatibility-level)
+ (>= ntlm-compatibility-level 0)
+ (<= ntlm-compatibility-level 5))
+ (error "Invalid ntlm-compatibility-level value"))
+ (if (and (>= ntlm-compatibility-level 3)
+ (<= ntlm-compatibility-level 5))
+ ;; extract target information block, if it is present
+ (if (< (cdr uDomain-offs) 48)
+ (error "Failed to find target information block")
+ (let* ((targetInfo-len (md4-unpack-int16 (substring rchallenge
+ 40 42)))
+ (targetInfo-offs (md4-unpack-int32 (substring rchallenge
+ 44 48)))
+ (targetInfo (substring rchallenge
+ (cdr targetInfo-offs)
+ (+ (cdr targetInfo-offs)
+ targetInfo-len)))
+ (upcase-user (upcase (ntlm-ascii2unicode user (length user))))
+ (ntlmv2-hash (hmac-md5 (concat upcase-user
+ (ntlm-ascii2unicode
+ domain (length domain)))
+ (cadr password-hashes)))
+ (nonce (ntlm-generate-nonce))
+ (blob (concat (make-string 2 1)
+ (make-string 2 0) ; blob signature
+ (make-string 4 0) ; reserved value
+ (ntlm-compute-timestamp) ; timestamp
+ nonce ; client nonce
+ (make-string 4 0) ; unknown
+ targetInfo ; target info
+ (make-string 4 0))) ; unknown
+ ;; for reference: LMv2 interim calculation
+ ;; (lm-interim (hmac-md5 (concat challengeData nonce)
+ ;; ntlmv2-hash))
+ (nt-interim (hmac-md5 (concat challengeData blob)
+ ntlmv2-hash)))
+ ;; for reference: LMv2 field, but match other clients that
+ ;; send all zeros
+ ;; (setq lmRespData (concat lm-interim nonce))
+ (setq lmRespData (make-string 24 0))
+ (setq ntRespData (concat nt-interim blob))))
+ ;; compatibility level is 2, 1 or 0
+ ;; level 2 should be treated specially but it's not clear how,
+ ;; so just treat it the same as levels 0 and 1
+ ;; check if "negotiate NTLM2 key" flag is set in type 2 message
+ (if (not (zerop (logand (aref flags 2) 8)))
+ (let (randomString
+ sessionHash)
+ ;; generate NTLM2 session response data
+ (setq randomString (ntlm-generate-nonce))
+ (setq sessionHash (ntlm-secure-hash
+ 'md5 (concat challengeData randomString)
+ nil nil t))
+ (setq sessionHash (substring sessionHash 0 8))
+ (setq lmRespData (concat randomString (make-string 16 0)))
+ (setq ntRespData (ntlm-smb-owf-encrypt
+ (cadr password-hashes) sessionHash)))