This commit is contained in:
justdan96
2018-04-13 09:50:16 +01:00
parent ca37395f51
commit 235d683359
3 changed files with 64 additions and 56 deletions

View File

@@ -7,30 +7,38 @@ const (
/*B*/ negotiateFlagNTLMNEGOTIATEOEM = 1 << 1 /*B*/ negotiateFlagNTLMNEGOTIATEOEM = 1 << 1
/*C*/ negotiateFlagNTLMSSPREQUESTTARGET = 1 << 2 /*C*/ negotiateFlagNTLMSSPREQUESTTARGET = 1 << 2
/*D*/ negotiateFlagNTLMSSPNEGOTIATESIGN = 1 << 4 /*D*/
negotiateFlagNTLMSSPNEGOTIATESIGN = 1 << 4
/*E*/ negotiateFlagNTLMSSPNEGOTIATESEAL = 1 << 5 /*E*/ negotiateFlagNTLMSSPNEGOTIATESEAL = 1 << 5
/*F*/ negotiateFlagNTLMSSPNEGOTIATEDATAGRAM = 1 << 6 /*F*/ negotiateFlagNTLMSSPNEGOTIATEDATAGRAM = 1 << 6
/*G*/ negotiateFlagNTLMSSPNEGOTIATELMKEY = 1 << 7 /*G*/ negotiateFlagNTLMSSPNEGOTIATELMKEY = 1 << 7
/*H*/ negotiateFlagNTLMSSPNEGOTIATENTLM = 1 << 9 /*H*/
negotiateFlagNTLMSSPNEGOTIATENTLM = 1 << 9
/*J*/ negotiateFlagANONYMOUS = 1 << 11 /*J*/
negotiateFlagANONYMOUS = 1 << 11
/*K*/ negotiateFlagNTLMSSPNEGOTIATEOEMDOMAINSUPPLIED = 1 << 12 /*K*/ negotiateFlagNTLMSSPNEGOTIATEOEMDOMAINSUPPLIED = 1 << 12
/*L*/ negotiateFlagNTLMSSPNEGOTIATEOEMWORKSTATIONSUPPLIED = 1 << 13 /*L*/ negotiateFlagNTLMSSPNEGOTIATEOEMWORKSTATIONSUPPLIED = 1 << 13
/*M*/ negotiateFlagNTLMSSPNEGOTIATEALWAYSSIGN = 1 << 15 /*M*/
negotiateFlagNTLMSSPNEGOTIATEALWAYSSIGN = 1 << 15
/*N*/ negotiateFlagNTLMSSPTARGETTYPEDOMAIN = 1 << 16 /*N*/ negotiateFlagNTLMSSPTARGETTYPEDOMAIN = 1 << 16
/*O*/ negotiateFlagNTLMSSPTARGETTYPESERVER = 1 << 17 /*O*/ negotiateFlagNTLMSSPTARGETTYPESERVER = 1 << 17
/*P*/ negotiateFlagNTLMSSPNEGOTIATEEXTENDEDSESSIONSECURITY = 1 << 19 /*P*/
negotiateFlagNTLMSSPNEGOTIATEEXTENDEDSESSIONSECURITY = 1 << 19
/*Q*/ negotiateFlagNTLMSSPNEGOTIATEIDENTIFY = 1 << 20 /*Q*/ negotiateFlagNTLMSSPNEGOTIATEIDENTIFY = 1 << 20
/*R*/ negotiateFlagNTLMSSPREQUESTNONNTSESSIONKEY = 1 << 22 /*R*/
negotiateFlagNTLMSSPREQUESTNONNTSESSIONKEY = 1 << 22
/*S*/ negotiateFlagNTLMSSPNEGOTIATETARGETINFO = 1 << 23 /*S*/ negotiateFlagNTLMSSPNEGOTIATETARGETINFO = 1 << 23
/*T*/ negotiateFlagNTLMSSPNEGOTIATEVERSION = 1 << 25 /*T*/
negotiateFlagNTLMSSPNEGOTIATEVERSION = 1 << 25
/*U*/ negotiateFlagNTLMSSPNEGOTIATE128 = 1 << 29 /*U*/
negotiateFlagNTLMSSPNEGOTIATE128 = 1 << 29
/*V*/ negotiateFlagNTLMSSPNEGOTIATEKEYEXCH = 1 << 30 /*V*/ negotiateFlagNTLMSSPNEGOTIATEKEYEXCH = 1 << 30
/*W*/ negotiateFlagNTLMSSPNEGOTIATE56 = 1 << 31 /*W*/ negotiateFlagNTLMSSPNEGOTIATE56 = 1 << 31
) )

View File

@@ -10,54 +10,54 @@ import (
const expMsgBodyLen = 40 const expMsgBodyLen = 40
type negotiateMessageFields struct { type negotiateMessageFields struct {
messageHeader messageHeader
NegotiateFlags negotiateFlags NegotiateFlags negotiateFlags
Domain varField Domain varField
Workstation varField Workstation varField
Version Version
} }
var defaultFlags = negotiateFlagNTLMSSPNEGOTIATETARGETINFO | var defaultFlags = negotiateFlagNTLMSSPNEGOTIATETARGETINFO |
negotiateFlagNTLMSSPNEGOTIATE56 | negotiateFlagNTLMSSPNEGOTIATE56 |
negotiateFlagNTLMSSPNEGOTIATE128 | negotiateFlagNTLMSSPNEGOTIATE128 |
negotiateFlagNTLMSSPNEGOTIATEUNICODE negotiateFlagNTLMSSPNEGOTIATEUNICODE
//NewNegotiateMessage creates a new NEGOTIATE message with the //NewNegotiateMessage creates a new NEGOTIATE message with the
//flags that this package supports. //flags that this package supports.
func NewNegotiateMessage(domainName, workstationName string) ([]byte, error) { func NewNegotiateMessage(domainName, workstationName string) ([]byte, error) {
payloadOffset := expMsgBodyLen payloadOffset := expMsgBodyLen
flags := defaultFlags flags := defaultFlags
if domainName != "" { if domainName != "" {
flags |= negotiateFlagNTLMSSPNEGOTIATEOEMDOMAINSUPPLIED flags |= negotiateFlagNTLMSSPNEGOTIATEOEMDOMAINSUPPLIED
} }
if workstationName != "" { if workstationName != "" {
flags |= negotiateFlagNTLMSSPNEGOTIATEOEMWORKSTATIONSUPPLIED flags |= negotiateFlagNTLMSSPNEGOTIATEOEMWORKSTATIONSUPPLIED
} }
msg := negotiateMessageFields{ msg := negotiateMessageFields{
messageHeader: newMessageHeader(1), messageHeader: newMessageHeader(1),
NegotiateFlags: flags, NegotiateFlags: flags,
Domain: newVarField(&payloadOffset, len(domainName)), Domain: newVarField(&payloadOffset, len(domainName)),
Workstation: newVarField(&payloadOffset, len(workstationName)), Workstation: newVarField(&payloadOffset, len(workstationName)),
Version: DefaultVersion(), Version: DefaultVersion(),
} }
b := bytes.Buffer{} b := bytes.Buffer{}
if err := binary.Write(&b, binary.LittleEndian, &msg); err != nil { if err := binary.Write(&b, binary.LittleEndian, &msg); err != nil {
return nil, err return nil, err
} }
if b.Len() != expMsgBodyLen { if b.Len() != expMsgBodyLen {
return nil, errors.New("incorrect body length") return nil, errors.New("incorrect body length")
} }
payload := strings.ToUpper(domainName + workstationName) payload := strings.ToUpper(domainName + workstationName)
if _, err := b.WriteString(payload); err != nil { if _, err := b.WriteString(payload); err != nil {
return nil, err return nil, err
} }
return b.Bytes(), nil return b.Bytes(), nil
} }

View File

@@ -77,21 +77,21 @@ func (l Negotiator) RoundTrip(req *http.Request) (res *http.Response, err error)
return nil, err return nil, err
} }
// parse domain name from username // parse domain name from username
domain := "" domain := ""
if strings.Contains(u, "\\") { if strings.Contains(u, "\\") {
ucomponents := strings.Split(u, "\\") ucomponents := strings.Split(u, "\\")
domain = ucomponents[0] domain = ucomponents[0]
u = ucomponents[1] u = ucomponents[1]
} }
// send negotiate // send negotiate
negotiateMessage, err := NewNegotiateMessage(domain, "") negotiateMessage, err := NewNegotiateMessage(domain, "")
if err != nil { if err != nil {
return nil, err return nil, err
} }
if resauth.IsNTLM() { if resauth.IsNTLM() {
req.Header.Set("Authorization", "NTLM "+base64.StdEncoding.EncodeToString(negotiateMessage)) req.Header.Set("Authorization", "NTLM "+base64.StdEncoding.EncodeToString(negotiateMessage))
} else { } else {
req.Header.Set("Authorization", "Negotiate "+base64.StdEncoding.EncodeToString(negotiateMessage)) req.Header.Set("Authorization", "Negotiate "+base64.StdEncoding.EncodeToString(negotiateMessage))