153 lines
4.5 KiB
Go
153 lines
4.5 KiB
Go
|
package mstypes
|
||
|
|
||
|
import (
|
||
|
"bytes"
|
||
|
"encoding/hex"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
|
||
|
"github.com/jcmturner/rpc/v2/ndr"
|
||
|
"golang.org/x/net/http2/hpack"
|
||
|
)
|
||
|
|
||
|
// Compression format assigned numbers. https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-xca/a8b7cb0a-92a6-4187-a23b-5e14273b96f8
|
||
|
const (
|
||
|
CompressionFormatNone uint16 = 0
|
||
|
CompressionFormatLZNT1 uint16 = 2 // LZNT1 aka ntfs compression
|
||
|
CompressionFormatXPress uint16 = 3 // plain LZ77
|
||
|
CompressionFormatXPressHuff uint16 = 4 // LZ77+Huffman - The Huffman variant of the XPRESS compression format uses LZ77-style dictionary compression combined with Huffman coding.
|
||
|
)
|
||
|
|
||
|
// ClaimsSourceTypeAD https://msdn.microsoft.com/en-us/library/hh553809.aspx
|
||
|
const ClaimsSourceTypeAD uint16 = 1
|
||
|
|
||
|
// Claim Type assigned numbers
|
||
|
const (
|
||
|
ClaimTypeIDInt64 uint16 = 1
|
||
|
ClaimTypeIDUInt64 uint16 = 2
|
||
|
ClaimTypeIDString uint16 = 3
|
||
|
ClaimsTypeIDBoolean uint16 = 6
|
||
|
)
|
||
|
|
||
|
// ClaimsBlob implements https://msdn.microsoft.com/en-us/library/hh554119.aspx
|
||
|
type ClaimsBlob struct {
|
||
|
Size uint32
|
||
|
EncodedBlob EncodedBlob
|
||
|
}
|
||
|
|
||
|
// EncodedBlob are the bytes of the encoded Claims
|
||
|
type EncodedBlob []byte
|
||
|
|
||
|
// Size returns the size of the bytes of the encoded Claims
|
||
|
func (b EncodedBlob) Size(c interface{}) int {
|
||
|
cb := c.(ClaimsBlob)
|
||
|
return int(cb.Size)
|
||
|
}
|
||
|
|
||
|
// ClaimsSetMetadata implements https://msdn.microsoft.com/en-us/library/hh554073.aspx
|
||
|
type ClaimsSetMetadata struct {
|
||
|
ClaimsSetSize uint32
|
||
|
ClaimsSetBytes []byte `ndr:"pointer,conformant"`
|
||
|
CompressionFormat uint16 // Enum see constants for options
|
||
|
UncompressedClaimsSetSize uint32
|
||
|
ReservedType uint16
|
||
|
ReservedFieldSize uint32
|
||
|
ReservedField []byte `ndr:"pointer,conformant"`
|
||
|
}
|
||
|
|
||
|
// ClaimsSet reads the ClaimsSet type from the NDR encoded ClaimsSetBytes in the ClaimsSetMetadata
|
||
|
func (m *ClaimsSetMetadata) ClaimsSet() (c ClaimsSet, err error) {
|
||
|
if len(m.ClaimsSetBytes) < 1 {
|
||
|
err = errors.New("no bytes available for ClaimsSet")
|
||
|
return
|
||
|
}
|
||
|
// TODO switch statement to decompress ClaimsSetBytes
|
||
|
switch m.CompressionFormat {
|
||
|
case CompressionFormatLZNT1:
|
||
|
s := hex.EncodeToString(m.ClaimsSetBytes)
|
||
|
err = fmt.Errorf("ClaimsSet compressed, format LZNT1 not currently supported: %s", s)
|
||
|
return
|
||
|
case CompressionFormatXPress:
|
||
|
s := hex.EncodeToString(m.ClaimsSetBytes)
|
||
|
err = fmt.Errorf("ClaimsSet compressed, format XPress not currently supported: %s", s)
|
||
|
return
|
||
|
case CompressionFormatXPressHuff:
|
||
|
var b []byte
|
||
|
buff := bytes.NewBuffer(b)
|
||
|
_, e := hpack.HuffmanDecode(buff, m.ClaimsSetBytes)
|
||
|
if e != nil {
|
||
|
err = fmt.Errorf("error deflating: %v", e)
|
||
|
return
|
||
|
}
|
||
|
m.ClaimsSetBytes = buff.Bytes()
|
||
|
}
|
||
|
dec := ndr.NewDecoder(bytes.NewReader(m.ClaimsSetBytes))
|
||
|
err = dec.Decode(&c)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// ClaimsSet implements https://msdn.microsoft.com/en-us/library/hh554122.aspx
|
||
|
type ClaimsSet struct {
|
||
|
ClaimsArrayCount uint32
|
||
|
ClaimsArrays []ClaimsArray `ndr:"pointer,conformant"`
|
||
|
ReservedType uint16
|
||
|
ReservedFieldSize uint32
|
||
|
ReservedField []byte `ndr:"pointer,conformant"`
|
||
|
}
|
||
|
|
||
|
// ClaimsArray implements https://msdn.microsoft.com/en-us/library/hh536458.aspx
|
||
|
type ClaimsArray struct {
|
||
|
ClaimsSourceType uint16
|
||
|
ClaimsCount uint32
|
||
|
ClaimEntries []ClaimEntry `ndr:"pointer,conformant"`
|
||
|
}
|
||
|
|
||
|
// ClaimEntry is a NDR union that implements https://msdn.microsoft.com/en-us/library/hh536374.aspx
|
||
|
type ClaimEntry struct {
|
||
|
ID string `ndr:"pointer,conformant,varying"`
|
||
|
Type uint16 `ndr:"unionTag"`
|
||
|
TypeInt64 ClaimTypeInt64 `ndr:"unionField"`
|
||
|
TypeUInt64 ClaimTypeUInt64 `ndr:"unionField"`
|
||
|
TypeString ClaimTypeString `ndr:"unionField"`
|
||
|
TypeBool ClaimTypeBoolean `ndr:"unionField"`
|
||
|
}
|
||
|
|
||
|
// SwitchFunc is the ClaimEntry union field selection function
|
||
|
func (u ClaimEntry) SwitchFunc(_ interface{}) string {
|
||
|
switch u.Type {
|
||
|
case ClaimTypeIDInt64:
|
||
|
return "TypeInt64"
|
||
|
case ClaimTypeIDUInt64:
|
||
|
return "TypeUInt64"
|
||
|
case ClaimTypeIDString:
|
||
|
return "TypeString"
|
||
|
case ClaimsTypeIDBoolean:
|
||
|
return "TypeBool"
|
||
|
}
|
||
|
return ""
|
||
|
}
|
||
|
|
||
|
// ClaimTypeInt64 is a claim of type int64
|
||
|
type ClaimTypeInt64 struct {
|
||
|
ValueCount uint32
|
||
|
Value []int64 `ndr:"pointer,conformant"`
|
||
|
}
|
||
|
|
||
|
// ClaimTypeUInt64 is a claim of type uint64
|
||
|
type ClaimTypeUInt64 struct {
|
||
|
ValueCount uint32
|
||
|
Value []uint64 `ndr:"pointer,conformant"`
|
||
|
}
|
||
|
|
||
|
// ClaimTypeString is a claim of type string
|
||
|
type ClaimTypeString struct {
|
||
|
ValueCount uint32
|
||
|
Value []LPWSTR `ndr:"pointer,conformant"`
|
||
|
}
|
||
|
|
||
|
// ClaimTypeBoolean is a claim of type bool
|
||
|
type ClaimTypeBoolean struct {
|
||
|
ValueCount uint32
|
||
|
Value []bool `ndr:"pointer,conformant"`
|
||
|
}
|