blob: b9f535f5b97a0a7194ec6b65b8febd2b1b57baf7 [file] [log] [blame]
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"`
}