private ReadOnlyMemory <byte> PreAuthFailed(KerberosValidationException kex, IKerberosPrincipal principal) { var err = new KrbError { ErrorCode = KerberosErrorCode.KDC_ERR_PREAUTH_FAILED, EText = kex.Message, Realm = RealmService.Name, SName = KrbPrincipalName.FromPrincipal(principal) }; return(err.EncodeApplication()); }
private ReadOnlyMemory <byte> PreAuthFailed(PreAuthenticationContext context) { var err = new KrbError { ErrorCode = KerberosErrorCode.KDC_ERR_PREAUTH_FAILED, EText = context.Failure.Message, Realm = this.RealmService.Name, SName = KrbPrincipalName.FromPrincipal(context.Principal) }; return(err.EncodeApplication()); }
private ReadOnlyMemory <byte> RequirePreAuth(IEnumerable <KrbPaData> preAuthRequests, IKerberosPrincipal principal) { var err = new KrbError { ErrorCode = KerberosErrorCode.KDC_ERR_PREAUTH_REQUIRED, EText = "", Realm = RealmService.Name, SName = KrbPrincipalName.FromPrincipal(principal), EData = new KrbMethodData { MethodData = preAuthRequests.ToArray() }.Encode().AsMemory() }; return(err.EncodeApplication()); }
private ReadOnlyMemory <byte> RequirePreAuth(PreAuthenticationContext context) { this.logger.LogTrace("AS-REQ requires pre-auth for user {User}", context.Principal.PrincipalName); var err = new KrbError { ErrorCode = KerberosErrorCode.KDC_ERR_PREAUTH_REQUIRED, EText = string.Empty, Realm = this.RealmService.Name, SName = KrbPrincipalName.FromPrincipal(context.Principal), EData = new KrbMethodData { MethodData = context.PaData.ToArray() }.Encode() }; return(err.EncodeApplication()); }
/// <summary> /// Executes the primary validation process for the pre-auth data. /// </summary> /// <param name="asReq">The message to validate</param> /// <param name="context">The current context of the request</param> /// <returns>Optionally returns PA-Data that needs to be sent to the client otherwise returns null.</returns> public override KrbPaData Validate(KrbKdcReq asReq, PreAuthenticationContext context) { // First we authenticate the incoming request // // 1. Get the ApReq (TGT) from the PA-Data of the request // 2. Decrypt the TGT and extract the client calling identity if (context.EvidenceTicketIdentity == null) { // we wouldn't ever hit this in the normal case, but we could hit it // if a referral came in from a realm we don't recognize or don't trust throw new KerberosProtocolException(KerberosErrorCode.KDC_ERR_S_PRINCIPAL_UNKNOWN); } var evidenceSName = KrbPrincipalName.FromPrincipal(context.EvidenceTicketIdentity, PrincipalNameType.NT_SRV_INST); if (!evidenceSName.IsKrbtgt()) { // spec-wise this isn't exactly correct as the authz ticket might be for renewal // we will deviate from the spec because that's how other KDCs operate today // KDC_ERR_PADATA_TYPE_NOSUPP is the closest error to indicate the way you // authenticated the request is not something we're willing to accept throw new KerberosProtocolException(KerberosErrorCode.KDC_ERR_PADATA_TYPE_NOSUPP); } // we need to validate that the evidence ticket is the KDC service (krbtgt) // it might either be our KDC that issued it, or a KDC from another realm (referral) // if it's ours it'll match our service name (krbtgt), and it'll decrypt with our key // if it's a referral it'll match a trusted realm's name and decrypt with their key // if it's a referral then the incoming identity will also need to be transposed // no matter what we only ever want the TGS service ticket // it might belong to another realm, but that's ok because it could be a referral // it is a krbtgt service identity we recognize // it could be ours, or a referral from a trusted realm // in either case we can and will validate the ticket and // extract the user principal from within the krbtgt ticket var krbtgtKey = context.EvidenceTicketIdentity.RetrieveLongTermCredential(); if (krbtgtKey == null) { // since the key comes from caller-implemented code we // should check to make sure they gave us a usable key throw new KerberosProtocolException(KerberosErrorCode.KDC_ERR_ETYPE_NOSUPP); } if (context.EvidenceTicketKey == null) { context.EvidenceTicketKey = krbtgtKey; } var state = context.GetState <TgsState>(PaDataType.PA_TGS_REQ); if (state.DecryptedApReq == null) { state.DecryptedApReq = DecryptApReq(state.ApReq, context.EvidenceTicketKey); } context.EncryptedPartKey = state.DecryptedApReq.SessionKey; context.Ticket = state.DecryptedApReq.Ticket; return(null); }