gRPC migration update
Change-Id: Icdd1a824948fa994cd36bd121c962f5ecf74e3cf
diff --git a/vendor/github.com/jcmturner/gokrb5/v8/pac/client_claims.go b/vendor/github.com/jcmturner/gokrb5/v8/pac/client_claims.go
new file mode 100644
index 0000000..36871e0
--- /dev/null
+++ b/vendor/github.com/jcmturner/gokrb5/v8/pac/client_claims.go
@@ -0,0 +1,34 @@
+package pac
+
+import (
+ "bytes"
+ "fmt"
+
+ "github.com/jcmturner/rpc/v2/mstypes"
+ "github.com/jcmturner/rpc/v2/ndr"
+)
+
+// Claims reference: https://msdn.microsoft.com/en-us/library/hh553895.aspx
+
+// ClientClaimsInfo implements https://msdn.microsoft.com/en-us/library/hh536365.aspx
+type ClientClaimsInfo struct {
+ ClaimsSetMetadata mstypes.ClaimsSetMetadata
+ ClaimsSet mstypes.ClaimsSet
+}
+
+// Unmarshal bytes into the ClientClaimsInfo struct
+func (k *ClientClaimsInfo) Unmarshal(b []byte) (err error) {
+ dec := ndr.NewDecoder(bytes.NewReader(b))
+ m := new(mstypes.ClaimsSetMetadata)
+ err = dec.Decode(m)
+ if err != nil {
+ err = fmt.Errorf("error unmarshaling ClientClaimsInfo ClaimsSetMetadata: %v", err)
+ return
+ }
+ k.ClaimsSetMetadata = *m
+ k.ClaimsSet, err = k.ClaimsSetMetadata.ClaimsSet()
+ if err != nil {
+ err = fmt.Errorf("error unmarshaling ClientClaimsInfo ClaimsSet: %v", err)
+ }
+ return
+}
diff --git a/vendor/github.com/jcmturner/gokrb5/v8/pac/client_info.go b/vendor/github.com/jcmturner/gokrb5/v8/pac/client_info.go
new file mode 100644
index 0000000..ddd9578
--- /dev/null
+++ b/vendor/github.com/jcmturner/gokrb5/v8/pac/client_info.go
@@ -0,0 +1,31 @@
+package pac
+
+import (
+ "bytes"
+
+ "github.com/jcmturner/rpc/v2/mstypes"
+)
+
+// ClientInfo implements https://msdn.microsoft.com/en-us/library/cc237951.aspx
+type ClientInfo struct {
+ ClientID mstypes.FileTime // A FILETIME structure in little-endian format that contains the Kerberos initial ticket-granting ticket TGT authentication time
+ NameLength uint16 // An unsigned 16-bit integer in little-endian format that specifies the length, in bytes, of the Name field.
+ Name string // An array of 16-bit Unicode characters in little-endian format that contains the client's account name.
+}
+
+// Unmarshal bytes into the ClientInfo struct
+func (k *ClientInfo) Unmarshal(b []byte) (err error) {
+ //The PAC_CLIENT_INFO structure is a simple structure that is not NDR-encoded.
+ r := mstypes.NewReader(bytes.NewReader(b))
+
+ k.ClientID, err = r.FileTime()
+ if err != nil {
+ return
+ }
+ k.NameLength, err = r.Uint16()
+ if err != nil {
+ return
+ }
+ k.Name, err = r.UTF16String(int(k.NameLength))
+ return
+}
diff --git a/vendor/github.com/jcmturner/gokrb5/v8/pac/credentials_info.go b/vendor/github.com/jcmturner/gokrb5/v8/pac/credentials_info.go
new file mode 100644
index 0000000..0c7ccd4
--- /dev/null
+++ b/vendor/github.com/jcmturner/gokrb5/v8/pac/credentials_info.go
@@ -0,0 +1,86 @@
+package pac
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+
+ "github.com/jcmturner/gokrb5/v8/crypto"
+ "github.com/jcmturner/gokrb5/v8/iana/keyusage"
+ "github.com/jcmturner/gokrb5/v8/types"
+ "github.com/jcmturner/rpc/v2/mstypes"
+ "github.com/jcmturner/rpc/v2/ndr"
+)
+
+// https://msdn.microsoft.com/en-us/library/cc237931.aspx
+
+// CredentialsInfo implements https://msdn.microsoft.com/en-us/library/cc237953.aspx
+type CredentialsInfo struct {
+ Version uint32 // A 32-bit unsigned integer in little-endian format that defines the version. MUST be 0x00000000.
+ EType uint32
+ PACCredentialDataEncrypted []byte // Key usage number for encryption: KERB_NON_KERB_SALT (16)
+ PACCredentialData CredentialData
+}
+
+// Unmarshal bytes into the CredentialsInfo struct
+func (c *CredentialsInfo) Unmarshal(b []byte, k types.EncryptionKey) (err error) {
+ //The CredentialsInfo structure is a simple structure that is not NDR-encoded.
+ r := mstypes.NewReader(bytes.NewReader(b))
+
+ c.Version, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ if c.Version != 0 {
+ err = errors.New("credentials info version is not zero")
+ return
+ }
+ c.EType, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ c.PACCredentialDataEncrypted, err = r.ReadBytes(len(b) - 8)
+ if err != nil {
+ err = fmt.Errorf("error reading PAC Credetials Data: %v", err)
+ return
+ }
+
+ err = c.DecryptEncPart(k)
+ if err != nil {
+ err = fmt.Errorf("error decrypting PAC Credentials Data: %v", err)
+ return
+ }
+ return
+}
+
+// DecryptEncPart decrypts the encrypted part of the CredentialsInfo.
+func (c *CredentialsInfo) DecryptEncPart(k types.EncryptionKey) error {
+ if k.KeyType != int32(c.EType) {
+ return fmt.Errorf("key provided is not the correct type. Type needed: %d, type provided: %d", c.EType, k.KeyType)
+ }
+ pt, err := crypto.DecryptMessage(c.PACCredentialDataEncrypted, k, keyusage.KERB_NON_KERB_SALT)
+ if err != nil {
+ return err
+ }
+ err = c.PACCredentialData.Unmarshal(pt)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+// CredentialData implements https://msdn.microsoft.com/en-us/library/cc237952.aspx
+type CredentialData struct {
+ CredentialCount uint32
+ Credentials []SECPKGSupplementalCred // Size is the value of CredentialCount
+}
+
+// Unmarshal converts the bytes provided into a CredentialData type.
+func (c *CredentialData) Unmarshal(b []byte) (err error) {
+ dec := ndr.NewDecoder(bytes.NewReader(b))
+ err = dec.Decode(c)
+ if err != nil {
+ err = fmt.Errorf("error unmarshaling KerbValidationInfo: %v", err)
+ }
+ return
+}
diff --git a/vendor/github.com/jcmturner/gokrb5/v8/pac/device_claims.go b/vendor/github.com/jcmturner/gokrb5/v8/pac/device_claims.go
new file mode 100644
index 0000000..6eb2926
--- /dev/null
+++ b/vendor/github.com/jcmturner/gokrb5/v8/pac/device_claims.go
@@ -0,0 +1,34 @@
+package pac
+
+import (
+ "bytes"
+ "fmt"
+
+ "github.com/jcmturner/rpc/v2/mstypes"
+ "github.com/jcmturner/rpc/v2/ndr"
+)
+
+// Claims reference: https://msdn.microsoft.com/en-us/library/hh553895.aspx
+
+// DeviceClaimsInfo implements https://msdn.microsoft.com/en-us/library/hh554226.aspx
+type DeviceClaimsInfo struct {
+ ClaimsSetMetadata mstypes.ClaimsSetMetadata
+ ClaimsSet mstypes.ClaimsSet
+}
+
+// Unmarshal bytes into the ClientClaimsInfo struct
+func (k *DeviceClaimsInfo) Unmarshal(b []byte) (err error) {
+ dec := ndr.NewDecoder(bytes.NewReader(b))
+ m := new(mstypes.ClaimsSetMetadata)
+ err = dec.Decode(m)
+ if err != nil {
+ err = fmt.Errorf("error unmarshaling ClientClaimsInfo ClaimsSetMetadata: %v", err)
+ return
+ }
+ k.ClaimsSetMetadata = *m
+ k.ClaimsSet, err = k.ClaimsSetMetadata.ClaimsSet()
+ if err != nil {
+ err = fmt.Errorf("error unmarshaling ClientClaimsInfo ClaimsSet: %v", err)
+ }
+ return
+}
diff --git a/vendor/github.com/jcmturner/gokrb5/v8/pac/device_info.go b/vendor/github.com/jcmturner/gokrb5/v8/pac/device_info.go
new file mode 100644
index 0000000..ce82daa
--- /dev/null
+++ b/vendor/github.com/jcmturner/gokrb5/v8/pac/device_info.go
@@ -0,0 +1,32 @@
+package pac
+
+import (
+ "bytes"
+ "fmt"
+
+ "github.com/jcmturner/rpc/v2/mstypes"
+ "github.com/jcmturner/rpc/v2/ndr"
+)
+
+// DeviceInfo implements https://msdn.microsoft.com/en-us/library/hh536402.aspx
+type DeviceInfo struct {
+ UserID uint32 // A 32-bit unsigned integer that contains the RID of the account. If the UserId member equals 0x00000000, the first group SID in this member is the SID for this account.
+ PrimaryGroupID uint32 // A 32-bit unsigned integer that contains the RID for the primary group to which this account belongs.
+ AccountDomainID mstypes.RPCSID `ndr:"pointer"` // A SID structure that contains the SID for the domain of the account.This member is used in conjunction with the UserId, and GroupIds members to create the user and group SIDs for the client.
+ AccountGroupCount uint32 // A 32-bit unsigned integer that contains the number of groups within the account domain to which the account belongs
+ AccountGroupIDs []mstypes.GroupMembership `ndr:"pointer,conformant"` // A pointer to a list of GROUP_MEMBERSHIP (section 2.2.2) structures that contains the groups to which the account belongs in the account domain. The number of groups in this list MUST be equal to GroupCount.
+ SIDCount uint32 // A 32-bit unsigned integer that contains the total number of SIDs present in the ExtraSids member.
+ ExtraSIDs []mstypes.KerbSidAndAttributes `ndr:"pointer,conformant"` // A pointer to a list of KERB_SID_AND_ATTRIBUTES structures that contain a list of SIDs corresponding to groups not in domains. If the UserId member equals 0x00000000, the first group SID in this member is the SID for this account.
+ DomainGroupCount uint32 // A 32-bit unsigned integer that contains the number of domains with groups to which the account belongs.
+ DomainGroup []mstypes.DomainGroupMembership `ndr:"pointer,conformant"` // A pointer to a list of DOMAIN_GROUP_MEMBERSHIP structures (section 2.2.3) that contains the domains to which the account belongs to a group. The number of sets in this list MUST be equal to DomainCount.
+}
+
+// Unmarshal bytes into the DeviceInfo struct
+func (k *DeviceInfo) Unmarshal(b []byte) (err error) {
+ dec := ndr.NewDecoder(bytes.NewReader(b))
+ err = dec.Decode(k)
+ if err != nil {
+ err = fmt.Errorf("error unmarshaling DeviceInfo: %v", err)
+ }
+ return
+}
diff --git a/vendor/github.com/jcmturner/gokrb5/v8/pac/kerb_validation_info.go b/vendor/github.com/jcmturner/gokrb5/v8/pac/kerb_validation_info.go
new file mode 100644
index 0000000..dde7861
--- /dev/null
+++ b/vendor/github.com/jcmturner/gokrb5/v8/pac/kerb_validation_info.go
@@ -0,0 +1,110 @@
+// Package pac implements Microsoft Privilege Attribute Certificate (PAC) processing.
+package pac
+
+import (
+ "bytes"
+ "fmt"
+
+ "github.com/jcmturner/rpc/v2/mstypes"
+ "github.com/jcmturner/rpc/v2/ndr"
+)
+
+// KERB_VALIDATION_INFO flags.
+const (
+ USERFLAG_GUEST = 31 // Authentication was done via the GUEST account; no password was used.
+ USERFLAG_NO_ENCRYPTION_AVAILABLE = 30 // No encryption is available.
+ USERFLAG_LAN_MANAGER_KEY = 28 // LAN Manager key was used for authentication.
+ USERFLAG_SUB_AUTH = 25 // Sub-authentication used; session key came from the sub-authentication package.
+ USERFLAG_EXTRA_SIDS = 26 // Indicates that the ExtraSids field is populated and contains additional SIDs.
+ USERFLAG_MACHINE_ACCOUNT = 24 // Indicates that the account is a machine account.
+ USERFLAG_DC_NTLM2 = 23 // Indicates that the domain controller understands NTLMv2.
+ USERFLAG_RESOURCE_GROUPIDS = 22 // Indicates that the ResourceGroupIds field is populated.
+ USERFLAG_PROFILEPATH = 21 // Indicates that ProfilePath is populated.
+ USERFLAG_NTLM2_NTCHALLENGERESP = 20 // The NTLMv2 response from the NtChallengeResponseFields ([MS-NLMP] section 2.2.1.3) was used for authentication and session key generation.
+ USERFLAG_LM2_LMCHALLENGERESP = 19 // The LMv2 response from the LmChallengeResponseFields ([MS-NLMP] section 2.2.1.3) was used for authentication and session key generation.
+ USERFLAG_AUTH_LMCHALLENGERESP_KEY_NTCHALLENGERESP = 18 // The LMv2 response from the LmChallengeResponseFields ([MS-NLMP] section 2.2.1.3) was used for authentication and the NTLMv2 response from the NtChallengeResponseFields ([MS-NLMP] section 2.2.1.3) was used session key generation.
+)
+
+// KerbValidationInfo implement https://msdn.microsoft.com/en-us/library/cc237948.aspx
+type KerbValidationInfo struct {
+ LogOnTime mstypes.FileTime
+ LogOffTime mstypes.FileTime
+ KickOffTime mstypes.FileTime
+ PasswordLastSet mstypes.FileTime
+ PasswordCanChange mstypes.FileTime
+ PasswordMustChange mstypes.FileTime
+ EffectiveName mstypes.RPCUnicodeString
+ FullName mstypes.RPCUnicodeString
+ LogonScript mstypes.RPCUnicodeString
+ ProfilePath mstypes.RPCUnicodeString
+ HomeDirectory mstypes.RPCUnicodeString
+ HomeDirectoryDrive mstypes.RPCUnicodeString
+ LogonCount uint16
+ BadPasswordCount uint16
+ UserID uint32
+ PrimaryGroupID uint32
+ GroupCount uint32
+ GroupIDs []mstypes.GroupMembership `ndr:"pointer,conformant"`
+ UserFlags uint32
+ UserSessionKey mstypes.UserSessionKey
+ LogonServer mstypes.RPCUnicodeString
+ LogonDomainName mstypes.RPCUnicodeString
+ LogonDomainID mstypes.RPCSID `ndr:"pointer"`
+ Reserved1 [2]uint32 // Has 2 elements
+ UserAccountControl uint32
+ SubAuthStatus uint32
+ LastSuccessfulILogon mstypes.FileTime
+ LastFailedILogon mstypes.FileTime
+ FailedILogonCount uint32
+ Reserved3 uint32
+ SIDCount uint32
+ ExtraSIDs []mstypes.KerbSidAndAttributes `ndr:"pointer,conformant"`
+ ResourceGroupDomainSID mstypes.RPCSID `ndr:"pointer"`
+ ResourceGroupCount uint32
+ ResourceGroupIDs []mstypes.GroupMembership `ndr:"pointer,conformant"`
+}
+
+// Unmarshal bytes into the DeviceInfo struct
+func (k *KerbValidationInfo) Unmarshal(b []byte) (err error) {
+ dec := ndr.NewDecoder(bytes.NewReader(b))
+ err = dec.Decode(k)
+ if err != nil {
+ err = fmt.Errorf("error unmarshaling KerbValidationInfo: %v", err)
+ }
+ return
+}
+
+// GetGroupMembershipSIDs returns a slice of strings containing the group membership SIDs found in the PAC.
+func (k *KerbValidationInfo) GetGroupMembershipSIDs() []string {
+ var g []string
+ lSID := k.LogonDomainID.String()
+ for i := range k.GroupIDs {
+ g = append(g, fmt.Sprintf("%s-%d", lSID, k.GroupIDs[i].RelativeID))
+ }
+ for _, s := range k.ExtraSIDs {
+ var exists = false
+ for _, es := range g {
+ if es == s.SID.String() {
+ exists = true
+ break
+ }
+ }
+ if !exists {
+ g = append(g, s.SID.String())
+ }
+ }
+ for _, r := range k.ResourceGroupIDs {
+ var exists = false
+ s := fmt.Sprintf("%s-%d", k.ResourceGroupDomainSID.String(), r.RelativeID)
+ for _, es := range g {
+ if es == s {
+ exists = true
+ break
+ }
+ }
+ if !exists {
+ g = append(g, s)
+ }
+ }
+ return g
+}
diff --git a/vendor/github.com/jcmturner/gokrb5/v8/pac/pac_type.go b/vendor/github.com/jcmturner/gokrb5/v8/pac/pac_type.go
new file mode 100644
index 0000000..fab2ad7
--- /dev/null
+++ b/vendor/github.com/jcmturner/gokrb5/v8/pac/pac_type.go
@@ -0,0 +1,251 @@
+package pac
+
+import (
+ "bytes"
+ "errors"
+ "fmt"
+ "log"
+
+ "github.com/jcmturner/gokrb5/v8/crypto"
+ "github.com/jcmturner/gokrb5/v8/iana/keyusage"
+ "github.com/jcmturner/gokrb5/v8/types"
+ "github.com/jcmturner/rpc/v2/mstypes"
+)
+
+const (
+ infoTypeKerbValidationInfo uint32 = 1
+ infoTypeCredentials uint32 = 2
+ infoTypePACServerSignatureData uint32 = 6
+ infoTypePACKDCSignatureData uint32 = 7
+ infoTypePACClientInfo uint32 = 10
+ infoTypeS4UDelegationInfo uint32 = 11
+ infoTypeUPNDNSInfo uint32 = 12
+ infoTypePACClientClaimsInfo uint32 = 13
+ infoTypePACDeviceInfo uint32 = 14
+ infoTypePACDeviceClaimsInfo uint32 = 15
+)
+
+// PACType implements: https://msdn.microsoft.com/en-us/library/cc237950.aspx
+type PACType struct {
+ CBuffers uint32
+ Version uint32
+ Buffers []InfoBuffer
+ Data []byte
+ KerbValidationInfo *KerbValidationInfo
+ CredentialsInfo *CredentialsInfo
+ ServerChecksum *SignatureData
+ KDCChecksum *SignatureData
+ ClientInfo *ClientInfo
+ S4UDelegationInfo *S4UDelegationInfo
+ UPNDNSInfo *UPNDNSInfo
+ ClientClaimsInfo *ClientClaimsInfo
+ DeviceInfo *DeviceInfo
+ DeviceClaimsInfo *DeviceClaimsInfo
+ ZeroSigData []byte
+}
+
+// InfoBuffer implements the PAC Info Buffer: https://msdn.microsoft.com/en-us/library/cc237954.aspx
+type InfoBuffer struct {
+ ULType uint32 // A 32-bit unsigned integer in little-endian format that describes the type of data present in the buffer contained at Offset.
+ CBBufferSize uint32 // A 32-bit unsigned integer in little-endian format that contains the size, in bytes, of the buffer in the PAC located at Offset.
+ Offset uint64 // A 64-bit unsigned integer in little-endian format that contains the offset to the beginning of the buffer, in bytes, from the beginning of the PACTYPE structure. The data offset MUST be a multiple of eight. The following sections specify the format of each type of element.
+}
+
+// Unmarshal bytes into the PACType struct
+func (pac *PACType) Unmarshal(b []byte) (err error) {
+ pac.Data = b
+ zb := make([]byte, len(b), len(b))
+ copy(zb, b)
+ pac.ZeroSigData = zb
+ r := mstypes.NewReader(bytes.NewReader(b))
+ pac.CBuffers, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ pac.Version, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ buf := make([]InfoBuffer, pac.CBuffers, pac.CBuffers)
+ for i := range buf {
+ buf[i].ULType, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ buf[i].CBBufferSize, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ buf[i].Offset, err = r.Uint64()
+ if err != nil {
+ return
+ }
+ }
+ pac.Buffers = buf
+ return nil
+}
+
+// ProcessPACInfoBuffers processes the PAC Info Buffers.
+// https://msdn.microsoft.com/en-us/library/cc237954.aspx
+func (pac *PACType) ProcessPACInfoBuffers(key types.EncryptionKey, l *log.Logger) error {
+ for _, buf := range pac.Buffers {
+ p := make([]byte, buf.CBBufferSize, buf.CBBufferSize)
+ copy(p, pac.Data[int(buf.Offset):int(buf.Offset)+int(buf.CBBufferSize)])
+ switch buf.ULType {
+ case infoTypeKerbValidationInfo:
+ if pac.KerbValidationInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k KerbValidationInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ return fmt.Errorf("error processing KerbValidationInfo: %v", err)
+ }
+ pac.KerbValidationInfo = &k
+ case infoTypeCredentials:
+ // Currently PAC parsing is only useful on the service side in gokrb5
+ // The CredentialsInfo are only useful when gokrb5 has implemented RFC4556 and only applied on the client side.
+ // Skipping CredentialsInfo - will be revisited under RFC4556 implementation.
+ continue
+ //if pac.CredentialsInfo != nil {
+ // //Must ignore subsequent buffers of this type
+ // continue
+ //}
+ //var k CredentialsInfo
+ //err := k.Unmarshal(p, key) // The encryption key used is the AS reply key only available to the client.
+ //if err != nil {
+ // return fmt.Errorf("error processing CredentialsInfo: %v", err)
+ //}
+ //pac.CredentialsInfo = &k
+ case infoTypePACServerSignatureData:
+ if pac.ServerChecksum != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k SignatureData
+ zb, err := k.Unmarshal(p)
+ copy(pac.ZeroSigData[int(buf.Offset):int(buf.Offset)+int(buf.CBBufferSize)], zb)
+ if err != nil {
+ return fmt.Errorf("error processing ServerChecksum: %v", err)
+ }
+ pac.ServerChecksum = &k
+ case infoTypePACKDCSignatureData:
+ if pac.KDCChecksum != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k SignatureData
+ zb, err := k.Unmarshal(p)
+ copy(pac.ZeroSigData[int(buf.Offset):int(buf.Offset)+int(buf.CBBufferSize)], zb)
+ if err != nil {
+ return fmt.Errorf("error processing KDCChecksum: %v", err)
+ }
+ pac.KDCChecksum = &k
+ case infoTypePACClientInfo:
+ if pac.ClientInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k ClientInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ return fmt.Errorf("error processing ClientInfo: %v", err)
+ }
+ pac.ClientInfo = &k
+ case infoTypeS4UDelegationInfo:
+ if pac.S4UDelegationInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k S4UDelegationInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ l.Printf("could not process S4U_DelegationInfo: %v", err)
+ continue
+ }
+ pac.S4UDelegationInfo = &k
+ case infoTypeUPNDNSInfo:
+ if pac.UPNDNSInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k UPNDNSInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ l.Printf("could not process UPN_DNSInfo: %v", err)
+ continue
+ }
+ pac.UPNDNSInfo = &k
+ case infoTypePACClientClaimsInfo:
+ if pac.ClientClaimsInfo != nil || len(p) < 1 {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k ClientClaimsInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ l.Printf("could not process ClientClaimsInfo: %v", err)
+ continue
+ }
+ pac.ClientClaimsInfo = &k
+ case infoTypePACDeviceInfo:
+ if pac.DeviceInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k DeviceInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ l.Printf("could not process DeviceInfo: %v", err)
+ continue
+ }
+ pac.DeviceInfo = &k
+ case infoTypePACDeviceClaimsInfo:
+ if pac.DeviceClaimsInfo != nil {
+ //Must ignore subsequent buffers of this type
+ continue
+ }
+ var k DeviceClaimsInfo
+ err := k.Unmarshal(p)
+ if err != nil {
+ l.Printf("could not process DeviceClaimsInfo: %v", err)
+ continue
+ }
+ pac.DeviceClaimsInfo = &k
+ }
+ }
+
+ if ok, err := pac.verify(key); !ok {
+ return err
+ }
+
+ return nil
+}
+
+func (pac *PACType) verify(key types.EncryptionKey) (bool, error) {
+ if pac.KerbValidationInfo == nil {
+ return false, errors.New("PAC Info Buffers does not contain a KerbValidationInfo")
+ }
+ if pac.ServerChecksum == nil {
+ return false, errors.New("PAC Info Buffers does not contain a ServerChecksum")
+ }
+ if pac.KDCChecksum == nil {
+ return false, errors.New("PAC Info Buffers does not contain a KDCChecksum")
+ }
+ if pac.ClientInfo == nil {
+ return false, errors.New("PAC Info Buffers does not contain a ClientInfo")
+ }
+ etype, err := crypto.GetChksumEtype(int32(pac.ServerChecksum.SignatureType))
+ if err != nil {
+ return false, err
+ }
+ if ok := etype.VerifyChecksum(key.KeyValue,
+ pac.ZeroSigData,
+ pac.ServerChecksum.Signature,
+ keyusage.KERB_NON_KERB_CKSUM_SALT); !ok {
+ return false, errors.New("PAC service checksum verification failed")
+ }
+
+ return true, nil
+}
diff --git a/vendor/github.com/jcmturner/gokrb5/v8/pac/s4u_delegation_info.go b/vendor/github.com/jcmturner/gokrb5/v8/pac/s4u_delegation_info.go
new file mode 100644
index 0000000..da837d4
--- /dev/null
+++ b/vendor/github.com/jcmturner/gokrb5/v8/pac/s4u_delegation_info.go
@@ -0,0 +1,26 @@
+package pac
+
+import (
+ "bytes"
+ "fmt"
+
+ "github.com/jcmturner/rpc/v2/mstypes"
+ "github.com/jcmturner/rpc/v2/ndr"
+)
+
+// S4UDelegationInfo implements https://msdn.microsoft.com/en-us/library/cc237944.aspx
+type S4UDelegationInfo struct {
+ S4U2proxyTarget mstypes.RPCUnicodeString // The name of the principal to whom the application can forward the ticket.
+ TransitedListSize uint32
+ S4UTransitedServices []mstypes.RPCUnicodeString `ndr:"pointer,conformant"` // List of all services that have been delegated through by this client and subsequent services or servers.. Size is value of TransitedListSize
+}
+
+// Unmarshal bytes into the S4UDelegationInfo struct
+func (k *S4UDelegationInfo) Unmarshal(b []byte) (err error) {
+ dec := ndr.NewDecoder(bytes.NewReader(b))
+ err = dec.Decode(k)
+ if err != nil {
+ err = fmt.Errorf("error unmarshaling S4UDelegationInfo: %v", err)
+ }
+ return
+}
diff --git a/vendor/github.com/jcmturner/gokrb5/v8/pac/signature_data.go b/vendor/github.com/jcmturner/gokrb5/v8/pac/signature_data.go
new file mode 100644
index 0000000..8f6aa58
--- /dev/null
+++ b/vendor/github.com/jcmturner/gokrb5/v8/pac/signature_data.go
@@ -0,0 +1,67 @@
+package pac
+
+import (
+ "bytes"
+
+ "github.com/jcmturner/gokrb5/v8/iana/chksumtype"
+ "github.com/jcmturner/rpc/v2/mstypes"
+)
+
+/*
+https://msdn.microsoft.com/en-us/library/cc237955.aspx
+
+The Key Usage Value MUST be KERB_NON_KERB_CKSUM_SALT (17) [MS-KILE] (section 3.1.5.9).
+
+Server Signature (SignatureType = 0x00000006)
+https://msdn.microsoft.com/en-us/library/cc237957.aspx
+
+KDC Signature (SignatureType = 0x00000007)
+https://msdn.microsoft.com/en-us/library/dd357117.aspx
+*/
+
+// SignatureData implements https://msdn.microsoft.com/en-us/library/cc237955.aspx
+type SignatureData struct {
+ SignatureType uint32 // A 32-bit unsigned integer value in little-endian format that defines the cryptographic system used to calculate the checksum. This MUST be one of the following checksum types: KERB_CHECKSUM_HMAC_MD5 (signature size = 16), HMAC_SHA1_96_AES128 (signature size = 12), HMAC_SHA1_96_AES256 (signature size = 12).
+ Signature []byte // Size depends on the type. See comment above.
+ RODCIdentifier uint16 // A 16-bit unsigned integer value in little-endian format that contains the first 16 bits of the key version number ([MS-KILE] section 3.1.5.8) when the KDC is an RODC. When the KDC is not an RODC, this field does not exist.
+}
+
+// Unmarshal bytes into the SignatureData struct
+func (k *SignatureData) Unmarshal(b []byte) (rb []byte, err error) {
+ r := mstypes.NewReader(bytes.NewReader(b))
+
+ k.SignatureType, err = r.Uint32()
+ if err != nil {
+ return
+ }
+
+ var c int
+ switch k.SignatureType {
+ case chksumtype.KERB_CHECKSUM_HMAC_MD5_UNSIGNED:
+ c = 16
+ case uint32(chksumtype.HMAC_SHA1_96_AES128):
+ c = 12
+ case uint32(chksumtype.HMAC_SHA1_96_AES256):
+ c = 12
+ }
+ k.Signature, err = r.ReadBytes(c)
+ if err != nil {
+ return
+ }
+
+ // When the KDC is not an Read Only Domain Controller (RODC), this field does not exist.
+ if len(b) >= 4+c+2 {
+ k.RODCIdentifier, err = r.Uint16()
+ if err != nil {
+ return
+ }
+ }
+
+ // Create bytes with zeroed signature needed for checksum verification
+ rb = make([]byte, len(b), len(b))
+ copy(rb, b)
+ z := make([]byte, len(b), len(b))
+ copy(rb[4:4+c], z)
+
+ return
+}
diff --git a/vendor/github.com/jcmturner/gokrb5/v8/pac/supplemental_cred.go b/vendor/github.com/jcmturner/gokrb5/v8/pac/supplemental_cred.go
new file mode 100644
index 0000000..d40679d
--- /dev/null
+++ b/vendor/github.com/jcmturner/gokrb5/v8/pac/supplemental_cred.go
@@ -0,0 +1,87 @@
+package pac
+
+import (
+ "bytes"
+ "encoding/binary"
+ "errors"
+ "fmt"
+
+ "github.com/jcmturner/rpc/v2/mstypes"
+ "github.com/jcmturner/rpc/v2/ndr"
+)
+
+const (
+ // NTLMSupCredLMOWF indicates that the LM OWF member is present and valid.
+ NTLMSupCredLMOWF uint32 = 31
+ // NTLMSupCredNTOWF indicates that the NT OWF member is present and valid.
+ NTLMSupCredNTOWF uint32 = 30
+)
+
+// NTLMSupplementalCred implements https://msdn.microsoft.com/en-us/library/cc237949.aspx
+type NTLMSupplementalCred struct {
+ Version uint32 // A 32-bit unsigned integer that defines the credential version.This field MUST be 0x00000000.
+ Flags uint32
+ 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.
+ 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.
+}
+
+// Unmarshal converts the bytes provided into a NTLMSupplementalCred.
+func (c *NTLMSupplementalCred) Unmarshal(b []byte) (err error) {
+ r := mstypes.NewReader(bytes.NewReader(b))
+ c.Version, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ if c.Version != 0 {
+ err = errors.New("NTLMSupplementalCred version is not zero")
+ return
+ }
+ c.Flags, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ if isFlagSet(c.Flags, NTLMSupCredLMOWF) {
+ c.LMPassword, err = r.ReadBytes(16)
+ if err != nil {
+ return
+ }
+ }
+ if isFlagSet(c.Flags, NTLMSupCredNTOWF) {
+ c.NTPassword, err = r.ReadBytes(16)
+ if err != nil {
+ return
+ }
+ }
+ return
+}
+
+// isFlagSet tests if a flag is set in the uint32 little endian flag
+func isFlagSet(f uint32, i uint32) bool {
+ //Which byte?
+ b := int(i / 8)
+ //Which bit in byte
+ p := uint(7 - (int(i) - 8*b))
+ fb := make([]byte, 4)
+ binary.LittleEndian.PutUint32(fb, f)
+ if fb[b]&(1<<p) != 0 {
+ return true
+ }
+ return false
+}
+
+// SECPKGSupplementalCred implements https://msdn.microsoft.com/en-us/library/cc237956.aspx
+type SECPKGSupplementalCred struct {
+ PackageName mstypes.RPCUnicodeString
+ CredentialSize uint32
+ Credentials []uint8 `ndr:"pointer,conformant"` // Is a ptr. Size is the value of CredentialSize
+}
+
+// Unmarshal converts the bytes provided into a SECPKGSupplementalCred.
+func (c *SECPKGSupplementalCred) Unmarshal(b []byte) (err error) {
+ dec := ndr.NewDecoder(bytes.NewReader(b))
+ err = dec.Decode(c)
+ if err != nil {
+ err = fmt.Errorf("error unmarshaling SECPKGSupplementalCred: %v", err)
+ }
+ return
+}
diff --git a/vendor/github.com/jcmturner/gokrb5/v8/pac/upn_dns_info.go b/vendor/github.com/jcmturner/gokrb5/v8/pac/upn_dns_info.go
new file mode 100644
index 0000000..d374b96
--- /dev/null
+++ b/vendor/github.com/jcmturner/gokrb5/v8/pac/upn_dns_info.go
@@ -0,0 +1,73 @@
+package pac
+
+import (
+ "bytes"
+
+ "github.com/jcmturner/rpc/v2/mstypes"
+)
+
+// UPNDNSInfo implements https://msdn.microsoft.com/en-us/library/dd240468.aspx
+type UPNDNSInfo struct {
+ UPNLength uint16 // An unsigned 16-bit integer in little-endian format that specifies the length, in bytes, of the UPN field.
+ UPNOffset uint16 // An unsigned 16-bit integer in little-endian format that contains the offset to the beginning of the buffer, in bytes, from the beginning of the UPN_DNS_INFO structure.
+ DNSDomainNameLength uint16
+ DNSDomainNameOffset uint16
+ Flags uint32
+ UPN string
+ DNSDomain string
+}
+
+const (
+ upnNoUPNAttr = 31 // The user account object does not have the userPrincipalName attribute ([MS-ADA3] section 2.349) set. A UPN constructed by concatenating the user name with the DNS domain name of the account domain is provided.
+)
+
+// Unmarshal bytes into the UPN_DNSInfo struct
+func (k *UPNDNSInfo) Unmarshal(b []byte) (err error) {
+ //The UPN_DNS_INFO structure is a simple structure that is not NDR-encoded.
+ r := mstypes.NewReader(bytes.NewReader(b))
+ k.UPNLength, err = r.Uint16()
+ if err != nil {
+ return
+ }
+ k.UPNOffset, err = r.Uint16()
+ if err != nil {
+ return
+ }
+ k.DNSDomainNameLength, err = r.Uint16()
+ if err != nil {
+ return
+ }
+ k.DNSDomainNameOffset, err = r.Uint16()
+ if err != nil {
+ return
+ }
+ k.Flags, err = r.Uint32()
+ if err != nil {
+ return
+ }
+ ub := mstypes.NewReader(bytes.NewReader(b[k.UPNOffset : k.UPNOffset+k.UPNLength]))
+ db := mstypes.NewReader(bytes.NewReader(b[k.DNSDomainNameOffset : k.DNSDomainNameOffset+k.DNSDomainNameLength]))
+
+ u := make([]rune, k.UPNLength/2, k.UPNLength/2)
+ for i := 0; i < len(u); i++ {
+ var r uint16
+ r, err = ub.Uint16()
+ if err != nil {
+ return
+ }
+ u[i] = rune(r)
+ }
+ k.UPN = string(u)
+ d := make([]rune, k.DNSDomainNameLength/2, k.DNSDomainNameLength/2)
+ for i := 0; i < len(d); i++ {
+ var r uint16
+ r, err = db.Uint16()
+ if err != nil {
+ return
+ }
+ d[i] = rune(r)
+ }
+ k.DNSDomain = string(d)
+
+ return
+}