Esempio n. 1
0
    public KerberosExecutor(ITestOutputHelper testOutputHelper, string realm)
    {
        var krb5Config = Krb5Config.Default();

        krb5Config.KdcDefaults.RegisterDefaultPkInitPreAuthHandler = false;

        var logger = new KerberosDelegateLogger(
            (level, categoryName, eventId, scopeState, logState, exception, log) =>
            testOutputHelper.WriteLine($"[{level}] [{categoryName}] {log}")
            );

        _principalService = new FakePrincipalService(realm);

        byte[] krbtgtPassword = new byte[16];

        var krbtgt = new FakeKerberosPrincipal(PrincipalType.Service, "krbtgt", realm, krbtgtPassword);

        _principalService.Add("krbtgt", krbtgt);
        _principalService.Add($"krbtgt/{realm}", krbtgt);

        _options = new ListenerOptions
        {
            Configuration = krb5Config,
            DefaultRealm  = realm,
            RealmLocator  = realm => new FakeRealmService(realm, krb5Config, _principalService),
            Log           = logger,
            IsDebug       = true,
        };

        _kdcListener       = new FakeKdcServer(_options);
        _realm             = realm;
        _servicePrincipals = new List <FakeKerberosPrincipal>();
        _testOutputHelper  = testOutputHelper;
    }
Esempio n. 2
0
        public async Task ValidatorMemoryCacheExpirationExpired()
        {
            var config = Krb5Config.Default();

            config.Defaults.ClockSkew = TimeSpan.Zero;

            using (var logger = new FakeExceptionLoggerFactory())
                using (var replay = new TicketReplayValidator(config, logger))
                {
                    var entry = new TicketCacheEntry
                    {
                        Key     = "blargh",
                        Expires = DateTimeOffset.UtcNow.AddMilliseconds(100)
                    };

                    var added = await replay.Add(entry);

                    Assert.IsTrue(added);

                    await Task.Delay(TimeSpan.FromSeconds(1));

                    added = await replay.Add(entry);

                    Assert.IsTrue(added);

                    Assert.IsTrue(logger.Logs.Count() > 1);
                }
        }
Esempio n. 3
0
        public void DefaultSerializesAsEmpty()
        {
            var conf = Krb5Config.Default();

            var ds = conf.Serialize();

            Assert.IsTrue(string.IsNullOrWhiteSpace(ds));
        }
Esempio n. 4
0
        public static KrbAsReq CreateAsReq(KerberosCredential credential, AuthenticationOptions options)
        {
            if (credential == null)
            {
                throw new ArgumentNullException(nameof(credential));
            }

            var config = credential.Configuration ?? Krb5Config.Default();

            var kdcOptions = (KdcOptions)(options & ~AuthenticationOptions.AllAuthentication);

            var pacRequest = new KrbPaPacRequest
            {
                IncludePac = options.HasFlag(AuthenticationOptions.IncludePacRequest)
            };

            var padata = new List <KrbPaData>()
            {
                new KrbPaData
                {
                    Type  = PaDataType.PA_PAC_REQUEST,
                    Value = pacRequest.Encode()
                }
            };

            var asreq = new KrbAsReq()
            {
                Body = new KrbKdcReqBody
                {
                    Addresses  = IncludeAddresses(config),
                    CName      = ExtractCName(credential),
                    EType      = GetPreferredETypes(config.Defaults.DefaultTicketEncTypes, config.Defaults.AllowWeakCrypto).ToArray(),
                    KdcOptions = kdcOptions,
                    Nonce      = GetNonce(),
                    RTime      = CalculateRenewTime(kdcOptions, config),
                    Realm      = credential.Domain,
                    SName      = new KrbPrincipalName
                    {
                        Type = PrincipalNameType.NT_SRV_INST,
                        Name = new[] { "krbtgt", credential.Domain }
                    },
                    Till = CalculateExpirationTime(config)
                },
                PaData = padata.ToArray()
            };

            if (options.HasFlag(AuthenticationOptions.PreAuthenticate))
            {
                credential.TransformKdcReq(asreq);
            }

            return(asreq);
        }
Esempio n. 5
0
        private static async Task ClientResolverProcessesEndpoint(string server)
        {
            var client = new ClientDomainService(null)
            {
                Configuration = Krb5Config.Default()
            };

            client.Configuration.Realms["TEST.COM"].Kdc.Add(server);

            client.Configuration.Defaults.DefaultRealm = "TEST.COM";
            client.Configuration.DomainRealm.Add("TEST.COM", "TEST.COM");
            client.Configuration.Defaults.DnsLookupKdc = false;

            var result = await client.LocateKdc("TEST.COM", "_kerberos._http");

            Assert.AreEqual(1, result.Count());
            Assert.AreEqual(server, result.First().Address);
        }
Esempio n. 6
0
        private static KrbAsRep RequestTgt(out KrbEncryptionKey sessionKey)
        {
            var cred = new KerberosPasswordCredential(Upn, "P@ssw0rd!")
            {
                // cheating by skipping the initial leg of requesting PA-type

                Salts = new[]
                {
                    new KeyValuePair <EncryptionType, string>(
                        EncryptionType.AES256_CTS_HMAC_SHA1_96,
                        "*****@*****.**"
                        )
                },
                Configuration = Krb5Config.Default()
            };

            var asReq = KrbAsReq.CreateAsReq(
                cred,
                AuthenticationOptions.AllAuthentication
                );

            var handler = new KdcAsReqMessageHandler(asReq.EncodeApplication(), new KdcServerOptions
            {
                DefaultRealm = Realm,
                IsDebug      = true,
                RealmLocator = realm => new FakeRealmService(realm)
            });

            handler.PreAuthHandlers[PaDataType.PA_ENC_TIMESTAMP] = service => new PaDataTimestampHandler(service);

            var results = handler.Execute();

            var decoded = KrbAsRep.DecodeApplication(results);

            var decrypted = cred.DecryptKdcRep(
                decoded,
                KeyUsage.EncAsRepPart,
                d => KrbEncAsRepPart.DecodeApplication(d)
                );

            sessionKey = decrypted.Key;

            return(decoded);
        }
        public async Task KinitExecutes()
        {
            var port = NextPort();

            using (var tmpCacheFile = new TemporaryFile())
                using (var tmpConfigFile = new TemporaryFile())
                {
                    var config = Krb5Config.Default();

                    File.WriteAllText(tmpConfigFile.File, config.Serialize());

                    using (var listener = StartTcpListener(port))
                    {
                        _ = listener.Start();

                        var reader = new CommandLineAutoReader();

                        var io = new InputControl
                        {
                            Clear      = () => { },
                            HookCtrlC  = hook => { },
                            ResetColor = () => { },
                            SetColor   = c => { },
                            Reader     = reader,
                            Writer     = new StringWriter(),
                            ReadKey    = () => ReadKey(reader)
                        };

                        var command = CreateCommand($"127.0.0.1:{port}", AdminAtCorpUserName, tmpCacheFile.File, tmpConfigFile.File, io);

                        reader.QueueNext(FakeAdminAtCorpPassword + "\n");

                        await command.Execute();

                        var output = io.Writer.ToString();

                        Assert.IsTrue(output.Contains("Ticket Count: 1"));
                        Assert.IsTrue(output.Contains("client : administrator", StringComparison.OrdinalIgnoreCase), output);
                    }
                }
        }
Esempio n. 8
0
        public void Version3DefaultsCorrectly()
        {
            using (var tmp = new TemporaryFile())
            {
                var config = Krb5Config.Default();

                config.Defaults.CCacheType        = 3;
                config.Defaults.DefaultCCacheName = tmp.File;

                using (var client = new KerberosClient(config)
                {
                    CacheInMemory = false
                })
                {
                    var cache = client.Cache as Krb5TicketCache;

                    Assert.IsNotNull(cache);
                    Assert.AreEqual(3, cache.Version);
                }
            }
        }
Esempio n. 9
0
        public async Task LsaLogonUserImportUseCache()
        {
            var cred   = CreateKrbCredential();
            var config = Krb5Config.Default();

            using (var interop = LsaInterop.Connect())
            {
                Assert.IsNotNull(interop);

                interop.LogonUser();

                interop.ImportCredential(cred);

                using (var client = new KerberosClient(config)
                {
                    Cache = new LsaCredentialCache(config, interop)
                })
                {
                    var ticket = await client.GetServiceTicket(RequestedSpn);

                    Assert.IsNotNull(ticket);
                }
            }
        }
Esempio n. 10
0
 protected Krb5TicketCache(ILoggerFactory logger)
     : this(Krb5Config.Default(), logger)
 {
 }
Esempio n. 11
0
        public static KrbTgsReq CreateTgsReq(
            RequestServiceTicket rst,
            KrbEncryptionKey tgtSessionKey,
            KrbKdcRep kdcRep,
            out KrbEncryptionKey sessionKey
            )
        {
            if (kdcRep == null)
            {
                throw new ArgumentNullException(nameof(kdcRep));
            }

            if (tgtSessionKey == null)
            {
                throw new ArgumentNullException(nameof(tgtSessionKey));
            }

            var sname = rst.ServicePrincipalName.Split('/', '@');
            var tgt   = kdcRep.Ticket;

            var additionalTickets = new List <KrbTicket>();

            if (rst.KdcOptions.HasFlag(KdcOptions.EncTktInSkey) && rst.UserToUserTicket != null)
            {
                additionalTickets.Add(rst.UserToUserTicket);
            }

            if (!string.IsNullOrWhiteSpace(rst.S4uTarget))
            {
                rst.KdcOptions |= KdcOptions.Forwardable;
            }

            if (rst.S4uTicket != null)
            {
                rst.KdcOptions |= KdcOptions.ConstrainedDelegation;

                additionalTickets.Add(rst.S4uTicket);
            }

            var config = rst.Configuration ?? Krb5Config.Default();

            var body = new KrbKdcReqBody
            {
                EType      = KerberosConstants.GetPreferredETypes(config.Defaults.DefaultTicketEncTypes).ToArray(),
                KdcOptions = rst.KdcOptions,
                Nonce      = KerberosConstants.GetNonce(),
                Realm      = rst.Realm,
                SName      = new KrbPrincipalName()
                {
                    Type = PrincipalNameType.NT_SRV_INST,
                    Name = sname
                },
                Till  = KerberosConstants.EndOfTime,
                CName = rst.CNameHint
            };

            if (additionalTickets.Count > 0)
            {
                body.AdditionalTickets = additionalTickets.ToArray();
            }

            var bodyChecksum = KrbChecksum.Create(
                body.Encode(),
                tgtSessionKey.AsKey(),
                KeyUsage.PaTgsReqChecksum
                );

            var tgtApReq = CreateApReq(kdcRep, tgtSessionKey, bodyChecksum, out sessionKey);

            var pacOptions = new KrbPaPacOptions
            {
                Flags = PacOptions.ResourceBasedConstrainedDelegation | PacOptions.Claims | PacOptions.BranchAware
            }.Encode();

            var paData = new List <KrbPaData>()
            {
                new KrbPaData
                {
                    Type  = PaDataType.PA_TGS_REQ,
                    Value = tgtApReq.EncodeApplication()
                },
                new KrbPaData
                {
                    Type  = PaDataType.PA_PAC_OPTIONS,
                    Value = pacOptions
                }
            };

            if (!string.IsNullOrWhiteSpace(rst.S4uTarget))
            {
                paData.Add(new KrbPaData
                {
                    Type  = PaDataType.PA_FOR_USER,
                    Value = EncodeS4URequest(rst.S4uTarget, tgt.Realm, tgtSessionKey)
                });
            }

            var tgs = new KrbTgsReq
            {
                PaData = paData.ToArray(),
                Body   = body
            };

            return(tgs);
        }
Esempio n. 12
0
 public TicketReplayValidator(ILoggerFactory logger)
     : this(Krb5Config.Default(), logger)
 {
 }