예제 #1
0
        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);
            }
        }
예제 #2
0
        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);
        }
예제 #4
0
        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);
            }
        }
예제 #5
0
 public async Task ClientRequestsServiceTicketBeforeAuthentication()
 {
     using (var client = new KerberosClient())
     {
         await client.GetServiceTicket("host/test.com");
     }
 }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #9
0
 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();
        }
예제 #11
0
        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"));
                }
            }
        }
예제 #12
0
        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);
            }
        }
예제 #13
0
        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);
            }
        }
예제 #14
0
        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);
        }
예제 #15
0
        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
                    );
            }
        }
예제 #16
0
        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));
        }
예제 #17
0
        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
                        );
                }
            }
        }
예제 #18
0
        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();
        }
예제 #19
0
        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);
            }
        }
예제 #20
0
        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();
            }
        }
예제 #21
0
        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);
            }
        }
예제 #22
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);
                }
            }
        }
예제 #23
0
        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);
        }
예제 #24
0
        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);
            }
        }
예제 #25
0
        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);
            }
        }
예제 #26
0
        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}
");
        }
예제 #27
0
        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()));
                }
            }
        }
예제 #28
0
        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();
                        }
                    }
                }
        }
예제 #29
0
        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);
            }
        }
예제 #30
0
        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);
            }
        }