private static async Task RequestAndValidateTickets( string user, string password, string overrideKdc, string s4u = null, bool encodeNego = false, bool caching = false, bool includePac = true ) { var kerbCred = new KerberosPasswordCredential(user, password); using (var client = new KerberosClient(overrideKdc) { CacheServiceTickets = caching }) { if (!includePac) { client.AuthenticationOptions &= ~AuthenticationOptions.IncludePacRequest; } await client.Authenticate(kerbCred); var spn = FakeAppServiceSpn; var ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = spn, ApOptions = ApOptions.MutualRequired } ); await ValidateTicket(ticket, includePac : includePac); await client.RenewTicket(); ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = FakeAppServiceSpn, ApOptions = ApOptions.MutualRequired } ); await ValidateTicket(ticket, encodeNego, includePac : includePac); ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = FakeAppServiceSpn, ApOptions = ApOptions.MutualRequired, S4uTarget = s4u } ); await ValidateTicket(ticket, includePac : includePac); } }
private async Task GetServiceTicket(KerberosClient client) { try { await client.GetServiceTicket(this.ServicePrincipalName); } catch (AggregateException aex) { ICollection <Exception> exceptions = aex.InnerExceptions?.Where(e => e != null)?.ToList(); if (exceptions == null) { exceptions = new List <Exception>(); if (aex.InnerException != null) { exceptions.Add(aex.InnerException); } } foreach (var ex in exceptions.Where(e => e != null)) { if (ex is KerberosProtocolException kex && kex?.Error?.ErrorCode == KerberosErrorCode.KRB_AP_ERR_TKT_EXPIRED) { await PurgeTickets(); await client.GetServiceTicket(this.ServicePrincipalName); break; } this.IO.Writer.WriteLine(ex?.Message ?? SR.Resource("Unknown Error")); } } }
private static async Task RequestAndValidateTickets( string user, string password, string overrideKdc, string s4u = null, bool encodeNego = false, bool caching = false ) { var kerbCred = new KerberosPasswordCredential(user, password); KerberosClient client = new KerberosClient(overrideKdc) { CacheServiceTickets = caching }; await client.Authenticate(kerbCred); var spn = "host/appservice.corp.identityintervention.com"; var ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = spn, ApOptions = ApOptions.MutualRequired } ); await ValidateTicket(ticket); await client.RenewTicket(); ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = "host/appservice.corp.identityintervention.com", ApOptions = ApOptions.MutualRequired } ); await ValidateTicket(ticket, encodeNego); ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = "host/appservice.corp.identityintervention.com", ApOptions = ApOptions.MutualRequired, S4uTarget = s4u } ); await ValidateTicket(ticket); }
private static async Task RequestTickets(string user, string password, string overrideKdc, string s4u, string spn) { var kerbCred = new KerberosPasswordCredential(user, password); using (KerberosClient client = new KerberosClient(overrideKdc)) { await client.Authenticate(kerbCred); spn = spn ?? "host/appservice.corp.identityintervention.com"; KrbTicket s4uTicket = null; if (!string.IsNullOrWhiteSpace(s4u)) { var s4uSelf = await client.GetServiceTicket( kerbCred.UserName, ApOptions.MutualRequired, s4u : s4u ); s4uTicket = s4uSelf.Ticket; } var ticket = await client.GetServiceTicket( spn, ApOptions.MutualRequired, s4uTicket : s4uTicket ); var encoded = ticket.EncodeApplication().ToArray(); var authenticator = new KerberosAuthenticator( new KeyTable( new KerberosKey( "P@ssw0rd!", principalName: new PrincipalName( PrincipalNameType.NT_PRINCIPAL, "CORP.IDENTITYINTERVENTION.com", new[] { spn } ), saltType: SaltType.ActiveDirectoryUser ) ) ); var validated = (KerberosIdentity)await authenticator.Authenticate(encoded); DumpClaims(validated); } }
public async Task ClientRequestsServiceTicketBeforeAuthentication() { using (var client = new KerberosClient()) { await client.GetServiceTicket("host/test.com"); } }
public async Task <ApplicationSessionContext> GetServiceTicket(RequestServiceTicket rst, CancellationToken cancellation) { rst.S4uTarget = null; rst.S4uTicket = this.krbApReq.EncryptedTicket; rst.KdcOptions |= KdcOptions.CNameInAdditionalTicket; bool retried = false; while (true) { try { return(await client.GetServiceTicket(rst, cancellation)); } catch (InvalidOperationException) { if (retried) { break; } await client.Authenticate(this.credential); retried = true; } } return(null); }
private async Task S4u2Self(KerberosClient client) { var myTgtEntry = client.Cache.GetCacheItem <KerberosClientCacheEntry>($"krbtgt/{client.DefaultDomain}"); var myTgt = myTgtEntry.KdcResponse?.Ticket; if (myTgt == null) { this.IO.Writer.WriteLine(SR.Resource("CommandLine_WhoAmI_NoTgt")); return; } var result = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = client.UserPrincipalName, UserToUserTicket = myTgt, CacheTicket = false, } ); var authenticator = new KerberosAuthenticator(new KerberosValidator(myTgtEntry.SessionKey.AsKey())); var identity = await authenticator.Authenticate(result.ApReq.EncodeApplication()); this.DescribeTicket(identity as KerberosIdentity); }
private static async Task RequestTickets(string user, string password, string overrideKdc) { var kerbCred = new KerberosPasswordCredential(user, password); KerberosClient client = new KerberosClient(overrideKdc); await client.Authenticate(kerbCred); var ticket = await client.GetServiceTicket( "host/appservice.corp.identityintervention.com", ApOptions.MutualRequired ); var encoded = ticket.EncodeApplication().ToArray(); var authenticator = new KerberosAuthenticator( new KeyTable( new KerberosKey( "P@ssw0rd!", principalName: new PrincipalName( PrincipalNameType.NT_PRINCIPAL, "CORP.IDENTITYINTERVENTION.com", new[] { "host/appservice.corp.identityintervention.com" } ), saltType: SaltType.ActiveDirectoryUser ) ) ); var validated = (KerberosIdentity)await authenticator.Authenticate(encoded); DumpClaims(validated); }
public async Task ClientCannotGetExpiredCachedItem() { using (var client = new KerberosClient() { Cache = new Krb5TicketCache(FilePath) }) { await client.GetServiceTicket(new RequestServiceTicket { ServicePrincipalName = "krbtgt/IPA.IDENTITYINTERVENTION.COM" }); } }
public async Task U2U() { var port = new Random().Next(20000, 40000); var options = new ListenerOptions { ListeningOn = new IPEndPoint(IPAddress.Loopback, port), DefaultRealm = "corp2.identityintervention.com".ToUpper(), IsDebug = true, RealmLocator = realm => LocateRealm(realm), ReceiveTimeout = TimeSpan.FromHours(1) }; KdcServiceListener listener = new KdcServiceListener(options); _ = listener.Start(); var kerbClientCred = new KerberosPasswordCredential("*****@*****.**", "P@ssw0rd!"); var client = new KerberosClient($"127.0.0.1:{port}"); await client.Authenticate(kerbClientCred); var kerbServerCred = new KerberosPasswordCredential("*****@*****.**", "P@ssw0rd!"); var server = new KerberosClient($"127.0.0.1:{port}"); await server.Authenticate(kerbClientCred); var serverEntry = await server.Cache.Get <KerberosClientCacheEntry>($"krbtgt/{server.DefaultDomain}"); var serverTgt = serverEntry.Ticket.Ticket; var apReq = await client.GetServiceTicket("host/u2u", ApOptions.MutualRequired | ApOptions.UseSessionKey, u2uServerTicket : serverTgt); Assert.IsNotNull(apReq); var decrypted = new DecryptedKrbApReq(apReq); Assert.IsNull(decrypted.Ticket); decrypted.Decrypt(serverEntry.SessionKey.AsKey()); decrypted.Validate(ValidationActions.All); Assert.IsNotNull(decrypted.Ticket); Assert.AreEqual("host/u2u/CORP.IDENTITYINTERVENTION.COM", decrypted.SName.FullyQualifiedName); listener.Stop(); }
private async Task S4u2Self(KerberosClient client) { if (client.Cache is LsaCredentialCache) { this.WriteLineError("The whoami command isn't supported with the LSA Cache"); return; } var myTgtEntry = client.Cache.GetCacheItem <KerberosClientCacheEntry>($"krbtgt/{client.DefaultDomain}"); var myTgt = myTgtEntry.KdcResponse?.Ticket; if (myTgt == null) { this.WriteHeader(SR.Resource("CommandLine_WhoAmI_NoTgt")); return; } try { var result = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = client.UserPrincipalName, UserToUserTicket = myTgt, CacheTicket = false, S4uTarget = client.UserPrincipalName } ); var authenticator = new KerberosAuthenticator(new KerberosValidator(myTgtEntry.SessionKey.AsKey())); var identity = await authenticator.Authenticate(result.ApReq.EncodeApplication()); this.DescribeTicket(identity as KerberosIdentity); } catch (KerberosProtocolException kex) { this.WriteLine(); this.WriteLine(1, "{ErrorCode}: {ErrorText}", kex.Error.ErrorCode, kex.Error.ETextWithoutCode()); if (kex.Error.ErrorCode == KerberosErrorCode.KRB_AP_ERR_TKT_EXPIRED) { this.WriteLine(); this.WriteLine(1, SR.Resource("CommandLine_WhoAmI_NoTgt")); } } }
public async Task KrbCredImportsAndGets() { var krbCred = CreateKrbCredential(); using (var client = new KerberosClient()) { client.ImportCredential(krbCred); var serviceTicket = await client.GetServiceTicket("host/test.com"); Assert.IsNotNull(serviceTicket); Assert.IsNotNull(serviceTicket.Authenticator); Assert.IsNotNull(serviceTicket.Ticket); } }
public async Task ClientGetsCachedItem() { using (var client = new KerberosClient() { Cache = new Krb5TicketCache(FilePath) }) { var apReq = await client.GetServiceTicket("krbtgt/IPA.IDENTITYINTERVENTION.COM"); Assert.IsNotNull(apReq); Assert.IsNotNull(apReq.Authenticator); Assert.IsNotNull(apReq.Ticket); Assert.AreEqual("*****@*****.**", apReq.Ticket.SName.FullyQualifiedName); } }
private static async Task RequestAndValidateTickets(string user, string password, string overrideKdc) { var kerbCred = new KerberosPasswordCredential(user, password); KerberosClient client = new KerberosClient(overrideKdc); await client.Authenticate(kerbCred); var ticket = await client.GetServiceTicket( "host/appservice.corp.identityintervention.com", ApOptions.MutualRequired ); await ValidateTicket(ticket); await client.RenewTicket(); ticket = await client.GetServiceTicket( "host/appservice.corp.identityintervention.com", ApOptions.MutualRequired ); await ValidateTicket(ticket); }
public async Task RequestServiceTicket() { var kerbCred = new KerberosPasswordCredential(user, password); var client = new KerberosClient($"{overrideKdc}:{port}"); await client.Authenticate(kerbCred); for (var i = 0; i < AuthenticationAttempts; i++) { await client.GetServiceTicket( "host/appservice.corp.identityintervention.com", ApOptions.MutualRequired ); } }
static async Task <int> Main(string[] args) { var getTicketCommand = new Command("get-ticket") { new Option <string>( "--kdc", description: "Key Destribution Center (KDC). Try AD domain name if you don't know this value - will usually work") { Required = true }, new Option <string>( "--user", description: "Kerberos client principal. Ex. [email protected]") { Required = true }, new Option <string>( "--password", "Password for the client principal") { Required = true }, new Option <string>( "--spn", "Destination service account or SPN. Ex http/myservice.domain.com") { Required = true } }; getTicketCommand.Handler = CommandHandler.Create <string, string, string, string>(async(kdc, user, password, spn) => { var client = new KerberosClient(kdc); var kerbCred = new KerberosPasswordCredential(user, password); await client.Authenticate(kerbCred); var ticket = await client.GetServiceTicket(spn); var ticket64 = Convert.ToBase64String(ticket.EncodeApplication().ToArray()); Console.WriteLine(ticket64); }); var rootCommand = new RootCommand(); rootCommand.AddCommand(getTicketCommand); return(await rootCommand.InvokeAsync(args)); }
public async Task RequestServiceTicket(string algo) { var kerbCred = new KerberosPasswordCredential(algo + this.user, this.password); using (var client = new KerberosClient()) { client.PinKdc(kerbCred.Domain, $"{this.overrideKdc}:{this.port}"); await client.Authenticate(kerbCred); for (var i = 0; i < this.AuthenticationAttempts; i++) { await client.GetServiceTicket( "host/appservice.corp.identityintervention.com", ApOptions.MutualRequired ); } } }
private async Task DumpServiceTicket(KerberosClient client) { var rep = await client.GetServiceTicket(this.DumpServicePrincipalName); string apreq; if (this.DumpAsNegotiate) { apreq = Convert.ToBase64String(rep.EncodeGssApi().ToArray()); } else { apreq = Convert.ToBase64String(rep.EncodeApplication().ToArray()); } var command = new KerberosDumpCommand(CommandLineParameters.Parse($"kdecode --ticket \"{apreq}\"")); await command.Execute(); }
public async Task ClientGetsCachedItem() { using (var client = new KerberosClient() { Cache = new Krb5TicketCache(FilePath) }) { var rep = await client.GetServiceTicket(new RequestServiceTicket { ServicePrincipalName = "krbtgt/IPA.IDENTITYINTERVENTION.COM", CanRetrieveExpiredTickets = true }); var apReq = rep.ApReq; Assert.IsNotNull(apReq); Assert.IsNotNull(apReq.Authenticator); Assert.IsNotNull(apReq.Ticket); Assert.AreEqual("*****@*****.**", apReq.Ticket.SName.FullyQualifiedName); } }
public async Task E2E_U2U() { var port = NextPort(); using (var listener = StartListener(port)) { var kerbClientCred = new KerberosPasswordCredential(AdminAtCorpUserName, FakeAdminAtCorpPassword); var kerbServerCred = new KerberosPasswordCredential("*****@*****.**", FakeAdminAtCorpPassword); using (var client = new KerberosClient($"127.0.0.1:{port}")) using (var server = new KerberosClient($"127.0.0.1:{port}")) { await client.Authenticate(kerbClientCred); await server.Authenticate(kerbClientCred); var serverEntry = await server.Cache.Get <KerberosClientCacheEntry>($"krbtgt/{server.DefaultDomain}"); var serverTgt = serverEntry.Ticket.Ticket; var apReq = await client.GetServiceTicket("host/u2u", ApOptions.MutualRequired | ApOptions.UseSessionKey, u2uServerTicket : serverTgt); Assert.IsNotNull(apReq); var decrypted = new DecryptedKrbApReq(apReq); Assert.IsNull(decrypted.Ticket); decrypted.Decrypt(serverEntry.SessionKey.AsKey()); decrypted.Validate(ValidationActions.All); Assert.IsNotNull(decrypted.Ticket); Assert.AreEqual("host/[email protected]", decrypted.SName.FullyQualifiedName); } listener.Stop(); } }
public async Task KrbCredImportsAndPassesAuthenticatorValidation() { var krbCred = CreateKrbCredential(); using (var client = new KerberosClient()) { client.ImportCredential(krbCred); var serviceTicket = await client.GetServiceTicket("host/test.com"); Assert.IsNotNull(serviceTicket); var encodedTicket = "Negotiate " + Convert.ToBase64String(serviceTicket.EncodeGssApi().ToArray()); var authenticator = new KerberosAuthenticator(new KeyTable(new KerberosKey(new byte[16], etype: EncryptionType.AES128_CTS_HMAC_SHA1_96))); var result = await authenticator.Authenticate(encodedTicket); Assert.IsNotNull(result); Assert.AreEqual("*****@*****.**", result.Name); } }
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); } } }
internal static async Task <List <Exception> > MultithreadedRequests( int threads, int requests, bool cacheTickets, bool encodeNego, bool includePac, string kdc, X509Certificate2 cert, KdcListener listener ) { var exceptions = new List <Exception>(); KerberosCredential kerbCred; if (cert != null) { kerbCred = new TrustedAsymmetricCredential(cert, TestAtCorpUserName); } else { kerbCred = new KerberosPasswordCredential(AdminAtCorpUserName, FakeAdminAtCorpPassword); } KerberosClient client = CreateClient(listener, kdc); using (client) { client.CacheServiceTickets = cacheTickets; if (!includePac) { client.AuthenticationOptions &= ~AuthenticationOptions.IncludePacRequest; } await client.Authenticate(kerbCred); Task.WaitAll(Enumerable.Range(0, threads).Select(taskNum => Task.Run(async() => { for (var i = 0; i < requests; i++) { try { if (i % 2 == 0) { await client.Authenticate(kerbCred); } var ticket = await client.GetServiceTicket(new RequestServiceTicket { ServicePrincipalName = FakeAppServiceSpn, ApOptions = ApOptions.MutualRequired }); Assert.IsNotNull(ticket.ApReq); await ValidateTicket(ticket, encodeNego: encodeNego, includePac: includePac); } catch (Exception ex) { exceptions.Add(ex); } } })).ToArray()); } return(exceptions); }
private static async Task RequestAndValidateTickets( string user, string password = null, string overrideKdc = null, KeyTable keytab = null, string s4u = null, bool encodeNego = false, bool caching = false, bool includePac = true, X509Certificate2 cert = null ) { KerberosCredential kerbCred; if (cert != null) { kerbCred = new TrustedAsymmetricCredential(cert, user); } else if (keytab != null) { kerbCred = new KeytabCredential(user, keytab); } else { kerbCred = new KerberosPasswordCredential(user, password); } using (var client = new KerberosClient(overrideKdc) { CacheServiceTickets = caching }) { if (!includePac) { client.AuthenticationOptions &= ~AuthenticationOptions.IncludePacRequest; } await client.Authenticate(kerbCred); var spn = FakeAppServiceSpn; var ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = spn, ApOptions = ApOptions.MutualRequired } ); await ValidateTicket(ticket, includePac : includePac); await client.RenewTicket(); ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = FakeAppServiceSpn, ApOptions = ApOptions.MutualRequired } ); await ValidateTicket(ticket, encodeNego, includePac : includePac); ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = FakeAppServiceSpn, ApOptions = ApOptions.MutualRequired, S4uTarget = s4u } ); await ValidateTicket(ticket, includePac : includePac); } }
static async Task Main(string[] args) { loggerFactory = LoggerFactory.Create(builder => { builder .AddFilter("Microsoft", LogLevel.Warning) .AddFilter("System", LogLevel.Warning) .AddFilter("RestNegotiateClient.Program", LogLevel.Debug) .AddFilter("Kerberos.Net", LogLevel.Trace) .AddConsole(delegate(ConsoleLoggerOptions d) { }); }); logger = loggerFactory.CreateLogger <Program>(); /*CommandLineArguments parsedArgs = new CommandLineArguments(args); * String url = (String) parsedArgs.GetValueOrDefault(""); * if (!parsedArgs.ContainsKey("keytab")) { * await Console.Error.WriteLineAsync("Syntax: RestNegotiateClient --keytab <keytab> --principal <principal> <url>"); * return; * } * String keytab = (String) parsedArgs.GetValueOrDefault("keytab", "krb5.keytab"); * String principal = (String) parsedArgs.GetValueOrDefault("principal", "cud/[email protected]");*/ String keytab = args[0]; String principal = args[1]; String url = args[2]; String outfile = args[3]; Console.Error.WriteLine("keytab={0}, principal={1}, url={2}", keytab, principal, url, outfile); // Check URL is syntactically valid Uri uri = null; if (!Uri.TryCreate(url, UriKind.Absolute, out uri)) { throw new ArgumentException(String.Format("Invalid URL: {0}", url)); } var client = new KerberosClient("kdc0.ox.ac.uk", loggerFactory); client.AuthenticationOptions ^= AuthenticationOptions.Canonicalize; var udp = client.Transports.OfType <UdpKerberosTransport>().FirstOrDefault(); udp.Enabled = true; var keyTable = new KeyTable(File.ReadAllBytes(keytab)); var kerbCred = new KeytabCredential(principal, keyTable, "OX.AC.UK"); logger.LogDebug("User name: {0}", kerbCred.UserName); await client.Authenticate(kerbCred); logger.LogDebug("Authenticated!"); // Now get a service ticket for the HTTP server and perform the request String serverPrincipal = String.Format("HTTP/{0}", uri.DnsSafeHost); var ticket = await client.GetServiceTicket(serverPrincipal); String spnego = Convert.ToBase64String(ticket.EncodeGssApi().ToArray()); var httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Negotiate", spnego); using (var outStream = File.Open(outfile, FileMode.Create)) { var httpStream = await httpClient.GetStreamAsync(uri); await httpStream.CopyToAsync(outStream); } }
static async Task TestKerberosAuthAndClaims(string[] args) { var cred = new KerberosPasswordCredential("test-user", "p@$$W0RD", "domain.local"); var spn = "nats/localhost.domain.local"; using var client = new KerberosClient(); await client.Authenticate(cred); var sess = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = spn, ApOptions = ApOptions.MutualRequired, //S4uTicket = stik.Ticket, //CNameHint = null, //cnameHint } ); var stik = sess.ApReq; // var stik = await client.GetServiceTicket(spn); var stok = stik.EncodeApplication().ToArray(); var kkey = new KerberosKey("p@$$W0RD", principalName: new PrincipalName( PrincipalNameType.NT_PRINCIPAL, stik.Ticket.Realm, new[] { spn } ), saltType: SaltType.ActiveDirectoryUser ); // var kkey = new KerberosKey("p@$$W0RD", // salt: "SampleSalt", // etype: stik.Ticket.EncryptedPart.EType, // saltType: SaltType.ActiveDirectoryService // ); var kval = new KerberosValidator(kkey); var auth = new KerberosAuthenticator(kval); var claims = await auth.Authenticate(stok); //var claims = await auth.Authenticate(session.ApReq.Ticket.EncodeApplication().ToArray()); Console.WriteLine($@" AuthType............: {claims.AuthenticationType} BootstrapContext....: {claims.BootstrapContext} IsAuthenticated.....: {claims.IsAuthenticated} Label...............: {claims.Label} Name................: {claims.Name} NameClaimType.......: {claims.NameClaimType} RoleClaimType.......: {claims.RoleClaimType} RoleClaimType.......: {claims.RoleClaimType} Claims..............: {string.Join("", claims.Claims.Select(c => " * " + c + "\r\n"))} Actor.AuthType............: {claims.Actor?.AuthenticationType} Actor.BootstrapContext....: {claims.Actor?.BootstrapContext} Actor.IsAuthenticated.....: {claims.Actor?.IsAuthenticated} Actor.Label...............: {claims.Actor?.Label} Actor.Name................: {claims.Actor?.Name} Actor.NameClaimType.......: {claims.Actor?.NameClaimType} Actor.RoleClaimType.......: {claims.Actor?.RoleClaimType} "); }
private static async Task MultithreadedRequests( int port, int threads, int requests, bool cacheTickets, bool encodeNego, bool includePac, string kdc ) { using (var listener = StartListener(port)) { var exceptions = new List <Exception>(); var kerbCred = new KerberosPasswordCredential(AdminAtCorpUserName, FakeAdminAtCorpPassword); using (KerberosClient client = new KerberosClient(kdc)) { client.CacheServiceTickets = cacheTickets; if (!includePac) { client.AuthenticationOptions &= ~AuthenticationOptions.IncludePacRequest; } await client.Authenticate(kerbCred); Task.WaitAll(Enumerable.Range(0, threads).Select(taskNum => Task.Run(async() => { for (var i = 0; i < requests; i++) { try { if (i % 2 == 0) { await client.Authenticate(kerbCred); } var ticket = await client.GetServiceTicket(new RequestServiceTicket { ServicePrincipalName = FakeAppServiceSpn, ApOptions = ApOptions.MutualRequired }); Assert.IsNotNull(ticket.ApReq); await ValidateTicket(ticket, encodeNego: encodeNego, includePac: includePac); } catch (Exception ex) { exceptions.Add(ex); } } })).ToArray()); } listener.Stop(); if (exceptions.Count > 0) { throw new AggregateException($"Failed {exceptions.Count}", exceptions.GroupBy(e => e.GetType()).Select(e => e.First())); } } }
private static async Task RequestTickets( X509Certificate2 cert, string user, string password, string overrideKdc, string s4u, string spn, bool retryDH, bool includeCNameHint, string servicePassword, string serviceSalt, bool cacheToFile ) { KerberosCredential kerbCred; if (cert == null) { kerbCred = new KerberosPasswordCredential(user, password); } else { var chain = new X509Chain(); chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck; chain.Build(cert); var kdcCerts = new List <X509Certificate2>(); for (var i = 0; i < chain.ChainElements.Count; i++) { var c = chain.ChainElements[i].Certificate; if (c.Thumbprint != cert.Thumbprint) { kdcCerts.Add(c); } } if (retryDH) { kerbCred = new RandomDHAsymmetricCredential(cert, user); } else { kerbCred = new TrustedKdcAsymmetricCredential(cert, user); } } var factory = LoggerFactory.Create(builder => { builder.AddConsole(opt => opt.IncludeScopes = true); builder.AddFilter <ConsoleLoggerProvider>(level => level >= LogLevel.Trace); }); var client = new KerberosClient(logger: factory); if (Uri.TryCreate(overrideKdc, UriKind.Absolute, out Uri kdcProxy)) { client.Configuration.Realms[kdcProxy.DnsSafeHost].Kdc.Add(kdcProxy.OriginalString); client.Configuration.Realms[kerbCred.Domain].Kdc.Add(kdcProxy.OriginalString); client.Configuration.Defaults.DnsLookupKdc = false; } else if (!string.IsNullOrWhiteSpace(overrideKdc)) { client.Configuration.Defaults.DnsLookupKdc = false; client.PinKdc(kerbCred.Domain, overrideKdc); } if (cacheToFile) { client.Configuration.Defaults.DefaultCCacheName = "krb5cc"; } KrbPrincipalName cnameHint = null; if (includeCNameHint) { cnameHint = KrbPrincipalName.FromString(kerbCred.UserName, PrincipalNameType.NT_PRINCIPAL, kerbCred.Domain); } client.RenewTickets = true; using (client) using (kerbCred as IDisposable) { await client.Authenticate(kerbCred); spn = spn ?? "host/appservice.corp.identityintervention.com"; KrbTicket s4uTicket = null; if (!string.IsNullOrWhiteSpace(s4u)) { var s4uSelf = await client.GetServiceTicket( kerbCred.UserName, ApOptions.MutualRequired, s4u : s4u ); s4uTicket = s4uSelf.Ticket; } var session = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = spn, ApOptions = ApOptions.MutualRequired, S4uTicket = s4uTicket, CNameHint = cnameHint } ); DumpTicket(session.ApReq); ResetColor(); if (!retryDH) { try { await TryValidate(spn, session.ApReq, servicePassword, serviceSalt, factory); } catch (Exception ex) { W(ex.Message, ConsoleColor.Yellow); ResetColor(); } } } }
internal static async Task RequestAndValidateTickets( KdcListener listener, string user, string password = null, string overrideKdc = null, KeyTable keytab = null, string s4u = null, bool encodeNego = false, bool caching = false, bool includePac = true, X509Certificate2 cert = null, string spn = FakeAppServiceSpn, KeyAgreementAlgorithm keyAgreement = KeyAgreementAlgorithm.DiffieHellmanModp14 ) { KerberosCredential kerbCred; if (cert != null) { kerbCred = new TrustedAsymmetricCredential(cert, user) { KeyAgreement = keyAgreement }; } else if (keytab != null) { kerbCred = new KeytabCredential(user, keytab); } else { kerbCred = new KerberosPasswordCredential(user, password); } KerberosClient client = CreateClient(listener, overrideKdc, caching: caching); using (client) { if (!includePac) { client.AuthenticationOptions &= ~AuthenticationOptions.IncludePacRequest; } await client.Authenticate(kerbCred); var ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = spn, ApOptions = ApOptions.MutualRequired } ); await ValidateTicket(ticket, includePac : includePac, spn : spn); await client.RenewTicket(); ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = spn, ApOptions = ApOptions.MutualRequired } ); await ValidateTicket(ticket, encodeNego, includePac : includePac, spn : spn); ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = spn, ApOptions = ApOptions.MutualRequired, S4uTarget = s4u } ); await ValidateTicket(ticket, includePac : includePac, spn : spn); } }
internal static async Task RequestAndValidateTicketsWithCaches( KdcListener listener, string user, string password = null, string overrideKdc = null, KeyTable keytab = null, string s4u = null, bool encodeNego = false, bool caching = false, bool includePac = true, X509Certificate2 cert = null, string spn = FakeAppServiceSpn, KeyAgreementAlgorithm keyAgreement = KeyAgreementAlgorithm.DiffieHellmanModp14, bool allowWeakCrypto = false, bool useWeakCrypto = false, bool mutualAuth = true, KrbTicket s4uTicket = null, bool useKrb5TicketCache = false ) { KerberosCredential kerbCred; if (cert != null) { kerbCred = new TrustedAsymmetricCredential(cert, user) { KeyAgreement = keyAgreement }; } else if (keytab != null) { kerbCred = new KeytabCredential(user, keytab); } else { kerbCred = new KerberosPasswordCredential(user, password); } KerberosClient client = CreateClient( listener, overrideKdc, caching: caching, allowWeakCrypto: allowWeakCrypto, useWeakCrypto: useWeakCrypto, useKrb5TicketCache: useKrb5TicketCache ); using (kerbCred as IDisposable) using (client) { if (!includePac) { client.AuthenticationOptions &= ~AuthenticationOptions.IncludePacRequest; } await client.Authenticate(kerbCred); var ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = spn, ApOptions = mutualAuth ? ApOptions.MutualRequired : 0 } ); await ValidateTicket(ticket, includePac : includePac, spn : spn, mutualAuth : mutualAuth); await client.RenewTicket(); ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = spn, ApOptions = mutualAuth ? ApOptions.MutualRequired : 0 } ); await ValidateTicket(ticket, encodeNego, includePac : includePac, spn : spn, mutualAuth : mutualAuth); ticket = await client.GetServiceTicket( new RequestServiceTicket { ServicePrincipalName = spn, ApOptions = mutualAuth ? ApOptions.MutualRequired : 0, S4uTarget = s4u, S4uTicket = s4uTicket } ); await ValidateTicket(ticket, includePac : includePac, spn : spn, mutualAuth : mutualAuth); } if (user.Contains("-fallback")) { Assert.AreEqual(PrincipalNameType.NT_PRINCIPAL, kerbCred.PrincipalNameType); } else { Assert.AreEqual(PrincipalNameType.NT_ENTERPRISE, kerbCred.PrincipalNameType); } }