github.com/psiphon-Labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/upstreamproxy/go-ntlm/ntlm/ntlm.go (about) 1 //Copyright 2013 Thomson Reuters Global Resources. BSD License please see License file for more information 2 3 // Package NTLM implements the interfaces used for interacting with NTLMv1 and NTLMv2. 4 // To create NTLM v1 or v2 sessions you would use CreateClientSession and create ClientServerSession. 5 package ntlm 6 7 import ( 8 rc4P "crypto/rc4" 9 "errors" 10 ) 11 12 type Version int 13 14 const ( 15 Version1 Version = 1 16 Version2 Version = 2 17 ) 18 19 type Mode int 20 21 const ( 22 ConnectionlessMode Mode = iota 23 ConnectionOrientedMode 24 ) 25 26 // Creates an NTLM v1 or v2 client 27 // mode - This must be ConnectionlessMode or ConnectionOrientedMode depending on what type of NTLM is used 28 // version - This must be Version1 or Version2 depending on the version of NTLM used 29 func CreateClientSession(version Version, mode Mode) (n ClientSession, err error) { 30 switch version { 31 case Version1: 32 n = new(V1ClientSession) 33 case Version2: 34 n = new(V2ClientSession) 35 default: 36 return nil, errors.New("Unknown NTLM Version, must be 1 or 2") 37 } 38 39 return n, nil 40 } 41 42 type ClientSession interface { 43 SetUserInfo(username string, password string, domain string) 44 SetMode(mode Mode) 45 46 GenerateNegotiateMessage() (*NegotiateMessage, error) 47 ProcessChallengeMessage(*ChallengeMessage) error 48 GenerateAuthenticateMessage() (*AuthenticateMessage, error) 49 50 Seal(message []byte) ([]byte, error) 51 Sign(message []byte) ([]byte, error) 52 Mac(message []byte, sequenceNumber int) ([]byte, error) 53 VerifyMac(message, expectedMac []byte, sequenceNumber int) (bool, error) 54 } 55 56 // Creates an NTLM v1 or v2 server 57 // mode - This must be ConnectionlessMode or ConnectionOrientedMode depending on what type of NTLM is used 58 // version - This must be Version1 or Version2 depending on the version of NTLM used 59 func CreateServerSession(version Version, mode Mode) (n ServerSession, err error) { 60 switch version { 61 case Version1: 62 n = new(V1ServerSession) 63 case Version2: 64 n = new(V2ServerSession) 65 default: 66 return nil, errors.New("Unknown NTLM Version, must be 1 or 2") 67 } 68 69 n.SetMode(mode) 70 return n, nil 71 } 72 73 type ServerSession interface { 74 SetUserInfo(username string, password string, domain string) 75 GetUserInfo() (string, string, string) 76 77 SetMode(mode Mode) 78 SetServerChallenge(challege []byte) 79 80 ProcessNegotiateMessage(*NegotiateMessage) error 81 GenerateChallengeMessage() (*ChallengeMessage, error) 82 ProcessAuthenticateMessage(*AuthenticateMessage) error 83 84 GetSessionData() *SessionData 85 86 Version() int 87 Seal(message []byte) ([]byte, error) 88 Sign(message []byte) ([]byte, error) 89 Mac(message []byte, sequenceNumber int) ([]byte, error) 90 VerifyMac(message, expectedMac []byte, sequenceNumber int) (bool, error) 91 } 92 93 // This struct collects NTLM data structures and keys that are used across all types of NTLM requests 94 type SessionData struct { 95 mode Mode 96 97 user string 98 password string 99 userDomain string 100 101 NegotiateFlags uint32 102 103 negotiateMessage *NegotiateMessage 104 challengeMessage *ChallengeMessage 105 authenticateMessage *AuthenticateMessage 106 107 serverChallenge []byte 108 clientChallenge []byte 109 ntChallengeResponse []byte 110 lmChallengeResponse []byte 111 112 responseKeyLM []byte 113 responseKeyNT []byte 114 exportedSessionKey []byte 115 encryptedRandomSessionKey []byte 116 keyExchangeKey []byte 117 sessionBaseKey []byte 118 mic []byte 119 120 ClientSigningKey []byte 121 ServerSigningKey []byte 122 ClientSealingKey []byte 123 ServerSealingKey []byte 124 125 clientHandle *rc4P.Cipher 126 serverHandle *rc4P.Cipher 127 }