blob: 5f4f93c28bd18b9a4115dbff2c559b9a56d53b86 [file] [log] [blame]
Takahiro Suzukid7bf8202020-12-17 20:21:59 +09001package pac
2
3import (
4 "bytes"
5 "encoding/binary"
6 "errors"
7 "fmt"
8
9 "gopkg.in/jcmturner/rpc.v1/mstypes"
10 "gopkg.in/jcmturner/rpc.v1/ndr"
11)
12
13const (
14 // NTLMSupCredLMOWF indicates that the LM OWF member is present and valid.
15 NTLMSupCredLMOWF uint32 = 31
16 // NTLMSupCredNTOWF indicates that the NT OWF member is present and valid.
17 NTLMSupCredNTOWF uint32 = 30
18)
19
20// NTLMSupplementalCred implements https://msdn.microsoft.com/en-us/library/cc237949.aspx
21type NTLMSupplementalCred struct {
22 Version uint32 // A 32-bit unsigned integer that defines the credential version.This field MUST be 0x00000000.
23 Flags uint32
24 LMPassword []byte // A 16-element array of unsigned 8-bit integers that define the LM OWF. The LMPassword member MUST be ignored if the L flag is not set in the Flags member.
25 NTPassword []byte // A 16-element array of unsigned 8-bit integers that define the NT OWF. The NTPassword member MUST be ignored if the N flag is not set in the Flags member.
26}
27
28// Unmarshal converts the bytes provided into a NTLMSupplementalCred.
29func (c *NTLMSupplementalCred) Unmarshal(b []byte) (err error) {
30 r := mstypes.NewReader(bytes.NewReader(b))
31 c.Version, err = r.Uint32()
32 if err != nil {
33 return
34 }
35 if c.Version != 0 {
36 err = errors.New("NTLMSupplementalCred version is not zero")
37 return
38 }
39 c.Flags, err = r.Uint32()
40 if err != nil {
41 return
42 }
43 if isFlagSet(c.Flags, NTLMSupCredLMOWF) {
44 c.LMPassword, err = r.ReadBytes(16)
45 if err != nil {
46 return
47 }
48 }
49 if isFlagSet(c.Flags, NTLMSupCredNTOWF) {
50 c.NTPassword, err = r.ReadBytes(16)
51 if err != nil {
52 return
53 }
54 }
55 return
56}
57
58// isFlagSet tests if a flag is set in the uint32 little endian flag
59func isFlagSet(f uint32, i uint32) bool {
60 //Which byte?
61 b := int(i / 8)
62 //Which bit in byte
63 p := uint(7 - (int(i) - 8*b))
64 fb := make([]byte, 4)
65 binary.LittleEndian.PutUint32(fb, f)
66 if fb[b]&(1<<p) != 0 {
67 return true
68 }
69 return false
70}
71
72// SECPKGSupplementalCred implements https://msdn.microsoft.com/en-us/library/cc237956.aspx
73// The SECPKG_SUPPLEMENTAL_CRED structure defines the name of the security package that requires
74// supplemental credentials and the credential buffer for that package.
75// The SECPKG_SUPPLEMENTAL_CRED structure is marshaled by RPC.
76type SECPKGSupplementalCred struct {
77 PackageName mstypes.RPCUnicodeString
78 CredentialSize uint32
79 Credentials []uint8 `ndr:"pointer,conformant"` // Is a ptr. Size is the value of CredentialSize
80}
81
82// Unmarshal converts the bytes provided into a SECPKGSupplementalCred.
83func (c *SECPKGSupplementalCred) Unmarshal(b []byte) (err error) {
84 dec := ndr.NewDecoder(bytes.NewReader(b))
85 err = dec.Decode(c)
86 if err != nil {
87 err = fmt.Errorf("error unmarshaling SECPKGSupplementalCred: %v", err)
88 }
89 return
90}