github.com/psiphon-Labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/upstreamproxy/go-ntlm/ntlm/payload.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 "encoding/hex" 9 "errors" 10 ) 11 12 const ( 13 UnicodeStringPayload = iota 14 OemStringPayload 15 BytesPayload 16 ) 17 18 type PayloadStruct struct { 19 Type int 20 Len uint16 21 MaxLen uint16 22 Offset uint32 23 Payload []byte 24 } 25 26 func (p *PayloadStruct) Bytes() []byte { 27 dest := make([]byte, 0, 8) 28 buffer := bytes.NewBuffer(dest) 29 30 binary.Write(buffer, binary.LittleEndian, p.Len) 31 binary.Write(buffer, binary.LittleEndian, p.MaxLen) 32 binary.Write(buffer, binary.LittleEndian, p.Offset) 33 34 return buffer.Bytes() 35 } 36 37 func (p *PayloadStruct) String() string { 38 var returnString string 39 40 switch p.Type { 41 case UnicodeStringPayload: 42 returnString = utf16ToString(p.Payload) 43 case OemStringPayload: 44 returnString = string(p.Payload) 45 case BytesPayload: 46 returnString = hex.EncodeToString(p.Payload) 47 default: 48 returnString = "unknown type" 49 } 50 return returnString 51 } 52 53 func CreateBytePayload(bytes []byte) (*PayloadStruct, error) { 54 p := new(PayloadStruct) 55 p.Type = BytesPayload 56 p.Len = uint16(len(bytes)) 57 p.MaxLen = uint16(len(bytes)) 58 p.Payload = bytes // TODO: Copy these bytes instead of keeping a reference 59 return p, nil 60 } 61 62 func CreateStringPayload(value string) (*PayloadStruct, error) { 63 // Create UTF16 unicode bytes from string 64 bytes := utf16FromString(value) 65 p := new(PayloadStruct) 66 p.Type = UnicodeStringPayload 67 p.Len = uint16(len(bytes)) 68 p.MaxLen = uint16(len(bytes)) 69 p.Payload = bytes // TODO: Copy these bytes instead of keeping a reference 70 return p, nil 71 } 72 73 func ReadStringPayload(startByte int, bytes []byte) (*PayloadStruct, error) { 74 return ReadPayloadStruct(startByte, bytes, UnicodeStringPayload) 75 } 76 77 func ReadBytePayload(startByte int, bytes []byte) (*PayloadStruct, error) { 78 return ReadPayloadStruct(startByte, bytes, BytesPayload) 79 } 80 81 func ReadPayloadStruct(startByte int, bytes []byte, PayloadType int) (*PayloadStruct, error) { 82 p := new(PayloadStruct) 83 84 // [Psiphon] 85 // Don't panic on malformed remote input. 86 if len(bytes) < startByte+8 { 87 return nil, errors.New("invalid payload") 88 } 89 90 p.Type = PayloadType 91 p.Len = binary.LittleEndian.Uint16(bytes[startByte : startByte+2]) 92 p.MaxLen = binary.LittleEndian.Uint16(bytes[startByte+2 : startByte+4]) 93 p.Offset = binary.LittleEndian.Uint32(bytes[startByte+4 : startByte+8]) 94 95 if p.Len > 0 { 96 endOffset := p.Offset + uint32(p.Len) 97 98 // [Psiphon] 99 // Don't panic on malformed remote input. 100 if len(bytes) < int(endOffset) { 101 return nil, errors.New("invalid payload") 102 } 103 104 p.Payload = bytes[p.Offset:endOffset] 105 } 106 107 return p, nil 108 }