You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
83 lines
1.8 KiB
83 lines
1.8 KiB
4 years ago
|
package ntlmssp
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"encoding/binary"
|
||
|
"fmt"
|
||
|
)
|
||
|
|
||
|
type challengeMessageFields struct {
|
||
|
messageHeader
|
||
|
TargetName varField
|
||
|
NegotiateFlags negotiateFlags
|
||
|
ServerChallenge [8]byte
|
||
|
_ [8]byte
|
||
|
TargetInfo varField
|
||
|
}
|
||
|
|
||
|
func (m challengeMessageFields) IsValid() bool {
|
||
|
return m.messageHeader.IsValid() && m.MessageType == 2
|
||
|
}
|
||
|
|
||
|
type challengeMessage struct {
|
||
|
challengeMessageFields
|
||
|
TargetName string
|
||
|
TargetInfo map[avID][]byte
|
||
|
TargetInfoRaw []byte
|
||
|
}
|
||
|
|
||
|
func (m *challengeMessage) UnmarshalBinary(data []byte) error {
|
||
|
r := bytes.NewReader(data)
|
||
|
err := binary.Read(r, binary.LittleEndian, &m.challengeMessageFields)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if !m.challengeMessageFields.IsValid() {
|
||
|
return fmt.Errorf("Message is not a valid challenge message: %+v", m.challengeMessageFields.messageHeader)
|
||
|
}
|
||
|
|
||
|
if m.challengeMessageFields.TargetName.Len > 0 {
|
||
|
m.TargetName, err = m.challengeMessageFields.TargetName.ReadStringFrom(data, m.NegotiateFlags.Has(negotiateFlagNTLMSSPNEGOTIATEUNICODE))
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if m.challengeMessageFields.TargetInfo.Len > 0 {
|
||
|
d, err := m.challengeMessageFields.TargetInfo.ReadFrom(data)
|
||
|
m.TargetInfoRaw = d
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
m.TargetInfo = make(map[avID][]byte)
|
||
|
r := bytes.NewReader(d)
|
||
|
for {
|
||
|
var id avID
|
||
|
var l uint16
|
||
|
err = binary.Read(r, binary.LittleEndian, &id)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if id == avIDMsvAvEOL {
|
||
|
break
|
||
|
}
|
||
|
|
||
|
err = binary.Read(r, binary.LittleEndian, &l)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
value := make([]byte, l)
|
||
|
n, err := r.Read(value)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
if n != int(l) {
|
||
|
return fmt.Errorf("Expected to read %d bytes, got only %d", l, n)
|
||
|
}
|
||
|
m.TargetInfo[id] = value
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|