github.com/psiphon-labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/upstreamproxy/go-ntlm/ntlm/message_negotiate.go (about)

     1  //Copyright 2013 Thomson Reuters Global Resources. BSD License please see License file for more information
     2  
     3  package ntlm
     4  
     5  import (
     6  	"bytes"
     7  	"encoding/binary"
     8  )
     9  
    10  //Supported negotiate flags
    11  const (
    12  	NEGOTIATE_FLAG_REQUEST_NTLMv1           = 0x00000200
    13  	NEGOTIATE_FLAG_REQUEST_NTLM2_SESSION    = 0x00080000
    14  	NEGOTIATE_FLAG_REQUEST_VERSION          = 0x02000000
    15  	NEGOTIATE_FLAG_REQUEST_ALWAYS_SIGN      = 0x00008000
    16  	NEGOTIATE_FLAG_REQUEST_128BIT_KEY_EXCH  = 0x20000000
    17  	NEGOTIATE_FLAG_REQUEST_56BIT_ENCRYPTION = 0x80000000
    18  	NEGOTIATE_FLAG_REQUEST_UNICODE_ENCODING = 0x00000001
    19  )
    20  
    21  type NegotiateMessage struct {
    22  	// All bytes of the message
    23  	// Bytes []byte
    24  
    25  	// sig - 8 bytes
    26  	Signature []byte
    27  	// message type - 4 bytes
    28  	MessageType uint32
    29  	// negotiate flags - 4bytes
    30  	NegotiateFlags uint32
    31  	// If the NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED flag is not set in NegotiateFlags,
    32  	// indicating that no DomainName is supplied in Payload  - then this should have Len 0 / MaxLen 0
    33  	// this contains a domain name
    34  	DomainNameFields *PayloadStruct
    35  	// If the NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED flag is not set in NegotiateFlags,
    36  	// indicating that no WorkstationName is supplied in Payload - then this should have Len 0 / MaxLen 0
    37  	WorkstationFields *PayloadStruct
    38  	// version - 8 bytes
    39  	Version *VersionStruct
    40  	// payload - variable
    41  	Payload       []byte
    42  	PayloadOffset int
    43  }
    44  
    45  func (nm *NegotiateMessage) Bytes() []byte {
    46  	//Domain and Workstation payload are not supported
    47  	messageLen := 40
    48  
    49  	messageBytes := make([]byte, 0, messageLen)
    50  	buffer := bytes.NewBuffer(messageBytes)
    51  
    52  	//Signature 8
    53  	buffer.Write(nm.Signature) //0
    54  	//MessageType 4
    55  	binary.Write(buffer, binary.LittleEndian, nm.MessageType) //8
    56  	//Flags 4
    57  	binary.Write(buffer, binary.LittleEndian, nm.NegotiateFlags) //12
    58  	//DomainLen 2
    59  	binary.Write(buffer, binary.LittleEndian, uint16(0))
    60  	//DomainMaxLen == DomainLen 2
    61  	binary.Write(buffer, binary.LittleEndian, uint16(0))
    62  	//DomainOffset 4
    63  	binary.Write(buffer, binary.LittleEndian, uint32(messageLen))
    64  	//WorkstationLen 2
    65  	binary.Write(buffer, binary.LittleEndian, uint16(0))
    66  	//WorkstationMaxLen == WorkstationLen 2
    67  	binary.Write(buffer, binary.LittleEndian, uint16(0))
    68  	//WorkstationOffset 4
    69  	binary.Write(buffer, binary.LittleEndian, uint32(40))
    70  	//VersionStruct  1 + 1 + 2 + 1 + 1 + 1 + 1 = 8
    71  	buffer.Write(nm.Version.Bytes())
    72  	return buffer.Bytes()
    73  }