diff options
Diffstat (limited to 'vendor/github.com/denisenkom/go-mssqldb/ntlm.go')
-rw-r--r-- | vendor/github.com/denisenkom/go-mssqldb/ntlm.go | 283 |
1 files changed, 0 insertions, 283 deletions
diff --git a/vendor/github.com/denisenkom/go-mssqldb/ntlm.go b/vendor/github.com/denisenkom/go-mssqldb/ntlm.go deleted file mode 100644 index f853435c..00000000 --- a/vendor/github.com/denisenkom/go-mssqldb/ntlm.go +++ /dev/null @@ -1,283 +0,0 @@ -// +build !windows - -package mssql - -import ( - "crypto/des" - "crypto/md5" - "crypto/rand" - "encoding/binary" - "errors" - "strings" - "unicode/utf16" - - "golang.org/x/crypto/md4" -) - -const ( - NEGOTIATE_MESSAGE = 1 - CHALLENGE_MESSAGE = 2 - AUTHENTICATE_MESSAGE = 3 -) - -const ( - NEGOTIATE_UNICODE = 0x00000001 - NEGOTIATE_OEM = 0x00000002 - NEGOTIATE_TARGET = 0x00000004 - NEGOTIATE_SIGN = 0x00000010 - NEGOTIATE_SEAL = 0x00000020 - NEGOTIATE_DATAGRAM = 0x00000040 - NEGOTIATE_LMKEY = 0x00000080 - NEGOTIATE_NTLM = 0x00000200 - NEGOTIATE_ANONYMOUS = 0x00000800 - NEGOTIATE_OEM_DOMAIN_SUPPLIED = 0x00001000 - NEGOTIATE_OEM_WORKSTATION_SUPPLIED = 0x00002000 - NEGOTIATE_ALWAYS_SIGN = 0x00008000 - NEGOTIATE_TARGET_TYPE_DOMAIN = 0x00010000 - NEGOTIATE_TARGET_TYPE_SERVER = 0x00020000 - NEGOTIATE_EXTENDED_SESSIONSECURITY = 0x00080000 - NEGOTIATE_IDENTIFY = 0x00100000 - REQUEST_NON_NT_SESSION_KEY = 0x00400000 - NEGOTIATE_TARGET_INFO = 0x00800000 - NEGOTIATE_VERSION = 0x02000000 - NEGOTIATE_128 = 0x20000000 - NEGOTIATE_KEY_EXCH = 0x40000000 - NEGOTIATE_56 = 0x80000000 -) - -const NEGOTIATE_FLAGS = NEGOTIATE_UNICODE | - NEGOTIATE_NTLM | - NEGOTIATE_OEM_DOMAIN_SUPPLIED | - NEGOTIATE_OEM_WORKSTATION_SUPPLIED | - NEGOTIATE_ALWAYS_SIGN | - NEGOTIATE_EXTENDED_SESSIONSECURITY - -type NTLMAuth struct { - Domain string - UserName string - Password string - Workstation string -} - -func getAuth(user, password, service, workstation string) (Auth, bool) { - if !strings.ContainsRune(user, '\\') { - return nil, false - } - domain_user := strings.SplitN(user, "\\", 2) - return &NTLMAuth{ - Domain: domain_user[0], - UserName: domain_user[1], - Password: password, - Workstation: workstation, - }, true -} - -func utf16le(val string) []byte { - var v []byte - for _, r := range val { - if utf16.IsSurrogate(r) { - r1, r2 := utf16.EncodeRune(r) - v = append(v, byte(r1), byte(r1>>8)) - v = append(v, byte(r2), byte(r2>>8)) - } else { - v = append(v, byte(r), byte(r>>8)) - } - } - return v -} - -func (auth *NTLMAuth) InitialBytes() ([]byte, error) { - domain_len := len(auth.Domain) - workstation_len := len(auth.Workstation) - msg := make([]byte, 40+domain_len+workstation_len) - copy(msg, []byte("NTLMSSP\x00")) - binary.LittleEndian.PutUint32(msg[8:], NEGOTIATE_MESSAGE) - binary.LittleEndian.PutUint32(msg[12:], NEGOTIATE_FLAGS) - // Domain Name Fields - binary.LittleEndian.PutUint16(msg[16:], uint16(domain_len)) - binary.LittleEndian.PutUint16(msg[18:], uint16(domain_len)) - binary.LittleEndian.PutUint32(msg[20:], 40) - // Workstation Fields - binary.LittleEndian.PutUint16(msg[24:], uint16(workstation_len)) - binary.LittleEndian.PutUint16(msg[26:], uint16(workstation_len)) - binary.LittleEndian.PutUint32(msg[28:], uint32(40+domain_len)) - // Version - binary.LittleEndian.PutUint32(msg[32:], 0) - binary.LittleEndian.PutUint32(msg[36:], 0) - // Payload - copy(msg[40:], auth.Domain) - copy(msg[40+domain_len:], auth.Workstation) - return msg, nil -} - -var errorNTLM = errors.New("NTLM protocol error") - -func createDesKey(bytes, material []byte) { - material[0] = bytes[0] - material[1] = (byte)(bytes[0]<<7 | (bytes[1]&0xff)>>1) - material[2] = (byte)(bytes[1]<<6 | (bytes[2]&0xff)>>2) - material[3] = (byte)(bytes[2]<<5 | (bytes[3]&0xff)>>3) - material[4] = (byte)(bytes[3]<<4 | (bytes[4]&0xff)>>4) - material[5] = (byte)(bytes[4]<<3 | (bytes[5]&0xff)>>5) - material[6] = (byte)(bytes[5]<<2 | (bytes[6]&0xff)>>6) - material[7] = (byte)(bytes[6] << 1) -} - -func oddParity(bytes []byte) { - for i := 0; i < len(bytes); i++ { - b := bytes[i] - needsParity := (((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 4) ^ (b >> 3) ^ (b >> 2) ^ (b >> 1)) & 0x01) == 0 - if needsParity { - bytes[i] = bytes[i] | byte(0x01) - } else { - bytes[i] = bytes[i] & byte(0xfe) - } - } -} - -func encryptDes(key []byte, cleartext []byte, ciphertext []byte) { - var desKey [8]byte - createDesKey(key, desKey[:]) - cipher, err := des.NewCipher(desKey[:]) - if err != nil { - panic(err) - } - cipher.Encrypt(ciphertext, cleartext) -} - -func response(challenge [8]byte, hash [21]byte) (ret [24]byte) { - encryptDes(hash[:7], challenge[:], ret[:8]) - encryptDes(hash[7:14], challenge[:], ret[8:16]) - encryptDes(hash[14:], challenge[:], ret[16:]) - return -} - -func lmHash(password string) (hash [21]byte) { - var lmpass [14]byte - copy(lmpass[:14], []byte(strings.ToUpper(password))) - magic := []byte("KGS!@#$%") - encryptDes(lmpass[:7], magic, hash[:8]) - encryptDes(lmpass[7:], magic, hash[8:]) - return -} - -func lmResponse(challenge [8]byte, password string) [24]byte { - hash := lmHash(password) - return response(challenge, hash) -} - -func ntlmHash(password string) (hash [21]byte) { - h := md4.New() - h.Write(utf16le(password)) - h.Sum(hash[:0]) - return -} - -func ntResponse(challenge [8]byte, password string) [24]byte { - hash := ntlmHash(password) - return response(challenge, hash) -} - -func clientChallenge() (nonce [8]byte) { - _, err := rand.Read(nonce[:]) - if err != nil { - panic(err) - } - return -} - -func ntlmSessionResponse(clientNonce [8]byte, serverChallenge [8]byte, password string) [24]byte { - var sessionHash [16]byte - h := md5.New() - h.Write(serverChallenge[:]) - h.Write(clientNonce[:]) - h.Sum(sessionHash[:0]) - var hash [8]byte - copy(hash[:], sessionHash[:8]) - passwordHash := ntlmHash(password) - return response(hash, passwordHash) -} - -func (auth *NTLMAuth) NextBytes(bytes []byte) ([]byte, error) { - if string(bytes[0:8]) != "NTLMSSP\x00" { - return nil, errorNTLM - } - if binary.LittleEndian.Uint32(bytes[8:12]) != CHALLENGE_MESSAGE { - return nil, errorNTLM - } - flags := binary.LittleEndian.Uint32(bytes[20:24]) - var challenge [8]byte - copy(challenge[:], bytes[24:32]) - - var lm, nt []byte - if (flags & NEGOTIATE_EXTENDED_SESSIONSECURITY) != 0 { - nonce := clientChallenge() - var lm_bytes [24]byte - copy(lm_bytes[:8], nonce[:]) - lm = lm_bytes[:] - nt_bytes := ntlmSessionResponse(nonce, challenge, auth.Password) - nt = nt_bytes[:] - } else { - lm_bytes := lmResponse(challenge, auth.Password) - lm = lm_bytes[:] - nt_bytes := ntResponse(challenge, auth.Password) - nt = nt_bytes[:] - } - lm_len := len(lm) - nt_len := len(nt) - - domain16 := utf16le(auth.Domain) - domain_len := len(domain16) - user16 := utf16le(auth.UserName) - user_len := len(user16) - workstation16 := utf16le(auth.Workstation) - workstation_len := len(workstation16) - - msg := make([]byte, 88+lm_len+nt_len+domain_len+user_len+workstation_len) - copy(msg, []byte("NTLMSSP\x00")) - binary.LittleEndian.PutUint32(msg[8:], AUTHENTICATE_MESSAGE) - // Lm Challenge Response Fields - binary.LittleEndian.PutUint16(msg[12:], uint16(lm_len)) - binary.LittleEndian.PutUint16(msg[14:], uint16(lm_len)) - binary.LittleEndian.PutUint32(msg[16:], 88) - // Nt Challenge Response Fields - binary.LittleEndian.PutUint16(msg[20:], uint16(nt_len)) - binary.LittleEndian.PutUint16(msg[22:], uint16(nt_len)) - binary.LittleEndian.PutUint32(msg[24:], uint32(88+lm_len)) - // Domain Name Fields - binary.LittleEndian.PutUint16(msg[28:], uint16(domain_len)) - binary.LittleEndian.PutUint16(msg[30:], uint16(domain_len)) - binary.LittleEndian.PutUint32(msg[32:], uint32(88+lm_len+nt_len)) - // User Name Fields - binary.LittleEndian.PutUint16(msg[36:], uint16(user_len)) - binary.LittleEndian.PutUint16(msg[38:], uint16(user_len)) - binary.LittleEndian.PutUint32(msg[40:], uint32(88+lm_len+nt_len+domain_len)) - // Workstation Fields - binary.LittleEndian.PutUint16(msg[44:], uint16(workstation_len)) - binary.LittleEndian.PutUint16(msg[46:], uint16(workstation_len)) - binary.LittleEndian.PutUint32(msg[48:], uint32(88+lm_len+nt_len+domain_len+user_len)) - // Encrypted Random Session Key Fields - binary.LittleEndian.PutUint16(msg[52:], 0) - binary.LittleEndian.PutUint16(msg[54:], 0) - binary.LittleEndian.PutUint32(msg[56:], uint32(88+lm_len+nt_len+domain_len+user_len+workstation_len)) - // Negotiate Flags - binary.LittleEndian.PutUint32(msg[60:], flags) - // Version - binary.LittleEndian.PutUint32(msg[64:], 0) - binary.LittleEndian.PutUint32(msg[68:], 0) - // MIC - binary.LittleEndian.PutUint32(msg[72:], 0) - binary.LittleEndian.PutUint32(msg[76:], 0) - binary.LittleEndian.PutUint32(msg[88:], 0) - binary.LittleEndian.PutUint32(msg[84:], 0) - // Payload - copy(msg[88:], lm) - copy(msg[88+lm_len:], nt) - copy(msg[88+lm_len+nt_len:], domain16) - copy(msg[88+lm_len+nt_len+domain_len:], user16) - copy(msg[88+lm_len+nt_len+domain_len+user_len:], workstation16) - return msg, nil -} - -func (auth *NTLMAuth) Free() { -} |