コード例 #1
0
            protected override Task <HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
            {
                var realmService = new FakeRealmService(Realm);
                var principal    = realmService.Principals.Find(KrbPrincipalName.FromString(UserUpn));

                var principalKey = principal.RetrieveLongTermCredential();

                var rst = new ServiceTicketRequest
                {
                    Principal           = principal,
                    EncryptedPartKey    = principalKey,
                    ServicePrincipalKey = new KerberosKey(key: TgtKey, etype: EncryptionType.AES256_CTS_HMAC_SHA1_96)
                };

                var tgt = KrbAsRep.GenerateTgt(rst, realmService);

                var encoded = tgt.EncodeApplication();

                var response = new Memory <byte>(new byte[encoded.Length + 4]);

                BinaryPrimitives.WriteInt32BigEndian(response.Span.Slice(0, 4), encoded.Length);
                encoded.CopyTo(response.Slice(4));

                var kdcMessage = new KdcProxyMessage
                {
                    KerbMessage = response
                };

                return(Task.FromResult(new HttpResponseMessage(HttpStatusCode.OK)
                {
                    Content = new ByteArrayContent(kdcMessage.Encode().ToArray())
                }));
            }
コード例 #2
0
        public void PrincipalName_Equality_DifferentServiceTypes()
        {
            var a = KrbPrincipalName.FromString("aaaa/aaaa");
            var b = KrbPrincipalName.FromString("bbbb/aaaa");

            Assert.IsFalse(a.Matches(b));
        }
コード例 #3
0
        public void KrbAuthenticator_Roundtrip()
        {
            var auth = new KrbAuthenticator
            {
                AuthorizationData = new[] { new KrbAuthorizationData {
                                                Data = new byte[16], Type = AuthorizationDataType.AdAndOr
                                            } },
                Checksum       = KrbChecksum.Create(new byte[16], new KerberosKey(key: new byte[16], etype: EncryptionType.AES128_CTS_HMAC_SHA1_96), KeyUsage.AdKdcIssuedChecksum),
                CName          = KrbPrincipalName.FromString("*****@*****.**"),
                CTime          = DateTimeOffset.UtcNow,
                CuSec          = 1234,
                Realm          = "blah.com",
                SequenceNumber = 123456,
                Subkey         = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96)
            };

            var encoded = auth.EncodeApplication();

            var decoded = KrbAuthenticator.DecodeApplication(encoded);

            Assert.IsNotNull(decoded);
            Assert.IsNotNull(decoded.AuthorizationData);
            Assert.AreEqual(1, decoded.AuthorizationData.Length);
            Assert.AreEqual(AuthorizationDataType.AdAndOr, decoded.AuthorizationData[0].Type);
            Assert.AreEqual("*****@*****.**", decoded.CName.FullyQualifiedName);
        }
コード例 #4
0
ファイル: KeyTable.cs プロジェクト: zha0/Kerberos.NET
        public KerberosKey GetKey(EncryptionType type, KrbPrincipalName sname)
        {
            // Match on type (e.g. RC4_HMAC_NT) and name (Realm + Name)

            var entry = Entries
                        .Where(e => e.EncryptionType == type && sname.Matches(e.Principal))
                        .OrderByDescending(x => x.Version)
                        .FirstOrDefault();

            // Fall back to first entry with matching type (RC4_HMAC_NT)

            if (entry == null)
            {
                entry = Entries
                        .Where(e => e.EncryptionType == type)
                        .OrderByDescending(x => x.Version)
                        .FirstOrDefault();;
            }

            // Fall back to first entry

            if (entry == null)
            {
                entry = Entries.FirstOrDefault();
            }

            return(entry?.Key);
        }
コード例 #5
0
        private static KerberosKey ConvertKey(NetworkCredential creds, bool tryAsKey)
        {
            string domain = creds.Domain ?? "";

            var userSplit = creds.UserName.Split(new[] { '\\', '@' }, StringSplitOptions.RemoveEmptyEntries);

            string username = userSplit[0];

            if (userSplit.Length > 1)
            {
                domain = userSplit[1];
            }

            var name = KrbPrincipalName.FromString(username, realm: domain);

            if (tryAsKey)
            {
                return(new KerberosKey(
                           key: Convert.FromBase64String(creds.Password),
                           principal: new PrincipalName(PrincipalNameType.NT_SRV_HST, domain, name.Name),
                           host: username
                           ));
            }
            else
            {
                return(new KerberosKey(
                           creds.Password,
                           new PrincipalName(PrincipalNameType.NT_SRV_HST, domain, name.Name),
                           host: username
                           ));
            }
        }
コード例 #6
0
        public void PrincipalName_NoRealm()
        {
            var principal = KrbPrincipalName.FromString("*****@*****.**");

            Assert.AreEqual("*****@*****.**", principal.FullyQualifiedName);
            Assert.AreEqual(1, principal.Name.Length);
        }
コード例 #7
0
 private static object CredToCacheEntry(Krb5Credential cred)
 {
     return(new KerberosClientCacheEntry
     {
         KdcResponse = new KrbTgsRep
         {
             Ticket = KrbTicket.DecodeApplication(cred.Ticket),
             CName = KrbPrincipalName.FromString(cred.Client.FullyQualifiedName, cred.Client.Type),
             CRealm = cred.Client.Realm,
             EncPart = new KrbEncryptedData {
             }
         },
         SessionKey = new KrbEncryptionKey
         {
             EType = cred.KeyBlock.Key,
             KeyValue = cred.KeyBlock.Value
         },
         Flags = cred.Flags,
         SName = KrbPrincipalName.FromString(cred.Server.FullyQualifiedName),
         AuthTime = cred.AuthTime,
         StartTime = cred.StartTime,
         EndTime = cred.EndTime,
         RenewTill = cred.RenewTill <= DateTimeOffset.MinValue ? null : cred.RenewTill
     });
 }
コード例 #8
0
        public void PrincipalName_X500_IncludeDomain()
        {
            var principal = KrbPrincipalName.FromString(principal: "CN=test,OU=blah", type: PrincipalNameType.NT_X500_PRINCIPAL, realm: "corp.test.internal");

            Assert.AreEqual("CN=test,OU=blah,DC=corp,DC=test,DC=internal", principal.FullyQualifiedName);
            Assert.AreEqual(5, principal.Name.Length);
        }
コード例 #9
0
        public void PrincipalName_Empty()
        {
            var principal = KrbPrincipalName.FromString(principal: "");

            Assert.IsNotNull(principal);
            Assert.AreEqual("", principal.FullyQualifiedName);
        }
コード例 #10
0
        public void PrincipalName_DifferentRealms()
        {
            var principal = KrbPrincipalName.FromString(principal: "*****@*****.**", realm: "corp.test.internal");

            Assert.AreEqual("*****@*****.**", principal.FullyQualifiedName);
            Assert.AreEqual(1, principal.Name.Length);
        }
コード例 #11
0
        public void PrincipalName_SrvInst()
        {
            var principal = KrbPrincipalName.FromString(principal: "krbtgt", type: PrincipalNameType.NT_SRV_INST, realm: "corp.test.internal");

            Assert.AreEqual("krbtgt/corp.test.internal", principal.FullyQualifiedName);
            Assert.AreEqual(2, principal.Name.Length);
        }
コード例 #12
0
ファイル: KeyTableTests.cs プロジェクト: dotnet/Kerberos.NET
        public void MultipleVersionsInSameKeytab()
        {
            var keys = new[] {
                new KerberosKey(
                    "password",
                    new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "REALM.COM", new[] { "host/appservice" }),
                    host: "appservice",
                    etype: EncryptionType.AES256_CTS_HMAC_SHA1_96,
                    kvno: 1
                    ),
                new KerberosKey(
                    "password",
                    new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "REALM.COM", new[] { "host/appservice" }),
                    host: "appservice",
                    etype: EncryptionType.AES256_CTS_HMAC_SHA1_96,
                    kvno: 2
                    ),
                new KerberosKey(
                    "password",
                    new PrincipalName(PrincipalNameType.NT_PRINCIPAL, "REALM.COM", new[] { "host/appservice" }),
                    host: "appservice",
                    etype: EncryptionType.AES256_CTS_HMAC_SHA1_96,
                    kvno: 12
                    )
            };

            var keytable = new KeyTable(keys);
            var key      = keytable.GetKey(EncryptionType.AES256_CTS_HMAC_SHA1_96, KrbPrincipalName.FromString("host/appservice"));

            Assert.AreEqual(12, key.Version);
        }
コード例 #13
0
        public void PrincipalName_NoRealm_SrvInst()
        {
            var principal = KrbPrincipalName.FromString("host/test.internal", type: PrincipalNameType.NT_SRV_INST);

            Assert.AreEqual("host/test.internal", principal.FullyQualifiedName);
            Assert.AreEqual(2, principal.Name.Length);
        }
コード例 #14
0
        public void PrincipalName_Equality_ServiceTypes_WithRealm()
        {
            var a = KrbPrincipalName.FromString("host/[email protected]");
            var b = KrbPrincipalName.FromString("host/[email protected]");

            Assert.IsTrue(a.Matches(b));
        }
コード例 #15
0
        public void KerberosKeyExportFile()
        {
            var file = KerberosKey.GenerateFile(
                "P@ssw0rd!",
                new Guid("0aa29dcb-3a9b-413f-aee2-8df91fd1118e"),
                KrbPrincipalName.FromString(
                    "host/test.identityintervention.com",
                    PrincipalNameType.NT_SRV_INST,
                    "corp.identityintervention.com"
                    )
                );

            var keytab = new KeyTable(file.ToArray());

            Assert.AreEqual(1, keytab.Entries.Count());

            var key = keytab.Entries.First();

            Assert.AreEqual(EncryptionType.AES256_CTS_HMAC_SHA1_96, key.EncryptionType);

            var derivedKey = key.Key.GetKey(null);

            Assert.IsNotNull(derivedKey);

            var expectedKey = new byte[]
            {
                0xbc, 0x31, 0x7e, 0x82, 0x48, 0x55, 0xcb, 0xa0, 0x3f, 0x70, 0xbe, 0x93, 0x0a, 0xa5, 0x0f, 0xef,
                0x6a, 0x64, 0x7c, 0xc3, 0x99, 0x36, 0x63, 0xee, 0xa5, 0x39, 0x2f, 0xab, 0xd9, 0x01, 0xad, 0xce
            };

            Assert.IsTrue(expectedKey.SequenceEqual(derivedKey.ToArray()));
        }
コード例 #16
0
        internal object GetCacheItem(string key)
        {
            Krb5Credential cred = this.FindCredential(key);

            if (cred is null)
            {
                return(cred);
            }

            return(new KerberosClientCacheEntry
            {
                KdcResponse = new KrbTgsRep
                {
                    Ticket = KrbTicket.DecodeApplication(cred.Ticket),
                    CName = KrbPrincipalName.FromString(cred.Client.FullyQualifiedName),
                    CRealm = cred.Client.Realm,
                    EncPart = new KrbEncryptedData {
                    }
                },
                SessionKey = new KrbEncryptionKey
                {
                    EType = cred.KeyBlock.Key,
                    KeyValue = cred.KeyBlock.Value
                },
                Flags = cred.Flags,
                SName = KrbPrincipalName.FromString(cred.Server.FullyQualifiedName)
            });
        }
コード例 #17
0
        public void PrincipalName_Equality_DifferentNames()
        {
            var a = KrbPrincipalName.FromString("*****@*****.**");
            var b = KrbPrincipalName.FromString("*****@*****.**");

            Assert.IsFalse(a.Matches(b));
        }
コード例 #18
0
        public static ReadOnlyMemory <byte> GenerateFile(
            string password,
            Guid saltGuid,
            KrbPrincipalName name,
            EncryptionType etype = EncryptionType.AES256_CTS_HMAC_SHA1_96
            )
        {
            var salt = NormalizeGuid(saltGuid);

            var kerbKey = new KerberosKey(
                password: password,
                etype: etype,
                salt: salt,
                principalName: name.ToKeyPrincipal()
                );

            using (var stream = new MemoryStream())
                using (var writer = new BinaryWriter(stream))
                {
                    var keytab = new KeyTable(kerbKey);

                    keytab.Write(writer);

                    return(stream.ToArray());
                }
        }
コード例 #19
0
        public void PrincipalName_Equality_Matches_DifferentNameTypes_Service()
        {
            var a = KrbPrincipalName.FromString("host/[email protected]", PrincipalNameType.NT_SRV_HST);
            var b = KrbPrincipalName.FromString("*****@*****.**", PrincipalNameType.NT_PRINCIPAL);

            Assert.IsFalse(a.Matches(b));
        }
コード例 #20
0
 private static TicketCacheEntry CreateCacheEntry(string key = "krbtgt/bar.com")
 {
     return(new TicketCacheEntry
     {
         Key = key,
         Value = new KerberosClientCacheEntry
         {
             KdcResponse = new KrbAsRep
             {
                 CName = KrbPrincipalName.FromString("*****@*****.**"),
                 CRealm = "bar.com",
                 Ticket = new KrbTicket
                 {
                     Realm = "bar.com",
                     SName = KrbPrincipalName.FromString(key),
                     EncryptedPart = new KrbEncryptedData
                     {
                         EType = EncryptionType.AES128_CTS_HMAC_SHA1_96,
                         Cipher = Array.Empty <byte>()
                     }
                 }
             },
             SessionKey = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96),
             SName = KrbPrincipalName.FromString(key)
         }
     });
 }
コード例 #21
0
        public void PrincipalName_Equality_Matches()
        {
            var a = KrbPrincipalName.FromString("*****@*****.**");
            var b = KrbPrincipalName.FromString("*****@*****.**");

            Assert.IsTrue(a.Matches(b));
        }
コード例 #22
0
        internal void Validate(KeyTable keytab, KrbPrincipalName sname)
        {
            var key = keytab.GetKey(Type, sname);

            Validator.Validate(key);

            Validated = true;
        }
コード例 #23
0
    public IKerberosPrincipal?Find(KrbPrincipalName principalName, string?realm = null)
    {
        if (_principals.TryGetValue(principalName.FullyQualifiedName, out var principal))
        {
            return(principal);
        }

        return(null);
    }
コード例 #24
0
        public void Validate(PrivilegedAttributeCertificate pac, KrbPrincipalName sname)
        {
            if (pac == null)
            {
                throw new ArgumentNullException(nameof(pac));
            }

            pac.ServerSignature.Validate(this.keytab, sname);
        }
コード例 #25
0
ファイル: FakeRealmService.cs プロジェクト: zha0/Kerberos.NET
        public IKerberosPrincipal Refer()
        {
            var fqn            = body.SName.FullyQualifiedName;
            var predictedRealm = fqn.Substring(fqn.IndexOf('.') + 1);

            var krbName = KrbPrincipalName.FromString($"krbtgt/{predictedRealm}");

            return(new FakeKerberosPrincipal(krbName.FullyQualifiedName));
        }
コード例 #26
0
        public void PrincipalName_Equality_ServiceTypeAliasesMatch()
        {
            var a = KrbPrincipalName.FromString("host/aaaa");
            var b = KrbPrincipalName.FromString("bbbb/aaaa");

            KrbPrincipalName.ServiceAliases["bbbb"] = "host";

            Assert.IsTrue(a.Matches(b));
        }
コード例 #27
0
        private ReadOnlyMemory <byte> PreAuthFailed(PreAuthenticationContext context)
        {
            var err = new KrbError
            {
                ErrorCode = KerberosErrorCode.KDC_ERR_PREAUTH_FAILED,
                EText     = context.Failure.Message,
                Realm     = this.RealmService.Name,
                SName     = KrbPrincipalName.FromPrincipal(context.Principal)
            };

            return(err.EncodeApplication());
        }
コード例 #28
0
        private ReadOnlyMemory <byte> PreAuthFailed(KerberosValidationException kex, IKerberosPrincipal principal)
        {
            var err = new KrbError
            {
                ErrorCode = KerberosErrorCode.KDC_ERR_PREAUTH_FAILED,
                EText     = kex.Message,
                Realm     = RealmService.Name,
                SName     = KrbPrincipalName.FromPrincipal(principal)
            };

            return(err.EncodeApplication());
        }
コード例 #29
0
 protected virtual void ValidateClientPrincipalIdentifier(KrbPrincipalName leftName, KrbPrincipalName rightName)
 {
     if (!leftName.Matches(rightName))
     {
         throw new KerberosValidationException(
                   "Ticket CName " +
                   $"({leftName.Type}: {leftName.Type})" +
                   " does not match Authenticator CName " +
                   $"({rightName.Type}: {rightName.Name})"
                   );
     }
 }
コード例 #30
0
        public void ParseFileRoundTrip()
        {
            var tmp   = Path.GetTempFileName();
            var cache = new Krb5TicketCache(tmp);

            try
            {
                Assert.IsNotNull(cache);

                cache.Add(new TicketCacheEntry
                {
                    Key   = "krbtgt/bar.com",
                    Value = new KerberosClientCacheEntry
                    {
                        KdcResponse = new KrbAsRep
                        {
                            CName  = KrbPrincipalName.FromString("*****@*****.**"),
                            CRealm = "bar.com",
                            Ticket = new KrbTicket
                            {
                                Realm         = "bar.com",
                                SName         = KrbPrincipalName.FromString("krbtgt/bar.com"),
                                EncryptedPart = new KrbEncryptedData
                                {
                                    EType  = EncryptionType.AES128_CTS_HMAC_SHA1_96,
                                    Cipher = Array.Empty <byte>()
                                }
                            }
                        },
                        SessionKey = KrbEncryptionKey.Generate(EncryptionType.AES128_CTS_HMAC_SHA1_96),
                        SName      = KrbPrincipalName.FromString("krbtgt/bar.com")
                    }
                });

                using (var secondCache = new Krb5TicketCache(tmp))
                {
                    var entry = secondCache.GetCacheItem <KerberosClientCacheEntry>("krbtgt/bar.com");

                    Assert.IsNotNull(entry.KdcResponse);
                    Assert.AreEqual("bar.com", entry.KdcResponse.CRealm);
                    Assert.AreEqual("*****@*****.**", entry.KdcResponse.CName.FullyQualifiedName);
                }
            }
            finally
            {
                cache.Dispose();

                if (File.Exists(tmp))
                {
                    File.Delete(tmp);
                }
            }
        }