blob: b9f535f5b97a0a7194ec6b65b8febd2b1b57baf7 [file] [log] [blame]
khenaidoo7d3c5582021-08-11 18:09:44 -04001package mstypes
2
3import (
4 "bytes"
5 "encoding/hex"
6 "errors"
7 "fmt"
8
9 "github.com/jcmturner/rpc/v2/ndr"
10 "golang.org/x/net/http2/hpack"
11)
12
13// Compression format assigned numbers. https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-xca/a8b7cb0a-92a6-4187-a23b-5e14273b96f8
14const (
15 CompressionFormatNone uint16 = 0
16 CompressionFormatLZNT1 uint16 = 2 // LZNT1 aka ntfs compression
17 CompressionFormatXPress uint16 = 3 // plain LZ77
18 CompressionFormatXPressHuff uint16 = 4 // LZ77+Huffman - The Huffman variant of the XPRESS compression format uses LZ77-style dictionary compression combined with Huffman coding.
19)
20
21// ClaimsSourceTypeAD https://msdn.microsoft.com/en-us/library/hh553809.aspx
22const ClaimsSourceTypeAD uint16 = 1
23
24// Claim Type assigned numbers
25const (
26 ClaimTypeIDInt64 uint16 = 1
27 ClaimTypeIDUInt64 uint16 = 2
28 ClaimTypeIDString uint16 = 3
29 ClaimsTypeIDBoolean uint16 = 6
30)
31
32// ClaimsBlob implements https://msdn.microsoft.com/en-us/library/hh554119.aspx
33type ClaimsBlob struct {
34 Size uint32
35 EncodedBlob EncodedBlob
36}
37
38// EncodedBlob are the bytes of the encoded Claims
39type EncodedBlob []byte
40
41// Size returns the size of the bytes of the encoded Claims
42func (b EncodedBlob) Size(c interface{}) int {
43 cb := c.(ClaimsBlob)
44 return int(cb.Size)
45}
46
47// ClaimsSetMetadata implements https://msdn.microsoft.com/en-us/library/hh554073.aspx
48type ClaimsSetMetadata struct {
49 ClaimsSetSize uint32
50 ClaimsSetBytes []byte `ndr:"pointer,conformant"`
51 CompressionFormat uint16 // Enum see constants for options
52 UncompressedClaimsSetSize uint32
53 ReservedType uint16
54 ReservedFieldSize uint32
55 ReservedField []byte `ndr:"pointer,conformant"`
56}
57
58// ClaimsSet reads the ClaimsSet type from the NDR encoded ClaimsSetBytes in the ClaimsSetMetadata
59func (m *ClaimsSetMetadata) ClaimsSet() (c ClaimsSet, err error) {
60 if len(m.ClaimsSetBytes) < 1 {
61 err = errors.New("no bytes available for ClaimsSet")
62 return
63 }
64 // TODO switch statement to decompress ClaimsSetBytes
65 switch m.CompressionFormat {
66 case CompressionFormatLZNT1:
67 s := hex.EncodeToString(m.ClaimsSetBytes)
68 err = fmt.Errorf("ClaimsSet compressed, format LZNT1 not currently supported: %s", s)
69 return
70 case CompressionFormatXPress:
71 s := hex.EncodeToString(m.ClaimsSetBytes)
72 err = fmt.Errorf("ClaimsSet compressed, format XPress not currently supported: %s", s)
73 return
74 case CompressionFormatXPressHuff:
75 var b []byte
76 buff := bytes.NewBuffer(b)
77 _, e := hpack.HuffmanDecode(buff, m.ClaimsSetBytes)
78 if e != nil {
79 err = fmt.Errorf("error deflating: %v", e)
80 return
81 }
82 m.ClaimsSetBytes = buff.Bytes()
83 }
84 dec := ndr.NewDecoder(bytes.NewReader(m.ClaimsSetBytes))
85 err = dec.Decode(&c)
86 return
87}
88
89// ClaimsSet implements https://msdn.microsoft.com/en-us/library/hh554122.aspx
90type ClaimsSet struct {
91 ClaimsArrayCount uint32
92 ClaimsArrays []ClaimsArray `ndr:"pointer,conformant"`
93 ReservedType uint16
94 ReservedFieldSize uint32
95 ReservedField []byte `ndr:"pointer,conformant"`
96}
97
98// ClaimsArray implements https://msdn.microsoft.com/en-us/library/hh536458.aspx
99type ClaimsArray struct {
100 ClaimsSourceType uint16
101 ClaimsCount uint32
102 ClaimEntries []ClaimEntry `ndr:"pointer,conformant"`
103}
104
105// ClaimEntry is a NDR union that implements https://msdn.microsoft.com/en-us/library/hh536374.aspx
106type ClaimEntry struct {
107 ID string `ndr:"pointer,conformant,varying"`
108 Type uint16 `ndr:"unionTag"`
109 TypeInt64 ClaimTypeInt64 `ndr:"unionField"`
110 TypeUInt64 ClaimTypeUInt64 `ndr:"unionField"`
111 TypeString ClaimTypeString `ndr:"unionField"`
112 TypeBool ClaimTypeBoolean `ndr:"unionField"`
113}
114
115// SwitchFunc is the ClaimEntry union field selection function
116func (u ClaimEntry) SwitchFunc(_ interface{}) string {
117 switch u.Type {
118 case ClaimTypeIDInt64:
119 return "TypeInt64"
120 case ClaimTypeIDUInt64:
121 return "TypeUInt64"
122 case ClaimTypeIDString:
123 return "TypeString"
124 case ClaimsTypeIDBoolean:
125 return "TypeBool"
126 }
127 return ""
128}
129
130// ClaimTypeInt64 is a claim of type int64
131type ClaimTypeInt64 struct {
132 ValueCount uint32
133 Value []int64 `ndr:"pointer,conformant"`
134}
135
136// ClaimTypeUInt64 is a claim of type uint64
137type ClaimTypeUInt64 struct {
138 ValueCount uint32
139 Value []uint64 `ndr:"pointer,conformant"`
140}
141
142// ClaimTypeString is a claim of type string
143type ClaimTypeString struct {
144 ValueCount uint32
145 Value []LPWSTR `ndr:"pointer,conformant"`
146}
147
148// ClaimTypeBoolean is a claim of type bool
149type ClaimTypeBoolean struct {
150 ValueCount uint32
151 Value []bool `ndr:"pointer,conformant"`
152}