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; }
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); } }
public void DefaultSerializesAsEmpty() { var conf = Krb5Config.Default(); var ds = conf.Serialize(); Assert.IsTrue(string.IsNullOrWhiteSpace(ds)); }
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); }
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); }
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); } } }
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); } } }
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); } } }
protected Krb5TicketCache(ILoggerFactory logger) : this(Krb5Config.Default(), logger) { }
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); }
public TicketReplayValidator(ILoggerFactory logger) : this(Krb5Config.Default(), logger) { }