Beispiel #1
0
        public static KrbTgsReq CreateTgsReq(
            string spn,
            KrbEncryptionKey tgtSessionKey,
            KrbKdcRep kdcRep,
            KdcOptions options,
            KrbTicket user2UserTicket = null
            )
        {
            var tgtApReq = CreateApReq(kdcRep, tgtSessionKey);

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

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

            var tgt = kdcRep.Ticket;

            var sname = spn.Split('/', '@');

            var tgs = new KrbTgsReq
            {
                PaData = paData.ToArray(),
                Body   = new KrbKdcReqBody
                {
                    EType      = KerberosConstants.ETypes.ToArray(),
                    KdcOptions = options,
                    Nonce      = KerberosConstants.GetNonce(),
                    Realm      = tgt.Realm,
                    SName      = new KrbPrincipalName()
                    {
                        Type = PrincipalNameType.NT_SRV_HST,
                        Name = sname
                    },
                    Till = KerberosConstants.EndOfTime
                },
            };

            if (options.HasFlag(KdcOptions.EncTktInSkey) && user2UserTicket != null)
            {
                tgs.Body.AdditionalTickets = new[] {
                    user2UserTicket
                };
            }

            return(tgs);
        }
Beispiel #2
0
        public static KrbTgsReq CreateTgsReq(
            RequestServiceTicket rst,
            KrbEncryptionKey tgtSessionKey,
            KrbKdcRep kdcRep,
            out KrbEncryptionKey sessionKey
            )
        {
            var sname = rst.ServicePrincipalName.Split('/', '@');
            var tgt   = kdcRep.Ticket;

            var additionalTickets = new List <KrbTicket>();

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

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

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

                additionalTickets.Add(rst.S4uTicket);
            }

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

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

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

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

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

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

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

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

            return(tgs);
        }
Beispiel #3
0
        public static KrbTgsReq CreateTgsReq(
            RequestServiceTicket rst,
            KrbEncryptionKey tgtSessionKey,
            KrbKdcRep kdcRep,
            out KrbEncryptionKey sessionKey
            )
        {
            if (kdcRep == null)
            {
                throw new ArgumentNullException(nameof(kdcRep));
            }

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

            if (string.IsNullOrWhiteSpace(rst.ServicePrincipalName))
            {
                throw new ArgumentNullException(nameof(rst.ServicePrincipalName));
            }

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

            var additionalTickets = new List <KrbTicket>();

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

            if (!string.IsNullOrWhiteSpace(rst.S4uTarget) && rst.S4uTicket != null)
            {
                throw new InvalidOperationException(SR.Resource("S4uTargetTicketBothPresent"));
            }

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

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

                additionalTickets.Add(rst.S4uTicket);
            }

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

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

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

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

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

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

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

            if (!string.IsNullOrWhiteSpace(rst.S4uTarget))
            {
                if (tgtSessionKey.EType == EncryptionType.RC4_HMAC_NT)
                {
                    paData.Add(new KrbPaData
                    {
                        Type  = PaDataType.PA_FOR_USER,
                        Value = EncodeS4ULegacyRequest(rst.S4uTarget, tgt.Realm, tgtSessionKey)
                    });
                }
                else
                {
                    paData.Add(new KrbPaData
                    {
                        Type  = PaDataType.PA_FOR_X509_USER,
                        Value = EncodeS4URequest(rst.S4uTarget, rst.S4uTargetCertificate, body.Nonce, tgt.Realm, sessionKey)
                    });
                }
            }

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

            return(tgs);
        }