protected override BodyWriter GetNextOutgoingMessageBody(Message incomingMessage, SspiNegotiationTokenProviderState sspiState)
        {
            try
            {
                ThrowIfFault(incomingMessage, this.TargetAddress);
            }
            catch (FaultException fault)
            {
                if (fault.Code.IsSenderFault)
                {
                    if (fault.Code.SubCode.Name == TrustApr2004Strings.FailedAuthenticationFaultCode || fault.Code.SubCode.Name == TrustFeb2005Strings.FailedAuthenticationFaultCode)
                    {
                        throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.AuthenticationOfClientFailed), fault), incomingMessage);
                    }

                    throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.FailedSspiNegotiation), fault), incomingMessage);
                }
                else
                {
                    throw;
                }
            }
            RequestSecurityTokenResponse negotiationRstr   = null;
            RequestSecurityTokenResponse authenticatorRstr = null;
            XmlDictionaryReader          bodyReader        = incomingMessage.GetReaderAtBodyContents();

            using (bodyReader)
            {
                if (this.StandardsManager.TrustDriver.IsAtRequestSecurityTokenResponseCollection(bodyReader))
                {
                    RequestSecurityTokenResponseCollection rstrCollection = this.StandardsManager.TrustDriver.CreateRequestSecurityTokenResponseCollection(bodyReader);
                    using (IEnumerator <RequestSecurityTokenResponse> enumerator = rstrCollection.RstrCollection.GetEnumerator())
                    {
                        enumerator.MoveNext();
                        negotiationRstr = enumerator.Current;
                        if (enumerator.MoveNext())
                        {
                            authenticatorRstr = enumerator.Current;
                        }
                    }
                    if (authenticatorRstr == null)
                    {
                        throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.AuthenticatorNotPresentInRSTRCollection)), incomingMessage);
                    }
                    else if (authenticatorRstr.Context != negotiationRstr.Context)
                    {
                        throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.RSTRAuthenticatorHasBadContext)), incomingMessage);
                    }
                    AddToDigest(sspiState, negotiationRstr, true, true);
                }
                else if (this.StandardsManager.TrustDriver.IsAtRequestSecurityTokenResponse(bodyReader))
                {
                    negotiationRstr = RequestSecurityTokenResponse.CreateFrom(this.StandardsManager, bodyReader);
                    AddToDigest(sspiState, negotiationRstr, true, false);
                }
                else
                {
                    this.StandardsManager.TrustDriver.OnRSTRorRSTRCMissingException();
                }
                incomingMessage.ReadFromBodyContentsToEnd(bodyReader);
            }
            if (negotiationRstr.Context != sspiState.Context)
            {
                throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.BadSecurityNegotiationContext)), incomingMessage);
            }
            BinaryNegotiation incomingBinaryNego = negotiationRstr.GetBinaryNegotiation();

            byte[] incomingBlob;
            if (incomingBinaryNego != null)
            {
                ValidateIncomingBinaryNegotiation(incomingBinaryNego);
                incomingBlob = incomingBinaryNego.GetNegotiationData();
            }
            else
            {
                incomingBlob = null;
            }
            BodyWriter nextMessageBody;

            if (incomingBlob == null && sspiState.SspiNegotiation.IsCompleted == false)
            {
                throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.NoBinaryNegoToReceive)), incomingMessage);
            }
            else if (incomingBlob == null && sspiState.SspiNegotiation.IsCompleted == true)
            {
                // the incoming RSTR must have the negotiated token
                OnNegotiationComplete(sspiState, negotiationRstr, authenticatorRstr);
                nextMessageBody = null;
            }
            else
            {
                // we got an incoming blob. Process it and see if there is an outgoing blob
                byte[] outgoingBlob = sspiState.SspiNegotiation.GetOutgoingBlob(incomingBlob,
                                                                                SecurityUtils.GetChannelBindingFromMessage(incomingMessage),
                                                                                null);

                if (outgoingBlob == null && sspiState.SspiNegotiation.IsCompleted == false)
                {
                    throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.NoBinaryNegoToSend)), incomingMessage);
                }
                else if (outgoingBlob == null && sspiState.SspiNegotiation.IsCompleted == true)
                {
                    // the incoming RSTR had the last blob. It must have the token too
                    this.OnNegotiationComplete(sspiState, negotiationRstr, authenticatorRstr);
                    nextMessageBody = null;
                }
                else
                {
                    nextMessageBody = PrepareRstr(sspiState, outgoingBlob);
                }
            }
            return(nextMessageBody);
        }
        BodyWriter ProcessNegotiation(SspiNegotiationTokenAuthenticatorState negotiationState, Message incomingMessage, BinaryNegotiation incomingNego)
        {
            ISspiNegotiation sspiNegotiation = negotiationState.SspiNegotiation;

            byte[] outgoingBlob = sspiNegotiation.GetOutgoingBlob(incomingNego.GetNegotiationData(),
                                                                  SecurityUtils.GetChannelBindingFromMessage(incomingMessage),
                                                                  this.extendedProtectionPolicy);

            if (sspiNegotiation.IsValidContext == false)
            {
                throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.InvalidSspiNegotiation)), incomingMessage);
            }
            // if there is no blob to send back the nego must be complete from the server side
            if (outgoingBlob == null && sspiNegotiation.IsCompleted == false)
            {
                throw TraceUtility.ThrowHelperError(new SecurityNegotiationException(SR.GetString(SR.NoBinaryNegoToSend)), incomingMessage);
            }
            BinaryNegotiation outgoingBinaryNegotiation;

            if (outgoingBlob != null)
            {
                outgoingBinaryNegotiation = GetOutgoingBinaryNegotiation(sspiNegotiation, outgoingBlob);
            }
            else
            {
                outgoingBinaryNegotiation = null;
            }
            BodyWriter replyBody;

            if (sspiNegotiation.IsCompleted)
            {
                ReadOnlyCollection <IAuthorizationPolicy> authorizationPolicies = ValidateSspiNegotiation(sspiNegotiation);
                SecurityContextSecurityToken serviceToken;
                WrappedKeySecurityToken      proofToken;
                int issuedKeySize;
                IssueServiceToken(negotiationState, authorizationPolicies, out serviceToken, out proofToken, out issuedKeySize);
                negotiationState.SetServiceToken(serviceToken);

                SecurityKeyIdentifierClause externalTokenReference = this.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(serviceToken, SecurityTokenReferenceStyle.External);
                SecurityKeyIdentifierClause internalTokenReference = this.IssuedSecurityTokenParameters.CreateKeyIdentifierClause(serviceToken, SecurityTokenReferenceStyle.Internal);

                RequestSecurityTokenResponse dummyRstr = new RequestSecurityTokenResponse(this.StandardsManager);
                dummyRstr.Context   = negotiationState.Context;
                dummyRstr.KeySize   = issuedKeySize;
                dummyRstr.TokenType = this.SecurityContextTokenUri;
                if (outgoingBinaryNegotiation != null)
                {
                    dummyRstr.SetBinaryNegotiation(outgoingBinaryNegotiation);
                }
                dummyRstr.RequestedUnattachedReference = externalTokenReference;
                dummyRstr.RequestedAttachedReference   = internalTokenReference;
                dummyRstr.SetLifetime(serviceToken.ValidFrom, serviceToken.ValidTo);
                if (negotiationState.AppliesTo != null)
                {
                    if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressing10)
                    {
                        dummyRstr.SetAppliesTo <EndpointAddress10>(EndpointAddress10.FromEndpointAddress(
                                                                       negotiationState.AppliesTo),
                                                                   negotiationState.AppliesToSerializer);
                    }
                    else if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressingAugust2004)
                    {
                        dummyRstr.SetAppliesTo <EndpointAddressAugust2004>(EndpointAddressAugust2004.FromEndpointAddress(
                                                                               negotiationState.AppliesTo),
                                                                           negotiationState.AppliesToSerializer);
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, incomingMessage.Version.Addressing)));
                    }
                }
                dummyRstr.MakeReadOnly();
                AddToDigest(negotiationState, dummyRstr, false);
                RequestSecurityTokenResponse negotiationRstr = new RequestSecurityTokenResponse(this.StandardsManager);
                negotiationRstr.RequestedSecurityToken = serviceToken;

                negotiationRstr.RequestedProofToken = proofToken;
                negotiationRstr.Context             = negotiationState.Context;
                negotiationRstr.KeySize             = issuedKeySize;
                negotiationRstr.TokenType           = this.SecurityContextTokenUri;
                if (outgoingBinaryNegotiation != null)
                {
                    negotiationRstr.SetBinaryNegotiation(outgoingBinaryNegotiation);
                }
                negotiationRstr.RequestedAttachedReference   = internalTokenReference;
                negotiationRstr.RequestedUnattachedReference = externalTokenReference;
                if (negotiationState.AppliesTo != null)
                {
                    if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressing10)
                    {
                        negotiationRstr.SetAppliesTo <EndpointAddress10>(
                            EndpointAddress10.FromEndpointAddress(negotiationState.AppliesTo),
                            negotiationState.AppliesToSerializer);
                    }
                    else if (incomingMessage.Version.Addressing == AddressingVersion.WSAddressingAugust2004)
                    {
                        negotiationRstr.SetAppliesTo <EndpointAddressAugust2004>(
                            EndpointAddressAugust2004.FromEndpointAddress(negotiationState.AppliesTo),
                            negotiationState.AppliesToSerializer);
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new ProtocolException(SR.GetString(SR.AddressingVersionNotSupported, incomingMessage.Version.Addressing)));
                    }
                }
                negotiationRstr.MakeReadOnly();

                byte[] authenticator = ComputeAuthenticator(negotiationState, serviceToken.GetKeyBytes());
                RequestSecurityTokenResponse authenticatorRstr = new RequestSecurityTokenResponse(this.StandardsManager);
                authenticatorRstr.Context = negotiationState.Context;
                authenticatorRstr.SetAuthenticator(authenticator);
                authenticatorRstr.MakeReadOnly();

                List <RequestSecurityTokenResponse> rstrList = new List <RequestSecurityTokenResponse>(2);
                rstrList.Add(negotiationRstr);
                rstrList.Add(authenticatorRstr);
                replyBody = new RequestSecurityTokenResponseCollection(rstrList, this.StandardsManager);
            }
            else
            {
                RequestSecurityTokenResponse rstr = new RequestSecurityTokenResponse(this.StandardsManager);
                rstr.Context = negotiationState.Context;
                rstr.SetBinaryNegotiation(outgoingBinaryNegotiation);
                rstr.MakeReadOnly();
                AddToDigest(negotiationState, rstr, false);
                replyBody = rstr;
            }

            return(replyBody);
        }
예제 #3
0
        protected virtual void VerifyIncomingMessageCore(ref Message message, TimeSpan timeout)
        {
            TransportSecurityProtocolFactory factory = (TransportSecurityProtocolFactory)this.SecurityProtocolFactory;
            string actor = string.Empty; // message.Version.Envelope.UltimateDestinationActor;

            ReceiveSecurityHeader securityHeader = factory.StandardsManager.TryCreateReceiveSecurityHeader(message, actor,
                                                                                                           factory.IncomingAlgorithmSuite, (factory.ActAsInitiator) ? MessageDirection.Output : MessageDirection.Input);
            bool expectBasicTokens;
            bool expectEndorsingTokens;
            bool expectSignedTokens;
            IList <SupportingTokenAuthenticatorSpecification> supportingAuthenticators = factory.GetSupportingTokenAuthenticators(message.Headers.Action,
                                                                                                                                  out expectSignedTokens, out expectBasicTokens, out expectEndorsingTokens);

            if (securityHeader == null)
            {
                bool expectSupportingTokens = expectEndorsingTokens || expectSignedTokens || expectBasicTokens;
                if ((factory.ActAsInitiator && (!factory.AddTimestamp || factory.SecurityBindingElement.EnableUnsecuredResponse)) ||
                    (!factory.ActAsInitiator && !factory.AddTimestamp && !expectSupportingTokens))
                {
                    return;
                }
                else
                {
                    if (String.IsNullOrEmpty(actor))
                    {
                        throw System.ServiceModel.Diagnostics.TraceUtility.ThrowHelperError(new MessageSecurityException(
                                                                                                SR.GetString(SR.UnableToFindSecurityHeaderInMessageNoActor)), message);
                    }
                    else
                    {
                        throw System.ServiceModel.Diagnostics.TraceUtility.ThrowHelperError(new MessageSecurityException(
                                                                                                SR.GetString(SR.UnableToFindSecurityHeaderInMessage, actor)), message);
                    }
                }
            }

            securityHeader.RequireMessageProtection = false;
            securityHeader.ExpectBasicTokens        = expectBasicTokens;
            securityHeader.ExpectSignedTokens       = expectSignedTokens;
            securityHeader.ExpectEndorsingTokens    = expectEndorsingTokens;
            securityHeader.MaxReceivedMessageSize   = factory.SecurityBindingElement.MaxReceivedMessageSize;
            securityHeader.ReaderQuotas             = factory.SecurityBindingElement.ReaderQuotas;

            // Due to compatibility, only honor this setting if this app setting is enabled
            if (ServiceModelAppSettings.UseConfiguredTransportSecurityHeaderLayout)
            {
                securityHeader.Layout = factory.SecurityHeaderLayout;
            }

            TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);

            if (!factory.ActAsInitiator)
            {
                securityHeader.ConfigureTransportBindingServerReceiveHeader(supportingAuthenticators);
                securityHeader.ConfigureOutOfBandTokenResolver(MergeOutOfBandResolvers(supportingAuthenticators, EmptyReadOnlyCollection <SecurityTokenResolver> .Instance));
                if (factory.ExpectKeyDerivation)
                {
                    securityHeader.DerivedTokenAuthenticator = factory.DerivedKeyTokenAuthenticator;
                }
            }
            securityHeader.ReplayDetectionEnabled = factory.DetectReplays;
            securityHeader.SetTimeParameters(factory.NonceCache, factory.ReplayWindow, factory.MaxClockSkew);
            securityHeader.Process(timeoutHelper.RemainingTime(), SecurityUtils.GetChannelBindingFromMessage(message), factory.ExtendedProtectionPolicy);
            message = securityHeader.ProcessedMessage;
            if (!factory.ActAsInitiator)
            {
                AttachRecipientSecurityProperty(message, securityHeader.BasicSupportingTokens, securityHeader.EndorsingSupportingTokens, securityHeader.SignedEndorsingSupportingTokens,
                                                securityHeader.SignedSupportingTokens, securityHeader.SecurityTokenAuthorizationPoliciesMapping);
            }

            base.OnIncomingMessageVerified(message);
        }