예제 #1
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);
        }
예제 #2
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);
        }
예제 #3
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);
            }
        }
예제 #4
0
        public async Task RequestTgt(string algo)
        {
            var cred = new KerberosPasswordCredential(algo + user, password);

            var client = new KerberosClient($"{overrideKdc}:{port}");

            for (var i = 0; i < AuthenticationAttempts; i++)
            {
                await client.Authenticate(cred);
            }
        }
예제 #5
0
        public async Task ClientConnectsToServer_Withtimeout()
        {
            var port = NextPort();

            var client = new KerberosClient($"127.0.0.1:{port}")
            {
                ConnectTimeout = TimeSpan.FromMilliseconds(1)
            };

            await client.Authenticate(new KerberosPasswordCredential("test", "test", "test"));
        }
        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);
        }
예제 #7
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);
            }
        }
        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();
        }
예제 #9
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
                    );
            }
        }
예제 #10
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));
        }
예제 #11
0
        public void RequestTgt()
        {
            TcpKerberosTransport.MaxPoolSize = this.ConcurrentRequests * 2;

            if (this.credential == null)
            {
                this.credential = Creds.GetOrAdd(this.AlgorithmType, a => new KerberosPasswordCredential(a + this.user, this.password));
            }

            var requestCounter = 0;

            try
            {
                Task.WaitAll(Enumerable.Range(0, this.ConcurrentRequests).Select(taskNum => Task.Run(async() =>
                {
                    var client = new KerberosClient();

                    client.Transports.OfType <UdpKerberosTransport>().FirstOrDefault().Enabled   = false;
                    client.Transports.OfType <HttpsKerberosTransport>().FirstOrDefault().Enabled = false;

                    client.PinKdc(this.credential.Domain, $"{this.overrideKdc}:{this.Port}");

                    for (var i = 0; i < this.AuthenticationAttempts; i++)
                    {
                        try
                        {
                            await client.Authenticate(this.credential);

                            Interlocked.Increment(ref Successes);

                            if (this.DisplayProgress)
                            {
                                CountItOut(ref requestCounter);
                            }
                        }
                        catch (Exception)
                        {
                        }
                    }
                })).ToArray());
            }
            catch
            {
            }
        }
예제 #12
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
                        );
                }
            }
        }
예제 #13
0
        public void RequestTgt()
        {
            var requestCounter = 0;

            Task.WaitAll(Enumerable.Range(0, ConcurrentRequests).Select(taskNum => Task.Run(async() =>
            {
                var client = new KerberosClient($"{overrideKdc}:{Port}");

                for (var i = 0; i < AuthenticationAttempts; i++)
                {
                    await client.Authenticate(credential);

                    if (DisplayProgress)
                    {
                        CountItOut(ref requestCounter);
                    }
                }
            })).ToArray());
        }
예제 #14
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();
            }
        }
예제 #15
0
        public async Task ClientConnectsToServer_WithTimeout()
        {
            var port = NextPort();

            using (var client = new KerberosClient()
            {
                ConnectTimeout = TimeSpan.FromMilliseconds(1)
            })
            {
                client.Configuration.Defaults.DnsLookupKdc = false;

                client.PinKdc("test", $"127.0.0.1:{port}");

                try
                {
                    await client.Authenticate(new KerberosPasswordCredential("test", "test", "test"));
                }
                catch (AggregateException agg)
                {
                    throw agg.InnerExceptions.First();
                }
            }
        }
예제 #16
0
        public void RequestTgt()
        {
            var requestCounter = 0;

            Task.WaitAll(Enumerable.Range(0, ConcurrentRequests).Select(taskNum => Task.Run(async() =>
            {
                var algo = Algorithms[random.Next(0, Algorithms.Length - 1)];

                var cred = Creds.GetOrAdd(algo, a => new KerberosPasswordCredential(a + user, password));

                var client = new KerberosClient($"{overrideKdc}:{Port}");

                for (var i = 0; i < AuthenticationAttempts; i++)
                {
                    await client.Authenticate(cred);

                    if (DisplayProgress)
                    {
                        CountItOut(ref requestCounter);
                    }
                }
            })).ToArray());
        }
예제 #17
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);
        }
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app)
        {
            var whitelist = app.ApplicationServices.GetRequiredService <IWhitelist>();

            var features = app.ServerFeatures.ToArray();

            app.MapWhen(context => context.Request.HttpContext.Connection.LocalPort > 10000
                        , map =>
            {
                map.Use(async(ctx, next) =>
                {
                    var proxyMap = ctx.RequestServices.GetService <ProxyMap>();
                    if (!proxyMap.Entries.TryGetValue(ctx.Connection.LocalPort, out var proxySettings))
                    {
                        await ctx.Response.WriteAsync("No proxy settings found for this port mapping");
                        return;
                    }

                    var config   = ctx.RequestServices.GetRequiredService <IConfiguration>();
                    var client   = new KerberosClient(config.GetValue <string>("Kerberos:Kdc"));
                    var kerbCred = new KerberosPasswordCredential(proxySettings.ClientLogin, proxySettings.ClientPassword);
                    await client.Authenticate(kerbCred);
                    var kerberosTicket = await client.GetServiceTicket(proxySettings.TargetSpn);


                    ctx.Items["KerberosTicket"] = Convert.ToBase64String(kerberosTicket.EncodeApplication().ToArray());
                    ctx.Items["ProxySettings"]  = proxySettings;
                    await next();
                });
                map.RunProxy(async context =>
                {
                    var kerberosTicket = (string)context.Items["KerberosTicket"];
                    var proxySettings  = (ProxyMapEntry)context.Items["ProxySettings"];
                    var proxyRequest   = context.ForwardTo(proxySettings.TargetUrl);
                    proxyRequest.HttpContext.Request.Headers.Add("Authorization", $"Negotiate {kerberosTicket}");
                    return(await proxyRequest.Send());
                });
            });
            app.MapWhen(context => context.Request.HttpContext.Connection.LocalPort < 10000
                        , reverseProxy =>
            {
                reverseProxy.UseAuthentication();
                reverseProxy.Use(async(context, next) =>
                {
                    if (!context.User.Identity.IsAuthenticated)
                    {
                        if (whitelist.IsWhitelisted(context.Request))
                        {
                            _logger.LogDebug($"Allowing passthrough for whitelisted request {context.Request.Path}");
                        }
                        else
                        {
                            var authResult = await context.AuthenticateAsync(SpnegoAuthenticationDefaults.AuthenticationScheme);
                            if (authResult.Succeeded)
                            {
                                _logger.LogDebug($"User {authResult.Principal.Identity.Name} successfully logged in");
                                await context.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme,
                                                          authResult.Principal);
                                context.User = authResult.Principal;
                            }
                            else
                            {
                                _logger.LogDebug("User authentication failed, issuing WWW-Authenticate challenge");
                                await context.ChallengeAsync(SpnegoAuthenticationDefaults.AuthenticationScheme
                                                             , new AuthenticationProperties());
                                return;
                            }
                        }
                    }

                    await next();
                });
                reverseProxy.RunProxy(async context =>
                {
                    HttpResponseMessage response;
                    if (!context.Request.Headers.TryGetForwardAddress(out var forwardTo))
                    {
                        response = new HttpResponseMessage(HttpStatusCode.BadRequest)
                        {
                            Content = new StringContent($"Required header {Constants.X_CF_Forwarded_Url} not present in the request")
                        };
                        _logger.LogDebug($"Received request without {Constants.X_CF_Forwarded_Url} header");
                        return(response);
                    }

                    var forwardContext = context.ForwardTo(forwardTo);
                    forwardContext.UpstreamRequest.RequestUri = new Uri(forwardTo);

                    if (whitelist.IsWhitelisted(context.Request))
                    {
                        _logger.LogInformation($"Allowing passthrough for whitelisted request {forwardTo}");
                    }
                    else
                    {
                        if (context.User.Identity.IsAuthenticated)
                        {
                            forwardContext.UpstreamRequest.Headers.Add(Constants.X_CF_Identity, context.User.Identity.Name);
                            var roles = string.Join(",", context.User.Claims.Where(x => x.Type == ClaimTypes.Role).Select(x => x.Value));
                            if (!string.IsNullOrEmpty(roles))
                            {
                                forwardContext.UpstreamRequest.Headers.Add(Constants.X_CF_Roles, roles);
                            }
                        }

                        forwardContext.UpstreamRequest.Headers.Remove("Authorization");
                    }

                    _logger.LogTrace("Headers sent downstream");
                    _logger.LogTrace("-----------------------");
                    foreach (var header in forwardContext.UpstreamRequest.Headers)
                    {
                        _logger.LogTrace($"  {header.Key}: {header.Value.FirstOrDefault()}");
                    }

                    response = await forwardContext.Send();
                    _logger.LogDebug($"Downstream responded with: {response.StatusCode}");

                    // merge cookie header set at the proxy level with headers from downstream request
                    foreach (var cookie in context.Response.Headers["Set-Cookie"])
                    {
                        response.Headers.TryAddWithoutValidation("Set-Cookie", cookie);
                    }

                    return(response);
                });
            });
        public async Task E2EMultithreadedClient()
        {
            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)
            };

            using (KdcServiceListener listener = new KdcServiceListener(options))
            {
                _ = listener.Start();

                var exceptions = new List <Exception>();

                var kerbCred = new KerberosPasswordCredential("*****@*****.**", "P@ssw0rd!");

                string kdc = $"127.0.0.1:{port}";
                //string kdc = "10.0.0.21:88";

                using (KerberosClient client = new KerberosClient(kdc))
                {
                    client.CacheServiceTickets = false;

                    await client.Authenticate(kerbCred);

                    Task.WaitAll(Enumerable.Range(0, 2).Select(taskNum => Task.Run(async() =>
                    {
                        for (var i = 0; i < 100; i++)
                        {
                            try
                            {
                                if (i % 2 == 0)
                                {
                                    await client.Authenticate(kerbCred);
                                }

                                var ticket = await client.GetServiceTicket(new RequestServiceTicket
                                {
                                    ServicePrincipalName = "host/appservice.corp.identityintervention.com",
                                    ApOptions            = ApOptions.MutualRequired
                                });

                                Assert.IsNotNull(ticket.ApReq);

                                await ValidateTicket(ticket);
                            }
                            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()));
                }
            }
        }
예제 #20
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()));
                }
            }
        }
예제 #21
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);
            }
        }
예제 #22
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);
            }
        }
예제 #23
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();
                        }
                    }
                }
        }
예제 #24
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);
            }
        }
예제 #25
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}
");
        }
예제 #26
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);
            }
        }
예제 #27
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);
        }