1package ntlmssp 2 3import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7) 8 9type challengeMessageFields struct { 10 messageHeader 11 TargetName varField 12 NegotiateFlags negotiateFlags 13 ServerChallenge [8]byte 14 _ [8]byte 15 TargetInfo varField 16} 17 18func (m challengeMessageFields) IsValid() bool { 19 return m.messageHeader.IsValid() && m.MessageType == 2 20} 21 22type challengeMessage struct { 23 challengeMessageFields 24 TargetName string 25 TargetInfo map[avID][]byte 26 TargetInfoRaw []byte 27} 28 29func (m *challengeMessage) UnmarshalBinary(data []byte) error { 30 r := bytes.NewReader(data) 31 err := binary.Read(r, binary.LittleEndian, &m.challengeMessageFields) 32 if err != nil { 33 return err 34 } 35 if !m.challengeMessageFields.IsValid() { 36 return fmt.Errorf("Message is not a valid challenge message: %+v", m.challengeMessageFields.messageHeader) 37 } 38 39 if m.challengeMessageFields.TargetName.Len > 0 { 40 m.TargetName, err = m.challengeMessageFields.TargetName.ReadStringFrom(data, m.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATEUNICODE)) 41 if err != nil { 42 return err 43 } 44 } 45 46 if m.challengeMessageFields.TargetInfo.Len > 0 { 47 d, err := m.challengeMessageFields.TargetInfo.ReadFrom(data) 48 m.TargetInfoRaw = d 49 if err != nil { 50 return err 51 } 52 m.TargetInfo = make(map[avID][]byte) 53 r := bytes.NewReader(d) 54 for { 55 var id avID 56 var l uint16 57 err = binary.Read(r, binary.LittleEndian, &id) 58 if err != nil { 59 return err 60 } 61 if id == avIDMsvAvEOL { 62 break 63 } 64 65 err = binary.Read(r, binary.LittleEndian, &l) 66 if err != nil { 67 return err 68 } 69 value := make([]byte, l) 70 n, err := r.Read(value) 71 if err != nil { 72 return err 73 } 74 if n != int(l) { 75 return fmt.Errorf("Expected to read %d bytes, got only %d", l, n) 76 } 77 m.TargetInfo[id] = value 78 } 79 } 80 81 return nil 82} 83