/// <summary>
		/// Prepares a message for sending based on the rules of this channel binding element.
		/// </summary>
		/// <param name="message">The message to prepare for sending.</param>
		/// <returns>
		/// The protections (if any) that this binding element applied to the message.
		/// Null if this binding element did not even apply to this binding element.
		/// </returns>
		/// <remarks>
		/// Implementations that provide message protection must honor the
		/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
		/// </remarks>
		public MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
			var userAuthResponse = message as UserAuthorizationResponse;
			if (userAuthResponse != null && userAuthResponse.Version >= Protocol.V10a.Version) {
				var requestToken = this.tokenManager.GetRequestToken(userAuthResponse.RequestToken);
				requestToken.VerificationCode = userAuthResponse.VerificationCode;
				this.tokenManager.UpdateToken(requestToken);
				return MessageProtections.None;
			}

			// Hook to store the token and secret on its way down to the Consumer.
			var grantRequestTokenResponse = message as UnauthorizedTokenResponse;
			if (grantRequestTokenResponse != null) {
				this.tokenManager.StoreNewRequestToken(grantRequestTokenResponse.RequestMessage, grantRequestTokenResponse);

				// The host may have already set these properties, but just to make sure...
				var requestToken = this.tokenManager.GetRequestToken(grantRequestTokenResponse.RequestToken);
				requestToken.ConsumerVersion = grantRequestTokenResponse.Version;
				if (grantRequestTokenResponse.RequestMessage.Callback != null) {
					requestToken.Callback = grantRequestTokenResponse.RequestMessage.Callback;
				}
				this.tokenManager.UpdateToken(requestToken);

				return MessageProtections.None;
			}

			return null;
		}
        /// <summary>
        /// Initializes a new instance of the <see cref="AutoResponsiveRequest"/> class.
        /// </summary>
        /// <param name="request">The request message.</param>
        /// <param name="response">The response that is ready for transmittal.</param>
        /// <param name="securitySettings">The security settings.</param>
        internal AutoResponsiveRequest(IDirectedProtocolMessage request, IProtocolMessage response, ProviderSecuritySettings securitySettings)
            : base(request, securitySettings)
        {
            ErrorUtilities.VerifyArgumentNotNull(response, "response");

            this.response = response;
        }
		/// <summary>
		/// Initializes a new instance of the <see cref="CoordinatingOutgoingWebResponse"/> class.
		/// </summary>
		/// <param name="message">The direct response message to send to the remote channel.  This message will be cloned.</param>
		/// <param name="receivingChannel">The receiving channel.</param>
		internal CoordinatingOutgoingWebResponse(IProtocolMessage message, CoordinatingChannel receivingChannel) {
			Contract.Requires<ArgumentNullException>(message != null);
			Contract.Requires<ArgumentNullException>(receivingChannel != null);

			this.receivingChannel = receivingChannel;
			this.OriginalMessage = message;
		}
        /// <summary>
        /// Initializes a new instance of the <see cref="AutoResponsiveRequest"/> class
        /// for a response to an unrecognizable request.
        /// </summary>
        /// <param name="response">The response that is ready for transmittal.</param>
        /// <param name="securitySettings">The security settings.</param>
        internal AutoResponsiveRequest(IProtocolMessage response, ProviderSecuritySettings securitySettings)
            : base(IndirectResponseBase.GetVersion(response), securitySettings)
        {
            ErrorUtilities.VerifyArgumentNotNull(response, "response");

            this.response = response;
        }
        /// <summary>
        /// Performs any transformation on an incoming message that may be necessary and/or
        /// validates an incoming message based on the rules of this channel binding element.
        /// </summary>
        /// <param name="message">The incoming message to process.</param>
        /// <returns>
        /// The protections (if any) that this binding element applied to the message.
        /// Null if this binding element did not even apply to this binding element.
        /// </returns>
        /// <exception cref="ProtocolException">
        /// Thrown when the binding element rules indicate that this message is invalid and should
        /// NOT be processed.
        /// </exception>
        /// <remarks>
        /// Implementations that provide message protection must honor the
        /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
        /// </remarks>
        public MessageProtections? ProcessIncomingMessage(IProtocolMessage message)
        {
            IndirectSignedResponse response = message as IndirectSignedResponse;
            if (response != null && response.Version.Major < 2) {
                // GetReturnToArgument may return parameters that are not signed,
                // but we must allow for that since in OpenID 1.x, a stateless RP has
                // no way to preserve the provider endpoint and claimed identifier otherwise.
                // We'll verify the positive assertion later in the
                // RelyingParty.PositiveAuthenticationResponse constructor anyway.
                // If this is a 1.0 OP signed response without these parameters then we didn't initiate
                // the request ,and since 1.0 OPs are not supposed to be able to send unsolicited
                // assertions it's an invalid case that we throw an exception for.
                if (response.ProviderEndpoint == null) {
                    string op_endpoint = response.GetReturnToArgument(ProviderEndpointParameterName);
                    ErrorUtilities.VerifyProtocol(op_endpoint != null, MessagingStrings.RequiredParametersMissing, message.GetType().Name, ProviderEndpointParameterName);
                    response.ProviderEndpoint = new Uri(op_endpoint);
                }

                PositiveAssertionResponse authResponse = response as PositiveAssertionResponse;
                if (authResponse != null) {
                    if (authResponse.ClaimedIdentifier == null) {
                        string claimedId = response.GetReturnToArgument(ClaimedIdentifierParameterName);
                        ErrorUtilities.VerifyProtocol(claimedId != null, MessagingStrings.RequiredParametersMissing, message.GetType().Name, ClaimedIdentifierParameterName);
                        authResponse.ClaimedIdentifier = claimedId;
                    }
                }

                return MessageProtections.None;
            }

            return null;
        }
		/// <summary>
		/// Queues a message for sending in the response stream.
		/// </summary>
		/// <param name="response">The message to send as a response.</param>
		/// <returns>
		/// The pending user agent redirect based message to be sent as an HttpResponse.
		/// </returns>
		/// <remarks>
		/// This method implements spec OAuth V1.0 section 5.3.
		/// </remarks>
		protected override HttpResponseMessage PrepareDirectResponse(IProtocolMessage response) {
			var webResponse = new HttpResponseMessage();
			ApplyMessageTemplate(response, webResponse);
			string json = this.SerializeAsJson(response);
			webResponse.Content = new StringContent(json, Encoding.UTF8, JsonEncoded);
			return webResponse;
		}
        /// <summary>
        /// Initializes a new instance of the <see cref="AutoResponsiveRequest"/> class.
        /// </summary>
        /// <param name="request">The request message.</param>
        /// <param name="response">The response that is ready for transmittal.</param>
        internal AutoResponsiveRequest(IDirectedProtocolMessage request, IProtocolMessage response)
            : base(request)
        {
            ErrorUtilities.VerifyArgumentNotNull(response, "response");

            this.response = response;
        }
		/// <summary>
		/// Prepares a message for sending based on the rules of this channel binding element.
		/// </summary>
		/// <param name="message">The message to prepare for sending.</param>
		/// <returns>
		/// The protections (if any) that this binding element applied to the message.
		/// Null if this binding element did not even apply to this binding element.
		/// </returns>
		/// <remarks>
		/// Implementations that provide message protection must honor the
		/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
		/// </remarks>
		public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
			var authCodeCarrier = message as IAuthorizationCodeCarryingRequest;
			if (authCodeCarrier != null) {
				var codeFormatter = AuthorizationCode.CreateFormatter(this.AuthorizationServer);
				var code = authCodeCarrier.AuthorizationDescription;
				authCodeCarrier.Code = codeFormatter.Serialize(code);
				return MessageProtections.None;
			}

			var accessTokenCarrier = message as IAccessTokenCarryingRequest;
			if (accessTokenCarrier != null) {
				var responseWithOriginatingRequest = (IDirectResponseProtocolMessage)message;
				var request = (IAccessTokenRequest)responseWithOriginatingRequest.OriginatingRequest;

				using (var resourceServerKey = this.AuthorizationServer.GetResourceServerEncryptionKey(request)) {
					var tokenFormatter = AccessToken.CreateFormatter(this.AuthorizationServer.AccessTokenSigningKey, resourceServerKey);
					var token = accessTokenCarrier.AuthorizationDescription;
					accessTokenCarrier.AccessToken = tokenFormatter.Serialize(token);
				}

				return MessageProtections.None;
			}

			var accessTokenResponse = message as AccessTokenSuccessResponse;
			if (accessTokenResponse != null) {
				var directResponseMessage = (IDirectResponseProtocolMessage)accessTokenResponse;
				var accessTokenRequest = (AccessTokenRequestBase)directResponseMessage.OriginatingRequest;
				ErrorUtilities.VerifyProtocol(accessTokenRequest.GrantType != GrantType.ClientCredentials || accessTokenResponse.RefreshToken == null, OAuthStrings.NoGrantNoRefreshToken);
			}

			return null;
		}
		/// <summary>
		/// Prepares a message for sending based on the rules of this channel binding element.
		/// </summary>
		/// <param name="message">The message to prepare for sending.</param>
		/// <returns>
		/// The protections (if any) that this binding element applied to the message.
		/// Null if this binding element did not even apply to this binding element.
		/// </returns>
		public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
			var directResponse = message as IDirectResponseProtocolMessage;
			IAccessTokenRequest request = directResponse != null ? directResponse.OriginatingRequest as IAccessTokenRequest : null;

			var implicitGrantResponse = message as EndUserAuthorizationSuccessAccessTokenResponse;
			if (implicitGrantResponse != null) {
				IAuthorizationCarryingRequest tokenCarryingResponse = implicitGrantResponse;
				tokenCarryingResponse.AuthorizationDescription = new AccessToken(request.ClientIdentifier, implicitGrantResponse.Scope, implicitGrantResponse.AuthorizingUsername, implicitGrantResponse.Lifetime);

				return MessageProtections.None;
			}

			var accessTokenResponse = message as AccessTokenSuccessResponse;
			if (accessTokenResponse != null) {
				var authCarryingRequest = (IAuthorizationCarryingRequest)request;
				var accessToken = new AccessToken(authCarryingRequest.AuthorizationDescription, accessTokenResponse.Lifetime);
				using (var resourceServerEncryptionKey = this.AuthorizationServer.GetResourceServerEncryptionKey(request)) {
					var accessTokenFormatter = AccessToken.CreateFormatter(this.AuthorizationServer.AccessTokenSigningKey, resourceServerEncryptionKey);
					accessTokenResponse.AccessToken = accessTokenFormatter.Serialize(accessToken);
				}

				if (accessTokenResponse.HasRefreshToken) {
					var refreshToken = new RefreshToken(authCarryingRequest.AuthorizationDescription);
					var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServer.CryptoKeyStore);
					accessTokenResponse.RefreshToken = refreshTokenFormatter.Serialize(refreshToken);
				}
			}

			return null;
		}
		/// <summary>
		/// Prepares a message for sending based on the rules of this channel binding element.
		/// </summary>
		/// <param name="message">The message to prepare for sending.</param>
		/// <returns>
		/// The protections (if any) that this binding element applied to the message.
		/// Null if this binding element did not even apply to this binding element.
		/// </returns>
		/// <remarks>
		/// Implementations that provide message protection must honor the
		/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
		/// </remarks>
		public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
			var response = message as IAuthorizationCarryingRequest;
			if (response != null) {
				switch (response.CodeOrTokenType) {
					case CodeOrTokenType.AuthorizationCode:
						var codeFormatter = AuthorizationCode.CreateFormatter(this.AuthorizationServer);
						var code = (AuthorizationCode)response.AuthorizationDescription;
						response.CodeOrToken = codeFormatter.Serialize(code);
						break;
					default:
						throw ErrorUtilities.ThrowInternal(string.Format(CultureInfo.CurrentCulture, "Unexpected outgoing code or token type: {0}", response.CodeOrTokenType));
				}

				return MessageProtections.None;
			}

			var accessTokenResponse = message as AccessTokenSuccessResponse;
			if (accessTokenResponse != null) {
				var directResponseMessage = (IDirectResponseProtocolMessage)accessTokenResponse;
				var accessTokenRequest = (AccessTokenRequestBase)directResponseMessage.OriginatingRequest;
				ErrorUtilities.VerifyProtocol(accessTokenRequest.GrantType != GrantType.ClientCredentials || accessTokenResponse.RefreshToken == null, OAuthStrings.NoGrantNoRefreshToken);
			}

			return null;
		}
		/// <summary>
		/// Verifies the signature by unrecognized handle.
		/// </summary>
		/// <param name="message">The message.</param>
		/// <param name="signedMessage">The signed message.</param>
		/// <param name="protectionsApplied">The protections applied.</param>
		/// <returns>
		/// The applied protections.
		/// </returns>
		protected override MessageProtections VerifySignatureByUnrecognizedHandle(IProtocolMessage message, ITamperResistantOpenIdMessage signedMessage, MessageProtections protectionsApplied) {
			// We did not recognize the association the provider used to sign the message.
			// Ask the provider to check the signature then.
			var indirectSignedResponse = (IndirectSignedResponse)signedMessage;
			var checkSignatureRequest = new CheckAuthenticationRequest(indirectSignedResponse, this.Channel);
			var checkSignatureResponse = this.Channel.Request<CheckAuthenticationResponse>(checkSignatureRequest);
			if (!checkSignatureResponse.IsValid) {
				Logger.Bindings.Error("Provider reports signature verification failed.");
				throw new InvalidSignatureException(message);
			}

			// If the OP confirms that a handle should be invalidated as well, do that.
			if (!string.IsNullOrEmpty(checkSignatureResponse.InvalidateHandle)) {
				if (this.rpAssociations != null) {
					this.rpAssociations.RemoveAssociation(indirectSignedResponse.ProviderEndpoint, checkSignatureResponse.InvalidateHandle);
				}
			}

			// When we're in dumb mode we can't provide our own replay protection,
			// but for OpenID 2.0 Providers we can rely on them providing it as part
			// of signature verification.
			if (message.Version.Major >= 2) {
				protectionsApplied |= MessageProtections.ReplayProtection;
			}

			return protectionsApplied;
		}
		/// <summary>
		/// Queues a message for sending in the response stream.
		/// </summary>
		/// <param name="response">The message to send as a response.</param>
		/// <returns>
		/// The pending user agent redirect based message to be sent as an HttpResponse.
		/// </returns>
		/// <remarks>
		/// This method implements spec OAuth V1.0 section 5.3.
		/// </remarks>
		protected override OutgoingWebResponse PrepareDirectResponse(IProtocolMessage response) {
			var webResponse = new OutgoingWebResponse();
			ApplyMessageTemplate(response, webResponse);
			string json = this.SerializeAsJson(response);
			webResponse.SetResponse(json, new ContentType(JsonEncoded));
			return webResponse;
		}
Esempio n. 13
0
		/// <summary>
		/// Performs any transformation on an incoming message that may be necessary and/or
		/// validates an incoming message based on the rules of this channel binding element.
		/// </summary>
		/// <param name="message">The incoming message to process.</param>
		/// <returns>
		/// The protections (if any) that this binding element applied to the message.
		/// Null if this binding element did not even apply to this binding element.
		/// </returns>
		/// <exception cref="ProtocolException">
		/// Thrown when the binding element rules indicate that this message is invalid and should
		/// NOT be processed.
		/// </exception>
		public MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
			var signedMessage = message as ITamperResistantOpenIdMessage;
			if (signedMessage != null) {
				Logger.Bindings.DebugFormat("Verifying incoming {0} message signature of: {1}", message.GetType().Name, signedMessage.Signature);
				MessageProtections protectionsApplied = MessageProtections.TamperProtection;

				this.EnsureParametersRequiringSignatureAreSigned(signedMessage);

				Association association = this.GetSpecificAssociation(signedMessage);
				if (association != null) {
					string signature = this.GetSignature(signedMessage, association);
					if (!MessagingUtilities.EqualsConstantTime(signedMessage.Signature, signature)) {
						Logger.Bindings.Error("Signature verification failed.");
						throw new InvalidSignatureException(message);
					}
				} else {
					ErrorUtilities.VerifyInternal(this.Channel != null, "Cannot verify private association signature because we don't have a channel.");

					protectionsApplied = this.VerifySignatureByUnrecognizedHandle(message, signedMessage, protectionsApplied);
				}

				return protectionsApplied;
			}

			return null;
		}
		/// <summary>
		/// Prepares a message for sending based on the rules of this channel binding element.
		/// </summary>
		/// <param name="message">The message to prepare for sending.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <returns>
		/// The protections (if any) that this binding element applied to the message.
		/// Null if this binding element did not even apply to this binding element.
		/// </returns>
		/// <remarks>
		/// Implementations that provide message protection must honor the
		/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
		/// </remarks>
		public override Task<MessageProtections?> ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
			var directResponse = message as IDirectResponseProtocolMessage;
			var request = directResponse != null ? directResponse.OriginatingRequest as IAccessTokenRequestInternal : null;

			// Serialize the authorization code, if there is one.
			var authCodeCarrier = message as IAuthorizationCodeCarryingRequest;
			if (authCodeCarrier != null) {
				var codeFormatter = AuthorizationCode.CreateFormatter(this.AuthorizationServer);
				var code = authCodeCarrier.AuthorizationDescription;
				authCodeCarrier.Code = codeFormatter.Serialize(code);
				return MessageProtectionTasks.None;
			}

			// Serialize the refresh token, if applicable.
			var refreshTokenResponse = message as AccessTokenSuccessResponse;
			if (refreshTokenResponse != null && refreshTokenResponse.HasRefreshToken) {
				var refreshTokenCarrier = (IAuthorizationCarryingRequest)message;
				var refreshToken = new RefreshToken(refreshTokenCarrier.AuthorizationDescription);
				var refreshTokenFormatter = RefreshToken.CreateFormatter(this.AuthorizationServer.CryptoKeyStore);
				refreshTokenResponse.RefreshToken = refreshTokenFormatter.Serialize(refreshToken);
			}

			// Serialize the access token, if applicable.
			var accessTokenResponse = message as IAccessTokenIssuingResponse;
			if (accessTokenResponse != null && accessTokenResponse.AuthorizationDescription != null) {
				ErrorUtilities.VerifyInternal(request != null, "We should always have a direct request message for this case.");
				accessTokenResponse.AccessToken = accessTokenResponse.AuthorizationDescription.Serialize();
			}

			return MessageProtectionTasks.Null;
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="CoordinatingOutgoingWebResponse"/> class.
		/// </summary>
		/// <param name="message">The direct response message to send to the remote channel.  This message will be cloned.</param>
		/// <param name="receivingChannel">The receiving channel.</param>
		internal CoordinatingOutgoingWebResponse(IProtocolMessage message, CoordinatingChannel receivingChannel) {
			Requires.NotNull(message, "message");
			Requires.NotNull(receivingChannel, "receivingChannel");

			this.receivingChannel = receivingChannel;
			this.OriginalMessage = message;
		}
Esempio n. 16
0
		/// <summary>
		/// Verifies the integrity and applicability of an incoming message.
		/// </summary>
		/// <param name="message">The message just received.</param>
		/// <exception cref="ProtocolException">
		/// Thrown when the message is somehow invalid, except for check_authentication messages.
		/// This can be due to tampering, replay attack or expiration, among other things.
		/// </exception>
		protected override void ProcessIncomingMessage(IProtocolMessage message) {
			var checkAuthRequest = message as CheckAuthenticationRequest;
			if (checkAuthRequest != null) {
				IndirectSignedResponse originalResponse = new IndirectSignedResponse(checkAuthRequest, this);
				try {
					base.ProcessIncomingMessage(originalResponse);
					checkAuthRequest.IsValid = true;
				} catch (ProtocolException) {
					checkAuthRequest.IsValid = false;
				}
			} else {
				base.ProcessIncomingMessage(message);
			}

			// Convert an OpenID indirect error message, which we never expect
			// between two good OpenID implementations, into an exception.
			// We don't process DirectErrorResponse because associate negotiations
			// commonly get a derivative of that message type and handle it.
			var errorMessage = message as IndirectErrorResponse;
			if (errorMessage != null) {
				string exceptionMessage = string.Format(
					CultureInfo.CurrentCulture,
					OpenIdStrings.IndirectErrorFormattedMessage,
					errorMessage.ErrorMessage,
					errorMessage.Contact,
					errorMessage.Reference);
				throw new ProtocolException(exceptionMessage, message);
			}
		}
		/// <summary>
		/// Initializes a new instance of the <see cref="ProtocolFaultResponseException"/> class
		/// such that it can be sent as a protocol message response to a remote caller.
		/// </summary>
		/// <param name="channel">The channel to use when encoding the response message.</param>
		/// <param name="errorResponse">The message to send back to the HTTP client.</param>
		/// <param name="faultedMessage">The message that was the cause of the exception.  May be null.</param>
		/// <param name="innerException">The inner exception.</param>
		/// <param name="message">The message for the exception.</param>
		protected internal ProtocolFaultResponseException(Channel channel, IDirectResponseProtocolMessage errorResponse, IProtocolMessage faultedMessage = null, Exception innerException = null, string message = null)
			: base(message ?? (innerException != null ? innerException.Message : null), faultedMessage, innerException) {
			Requires.NotNull(channel, "channel");
			Requires.NotNull(errorResponse, "errorResponse");
			this.channel = channel;
			this.ErrorResponseMessage = errorResponse;
		}
        /// <summary>
        /// Initializes a new instance of the <see cref="AutoResponsiveRequest"/> class
        /// for a response to an unrecognizable request.
        /// </summary>
        /// <param name="response">The response that is ready for transmittal.</param>
        internal AutoResponsiveRequest(IProtocolMessage response)
            : base(IndirectResponseBase.GetVersion(response))
        {
            ErrorUtilities.VerifyArgumentNotNull(response, "response");

            this.response = response;
        }
		/// <summary>
		/// Retrieves an association given an association handle.
		/// </summary>
		/// <param name="containingMessage">The OpenID message that referenced this association handle.</param>
		/// <param name="isPrivateAssociation">A value indicating whether a private association is expected.</param>
		/// <param name="handle">The association handle.</param>
		/// <returns>
		/// An association instance, or <c>null</c> if the association has expired or the signature is incorrect (which may be because the OP's symmetric key has changed).
		/// </returns>
		/// <exception cref="ProtocolException">Thrown if the association is not of the expected type.</exception>
		public Association Deserialize(IProtocolMessage containingMessage, bool isPrivateAssociation, string handle) {
			var key = this.cryptoKeyStore.GetKey(isPrivateAssociation ? PrivateAssociationBucket : SharedAssociationBucket, handle);
			if (key != null) {
				return Association.Deserialize(handle, key.ExpiresUtc, key.Key);
			}

			return null;
		}
		Task<MessageProtections?> IChannelBindingElement.ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
			var signedMessage = message as ITamperResistantProtocolMessage;
			if (signedMessage != null) {
				signedMessage.Signature = MessageSignature;
				return MessageProtectionTasks.TamperProtection;
			}

			return MessageProtectionTasks.Null;
		}
		MessageProtections? IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message) {
			ITamperResistantProtocolMessage signedMessage = message as ITamperResistantProtocolMessage;
			if (signedMessage != null) {
				signedMessage.Signature = MessageSignature;
				return MessageProtections.TamperProtection;
			}

			return null;
		}
		Task<MessageProtections?> IChannelBindingElement.ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
			var replayMessage = message as IReplayProtectedProtocolMessage;
			if (replayMessage != null) {
				replayMessage.Nonce = "someNonce";
				return MessageProtectionTasks.ReplayProtection;
			}

			return MessageProtectionTasks.Null;
		}
		/// <summary>
		/// Sets the timestamp on an outgoing message.
		/// </summary>
		/// <param name="message">The outgoing message.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <returns>
		/// The protections (if any) that this binding element applied to the message.
		/// Null if this binding element did not even apply to this binding element.
		/// </returns>
		/// <remarks>
		/// Implementations that provide message protection must honor the
		/// <see cref="MessagePartAttribute.RequiredProtection" /> properties where applicable.
		/// </remarks>
		public Task<MessageProtections?> ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
			IExpiringProtocolMessage expiringMessage = message as IExpiringProtocolMessage;
			if (expiringMessage != null) {
				expiringMessage.UtcCreationDate = DateTime.UtcNow;
				return CompletedExpirationTask;
			}

			return NullTask;
		}
		/// <summary>
		/// Performs any transformation on an incoming message that may be necessary and/or
		/// validates an incoming message based on the rules of this channel binding element.
		/// </summary>
		/// <param name="message">The incoming message to process.</param>
		/// <returns>
		/// The protections (if any) that this binding element applied to the message.
		/// Null if this binding element did not even apply to this binding element.
		/// </returns>
		/// <exception cref="ProtocolException">
		/// Thrown when the binding element rules indicate that this message is invalid and should
		/// NOT be processed.
		/// </exception>
		/// <remarks>
		/// Implementations that provide message protection must honor the
		/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
		/// </remarks>
		public MessageProtections? ProcessIncomingMessage(IProtocolMessage message) {
			var signedMessage = message as ITamperResistantOpenIdMessage;
			if (signedMessage != null) {
				Logger.Bindings.DebugFormat("Skipped security checks of incoming {0} message for preview purposes.", message.GetType().Name);
				return this.Protection;
			}

			return null;
		}
		Task<MessageProtections?> IChannelBindingElement.ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
			var testMessage = message as TestMessage;
			if (testMessage != null) {
				testMessage.Name = this.transform + testMessage.Name;
				return MessageProtectionTasks.None;
			}

			return MessageProtectionTasks.Null;
		}
		MessageProtections? IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message) {
			var testMessage = message as TestMessage;
			if (testMessage != null) {
				testMessage.Name = this.transform + testMessage.Name;
				return MessageProtections.None;
			}

			return null;
		}
		/// <summary>
		/// Sets the timestamp on an outgoing message.
		/// </summary>
		/// <param name="message">The outgoing message.</param>
		/// <returns>
		/// The protections (if any) that this binding element applied to the message.
		/// Null if this binding element did not even apply to this binding element.
		/// </returns>
		public MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
			IExpiringProtocolMessage expiringMessage = message as IExpiringProtocolMessage;
			if (expiringMessage != null) {
				expiringMessage.UtcCreationDate = DateTime.UtcNow;
				return MessageProtections.Expiration;
			}

			return null;
		}
		/// <summary>
		/// Performs any transformation on an incoming message that may be necessary and/or
		/// validates an incoming message based on the rules of this channel binding element.
		/// </summary>
		/// <param name="message">The incoming message to process.</param>
		/// <param name="cancellationToken">The cancellation token.</param>
		/// <returns>
		/// The protections (if any) that this binding element applied to the message.
		/// Null if this binding element did not even apply to this binding element.
		/// </returns>
		/// <exception cref="ProtocolException">
		/// Thrown when the binding element rules indicate that this message is invalid and should
		/// NOT be processed.
		/// </exception>
		/// <remarks>
		/// Implementations that provide message protection must honor the
		/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
		/// </remarks>
		public Task<MessageProtections?> ProcessIncomingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken) {
			var signedMessage = message as ITamperResistantOpenIdMessage;
			if (signedMessage != null) {
				Logger.Bindings.DebugFormat("Skipped security checks of incoming {0} message for preview purposes.", message.GetType().Name);
				return Task.FromResult<MessageProtections?>(this.Protection);
			}

			return NullTask;
		}
		MessageProtections? IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message) {
			var replayMessage = message as IReplayProtectedProtocolMessage;
			if (replayMessage != null) {
				replayMessage.Nonce = "someNonce";
				return MessageProtections.ReplayProtection;
			}

			return null;
		}
		/// <summary>
		/// Prepares a message for sending based on the rules of this channel binding element.
		/// </summary>
		/// <param name="message">The message to prepare for sending.</param>
		/// <returns>
		/// The protections (if any) that this binding element applied to the message.
		/// Null if this binding element did not even apply to this binding element.
		/// </returns>
		/// <remarks>
		/// Implementations that provide message protection must honor the
		/// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
		/// </remarks>
		public override MessageProtections? ProcessOutgoingMessage(IProtocolMessage message) {
			var accessTokenResponse = message as AccessTokenSuccessResponse;
			if (accessTokenResponse != null) {
				var directResponseMessage = (IDirectResponseProtocolMessage)accessTokenResponse;
				var accessTokenRequest = (AccessTokenRequestBase)directResponseMessage.OriginatingRequest;
				ErrorUtilities.VerifyProtocol(accessTokenRequest.GrantType != GrantType.ClientCredentials || accessTokenResponse.RefreshToken == null, OAuthStrings.NoGrantNoRefreshToken);
			}

			return null;
		}
Esempio n. 31
0
        /// <summary>
        /// Performs any transformation on an incoming message that may be necessary and/or
        /// validates an incoming message based on the rules of this channel binding element.
        /// </summary>
        /// <param name="message">The incoming message to process.</param>
        /// <returns>
        /// The protections (if any) that this binding element applied to the message.
        /// Null if this binding element did not even apply to this binding element.
        /// </returns>
        /// <exception cref="ProtocolException">
        /// Thrown when the binding element rules indicate that this message is invalid and should
        /// NOT be processed.
        /// </exception>
        /// <remarks>
        /// Implementations that provide message protection must honor the
        /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
        /// </remarks>
        public MessageProtections?ProcessIncomingMessage(IProtocolMessage message)
        {
            var signedMessage = message as ITamperResistantOpenIdMessage;

            if (signedMessage != null)
            {
                Logger.Bindings.DebugFormat("Skipped security checks of incoming {0} message for preview purposes.", message.GetType().Name);
                return(this.Protection);
            }

            return(null);
        }
Esempio n. 32
0
        internal OutgoingWebResponse RequestProtectedResource(AccessProtectedResourceRequest request)
        {
            ((ITamperResistantOAuthMessage)request).HttpMethod = this.GetHttpMethod(((ITamperResistantOAuthMessage)request).HttpMethods);
            this.ProcessOutgoingMessage(request);
            HttpRequestInfo requestInfo = this.SpoofHttpMethod(request);

            TestBase.TestLogger.InfoFormat("Sending protected resource request: {0}", requestInfo.Message);
            // Drop the outgoing message in the other channel's in-slot and let them know it's there.
            this.RemoteChannel.incomingMessage = requestInfo.Message;
            this.RemoteChannel.incomingMessageSignal.Set();
            return(this.AwaitIncomingRawResponse());
        }
        MessageProtections?IChannelBindingElement.ProcessOutgoingMessage(IProtocolMessage message)
        {
            var replayMessage = message as IReplayProtectedProtocolMessage;

            if (replayMessage != null)
            {
                replayMessage.Nonce = "someNonce";
                return(MessageProtections.ReplayProtection);
            }

            return(null);
        }
Esempio n. 34
0
        public async Task <HttpResponseMessage> PrepareResponseAsync_CCP(IProtocolMessage message, CancellationToken cancellationToken = default(CancellationToken))
        {
            Requires.NotNull(message, "message");

            await this.ProcessOutgoingMessageAsync_CCP(message, cancellationToken);

            HttpResponseMessage result;
            var directedMessage = message as IDirectedProtocolMessage;

            result = this.PrepareIndirectResponse(directedMessage);
            return(result);
        }
Esempio n. 35
0
        /// <summary>
        /// Performs any transformation on an incoming message that may be necessary and/or
        /// validates an incoming message based on the rules of this channel binding element.
        /// </summary>
        /// <param name="message">The incoming message to process.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// The protections (if any) that this binding element applied to the message.
        /// Null if this binding element did not even apply to this binding element.
        /// </returns>
        /// <exception cref="ProtocolException">
        /// Thrown when the binding element rules indicate that this message is invalid and should
        /// NOT be processed.
        /// </exception>
        /// <remarks>
        /// Implementations that provide message protection must honor the
        /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
        /// </remarks>
        public Task <MessageProtections?> ProcessIncomingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken)
        {
            var signedMessage = message as ITamperResistantOpenIdMessage;

            if (signedMessage != null)
            {
                Logger.Bindings.DebugFormat("Skipped security checks of incoming {0} message for preview purposes.", message.GetType().Name);
                return(Task.FromResult <MessageProtections?>(this.Protection));
            }

            return(NullTask);
        }
Esempio n. 36
0
        /// <summary>
        /// Queues a message for sending in the response stream where the fields
        /// are sent in the response stream in querystring style.
        /// </summary>
        /// <param name="response">The message to send as a response.</param>
        /// <returns>The pending user agent redirect based message to be sent as an HttpResponse.</returns>
        /// <remarks>
        /// This method implements spec V1.0 section 5.3.
        /// </remarks>
        protected override HttpResponseMessage PrepareDirectResponse(IProtocolMessage response)
        {
            var messageAccessor = this.MessageDescriptions.GetAccessor(response);
            var fields          = messageAccessor.Serialize();

            var encodedResponse = new HttpResponseMessage {
                Content = new FormUrlEncodedContent(fields),
            };

            ApplyMessageTemplate(response, encodedResponse);
            return(encodedResponse);
        }
        /// <summary>
        /// Applies a nonce to the message.
        /// </summary>
        /// <param name="message">The message to apply replay protection to.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// The protections (if any) that this binding element applied to the message.
        /// Null if this binding element did not even apply to this binding element.
        /// </returns>
        public Task <MessageProtections?> ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken)
        {
            IReplayProtectedProtocolMessage nonceMessage = message as IReplayProtectedProtocolMessage;

            if (nonceMessage != null)
            {
                nonceMessage.Nonce = this.GenerateUniqueFragment();
                return(CompletedReplayProtectionTask);
            }

            return(NullTask);
        }
        /// <summary>
        /// Reads messages from the client stream and processes them in a loop until the client disconnects
        /// or until an action (such as a protocol violation) that leads to disconnecting of the client occurs.
        /// </summary>
        public async Task ReceiveMessageLoop()
        {
            log.Trace("()");

            try
            {
                if (UseTls)
                {
                    SslStream  sslStream = (SslStream)Stream;
                    ConfigBase config    = (ConfigBase)Base.ComponentDictionary[ConfigBase.ComponentName];
                    await sslStream.AuthenticateAsServerAsync((X509Certificate)config.Settings["TcpServerTlsCertificate"], false, SslProtocols.Tls12, false);
                }

                RawMessageReader messageReader = new RawMessageReader(Stream);
                while (!shutdownSignaling.IsShutdown)
                {
                    RawMessageResult rawMessage = await messageReader.ReceiveMessageAsync(shutdownSignaling.ShutdownCancellationTokenSource.Token);

                    bool disconnect        = rawMessage.Data == null;
                    bool protocolViolation = rawMessage.ProtocolViolation;
                    if (rawMessage.Data != null)
                    {
                        IProtocolMessage message = CreateMessageFromRawData(rawMessage.Data);
                        if (message != null)
                        {
                            disconnect = !await messageProcessor.ProcessMessageAsync(this, message);
                        }
                        else
                        {
                            protocolViolation = true;
                        }
                    }

                    if (protocolViolation)
                    {
                        await messageProcessor.SendProtocolViolation(this);

                        break;
                    }

                    if (disconnect)
                    {
                        break;
                    }
                }
            }
            catch (Exception e)
            {
                log.Error("Exception occurred: {0}", e.ToString());
            }

            log.Trace("(-)");
        }
        /// <summary>
        /// Performs any transformation on an incoming message that may be necessary and/or
        /// validates an incoming message based on the rules of this channel binding element.
        /// </summary>
        /// <param name="message">The incoming message to process.</param>
        /// <returns>
        /// True if the <paramref name="message"/> applied to this binding element
        /// and the operation was successful.  False if the operation did not apply to this message.
        /// </returns>
        public bool PrepareMessageForReceiving(IProtocolMessage message)
        {
            foreach (IChannelBindingElement signer in this.signers)
            {
                if (signer.PrepareMessageForReceiving(message))
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 40
0
        /// <summary>
        /// Verifies the integrity and applicability of an incoming message.
        /// </summary>
        /// <param name="message">The message just received.</param>
        /// <exception cref="ProtocolException">
        /// Thrown when the message is somehow invalid.
        /// This can be due to tampering, replay attack or expiration, among other things.
        /// </exception>
        protected virtual void VerifyMessageAfterReceiving(IProtocolMessage message)
        {
            Debug.Assert(message != null, "message == null");

            if (Logger.IsDebugEnabled)
            {
                Logger.DebugFormat(
                    "Preparing to receive {0} ({1}) message:{2}{3}",
                    message.GetType().Name,
                    message.Version,
                    Environment.NewLine,
                    new MessageDictionary(message).ToStringDeferred());
            }

            MessageProtections appliedProtection = MessageProtections.None;

            foreach (IChannelBindingElement bindingElement in this.incomingBindingElements)
            {
                if (bindingElement.PrepareMessageForReceiving(message))
                {
                    Logger.DebugFormat("Binding element {0} applied to message.", bindingElement.GetType().FullName);

                    // Ensure that only one protection binding element applies to this message
                    // for each protection type.
                    ErrorUtilities.VerifyInternal((appliedProtection & bindingElement.Protection) == 0, MessagingStrings.TooManyBindingsOfferingSameProtection, bindingElement.Protection);
                    appliedProtection |= bindingElement.Protection;
                }
                else
                {
                    Logger.DebugFormat("Binding element {0} did not apply to message.", bindingElement.GetType().FullName);
                }
            }

            // Ensure that the message's protection requirements have been satisfied.
            if ((message.RequiredProtection & appliedProtection) != message.RequiredProtection)
            {
                throw new UnprotectedMessageException(message, appliedProtection);
            }

            // Give the message a chance to do custom serialization.
            IMessageWithEvents eventedMessage = message as IMessageWithEvents;

            if (eventedMessage != null)
            {
                eventedMessage.OnReceiving();
            }

            // We do NOT verify that all required message parts are present here... the
            // message deserializer did for us.  It would be too late to do it here since
            // they might look initialized by the time we have an IProtocolMessage instance.
            message.EnsureValidMessage();
        }
Esempio n. 41
0
        /// <summary>
        /// Prepares a message for sending based on the rules of this channel binding element.
        /// </summary>
        /// <param name="message">The message to prepare for sending.</param>
        /// <returns>
        /// The protections (if any) that this binding element applied to the message.
        /// Null if this binding element did not even apply to this binding element.
        /// </returns>
        /// <remarks>
        /// Implementations that provide message protection must honor the
        /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
        /// </remarks>
        public override MessageProtections?ProcessOutgoingMessage(IProtocolMessage message)
        {
            var accessTokenResponse = message as AccessTokenSuccessResponse;

            if (accessTokenResponse != null)
            {
                var directResponseMessage = (IDirectResponseProtocolMessage)accessTokenResponse;
                var accessTokenRequest    = (AccessTokenRequestBase)directResponseMessage.OriginatingRequest;
                ErrorUtilities.VerifyProtocol(accessTokenRequest.GrantType != GrantType.ClientCredentials || accessTokenResponse.RefreshToken == null, OAuthStrings.NoGrantNoRefreshToken);
            }

            return(null);
        }
    /// <summary>
    /// Handle an incoming protocol message by sending back an error message
    /// indicating that a message of this type is not allowed at this point in
    /// the conversation.
    /// </summary>
    void ProtocolViolationMessage(IProtocolMessage message,
                                  string reason = null, params object[] args)
    {
        SendError(reason == null,
                  9999,
                  "Received unexpected message with id={0}; protocol violation",
                  message.MsgID);

        if (reason != null)
        {
            SendError(true, 9999, reason, args);
        }
    }
Esempio n. 43
0
        MessageProtections?IChannelBindingElement.ProcessIncomingMessage(IProtocolMessage message)
        {
            var testMessage = message as TestMessage;

            if (testMessage != null)
            {
                StringAssert.StartsWith(this.transform, testMessage.Name);
                testMessage.Name = testMessage.Name.Substring(this.transform.Length);
                return(MessageProtections.None);
            }

            return(null);
        }
Esempio n. 44
0
        public TResponse Request <TResponse>(IDirectedProtocolMessage requestMessage)
            where TResponse : class, IProtocolMessage
        {
            IProtocolMessage response = this.Request(requestMessage);

            ErrorUtilities.VerifyProtocol(response != null, MessagingStrings.ExpectedMessageNotReceived, typeof(TResponse));

            var expectedResponse = response as TResponse;

            ErrorUtilities.VerifyProtocol(expectedResponse != null, MessagingStrings.UnexpectedMessageReceived, typeof(TResponse), response.GetType());

            return(expectedResponse);
        }
Esempio n. 45
0
        public IDirectedProtocolMessage ReadFromRequestAsync1_ccp(IProtocolMessage message, CancellationToken cancellationToken)
        {
            IDirectedProtocolMessage requestMessage = (IDirectedProtocolMessage)message;


            if (requestMessage != null)
            {
                this.ProcessIncomingMessageAsync1_ccp(requestMessage, cancellationToken);
            }


            return(requestMessage);
        }
Esempio n. 46
0
        public void ReadFromRequestWithContext()
        {
            var         fields          = GetStandardTestFields(FieldFill.AllRequired);
            TestMessage expectedMessage = GetStandardTestMessage(FieldFill.AllRequired);
            HttpRequest request         = new HttpRequest("somefile", "http://someurl", MessagingUtilities.CreateQueryString(fields));

            HttpContext.Current = new HttpContext(request, new HttpResponse(new StringWriter()));
            IProtocolMessage message = this.Channel.ReadFromRequest();

            Assert.IsNotNull(message);
            Assert.IsInstanceOf <TestMessage>(message);
            Assert.AreEqual(expectedMessage.Age, ((TestMessage)message).Age);
        }
Esempio n. 47
0
        /// <summary>
        /// Prepares a message for sending based on the rules of this channel binding element.
        /// </summary>
        /// <param name="message">The message to prepare for sending.</param>
        /// <returns>
        /// True if the <paramref name="message"/> applied to this binding element
        /// and the operation was successful.  False otherwise.
        /// </returns>
        /// <remarks>
        /// Implementations that provide message protection must honor the
        /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
        /// </remarks>
        public bool PrepareMessageForSending(IProtocolMessage message)
        {
            SignedResponseRequest request = message as SignedResponseRequest;

            if (request != null)
            {
                request.AddReturnToArguments(ReturnToSignatureHandleParameterName, this.secretManager.CurrentHandle);
                request.AddReturnToArguments(ReturnToSignatureParameterName, this.GetReturnToSignature(request.ReturnTo));
                return(true);
            }

            return(false);
        }
        /// <summary>
        /// Prepares a message for sending based on the rules of this channel binding element.
        /// </summary>
        /// <param name="message">The message to prepare for sending.</param>
        /// <returns>
        /// True if the <paramref name="message"/> applied to this binding element
        /// and the operation was successful.  False otherwise.
        /// </returns>
        /// <remarks>
        /// Implementations that provide message protection must honor the
        /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
        /// </remarks>
        public bool PrepareMessageForSending(IProtocolMessage message)
        {
            ErrorUtilities.VerifyArgumentNotNull(message, "message");

            var extendableMessage = message as IProtocolMessageWithExtensions;

            if (extendableMessage != null)
            {
                Protocol          protocol = Protocol.Lookup(message.Version);
                MessageDictionary baseMessageDictionary = new MessageDictionary(message);

                // We have a helper class that will do all the heavy-lifting of organizing
                // all the extensions, their aliases, and their parameters.
                var extensionManager = ExtensionArgumentsManager.CreateOutgoingExtensions(protocol);
                foreach (IExtensionMessage protocolExtension in extendableMessage.Extensions)
                {
                    var extension = protocolExtension as IOpenIdMessageExtension;
                    if (extension != null)
                    {
                        // Give extensions that require custom serialization a chance to do their work.
                        var customSerializingExtension = extension as IMessageWithEvents;
                        if (customSerializingExtension != null)
                        {
                            customSerializingExtension.OnSending();
                        }

                        // OpenID 2.0 Section 12 forbids two extensions with the same TypeURI in the same message.
                        ErrorUtilities.VerifyProtocol(!extensionManager.ContainsExtension(extension.TypeUri), OpenIdStrings.ExtensionAlreadyAddedWithSameTypeURI, extension.TypeUri);

                        var extensionDictionary = MessageSerializer.Get(extension.GetType()).Serialize(extension);
                        extensionManager.AddExtensionArguments(extension.TypeUri, extensionDictionary);
                    }
                    else
                    {
                        Logger.WarnFormat("Unexpected extension type {0} did not implement {1}.", protocolExtension.GetType(), typeof(IOpenIdMessageExtension).Name);
                    }
                }

                // We use a cheap trick (for now at least) to determine whether the 'openid.' prefix
                // belongs on the parameters by just looking at what other parameters do.
                // Technically, direct message responses from Provider to Relying Party are the only
                // messages that leave off the 'openid.' prefix.
                bool includeOpenIdPrefix = baseMessageDictionary.Keys.Any(key => key.StartsWith(protocol.openid.Prefix, StringComparison.Ordinal));

                // Add the extension parameters to the base message for transmission.
                extendableMessage.AddExtraParameters(extensionManager.GetArgumentsToSend(includeOpenIdPrefix));
                return(true);
            }

            return(false);
        }
Esempio n. 49
0
        protected void ProcessOutgoingMessageAsync(IProtocolMessage message, CancellationToken cancellationToken)
        {
            Logger.Channel.DebugFormat("Preparing to send {0} ({1}) message.", message.GetType().Name, message.Version);
            this.OnSending(message);
            IMessageWithEvents eventedMessage = message as IMessageWithEvents;

            if (eventedMessage != null)
            {
                eventedMessage.OnSending();
            }
            MessageProtections appliedProtection = MessageProtections.None;

            foreach (IChannelBindingElement bindingElement in this.outgoingBindingElements)
            {
                Assumes.True(bindingElement.Channel != null);
                MessageProtections?elementProtection = bindingElement.ProcessOutgoingMessageAsync(message, cancellationToken);
                if (elementProtection.HasValue)
                {
                    Logger.Bindings.DebugFormat("Binding element {0} applied to message.", bindingElement.GetType().FullName);
                    ErrorUtilities.VerifyProtocol((appliedProtection & elementProtection.Value) == 0, MessagingStrings.TooManyBindingsOfferingSameProtection, elementProtection.Value);
                    appliedProtection |= elementProtection.Value;
                }
                else
                {
                    Logger.Bindings.DebugFormat("Binding element {0} did not apply to message.", bindingElement.GetType().FullName);
                }
            }
            if ((message.RequiredProtection & appliedProtection) != message.RequiredProtection)
            {
                throw new UnprotectedMessageException(message, appliedProtection);
            }
            this.EnsureValidMessageParts(message);
            message.EnsureValidMessage();
            if (this.OutgoingMessageFilter != null)
            {
                this.OutgoingMessageFilter(message);
            }
            if (Logger.Channel.IsInfoEnabled()) // 日志
            {
                var    directedMessage = message as IDirectedProtocolMessage;
                string recipient       = (directedMessage != null && directedMessage.Recipient != null) ? directedMessage.Recipient.AbsoluteUri : "<response>";
                var    messageAccessor = this.MessageDescriptions.GetAccessor(message);
                Logger.Channel.InfoFormat(
                    "Prepared outgoing {0} ({1}) message for {2}: {3}{4}",
                    message.GetType().Name,
                    message.Version,
                    recipient,
                    Environment.NewLine,
                    messageAccessor.ToStringDeferred());
            }
        }
        /// <summary>
        /// Performs any transformation on an incoming message that may be necessary and/or
        /// validates an incoming message based on the rules of this channel binding element.
        /// </summary>
        /// <param name="message">The incoming message to process.</param>
        /// <returns>
        /// True if the <paramref name="message"/> applied to this binding element
        /// and the operation was successful.  False if the operation did not apply to this message.
        /// </returns>
        /// <exception cref="ProtocolException">
        /// Thrown when the binding element rules indicate that this message is invalid and should
        /// NOT be processed.
        /// </exception>
        public bool PrepareMessageForReceiving(IProtocolMessage message)
        {
            var signedMessage = message as ITamperResistantOpenIdMessage;

            if (signedMessage != null)
            {
                Logger.DebugFormat("Verifying incoming {0} message signature of: {1}", message.GetType().Name, signedMessage.Signature);

                EnsureParametersRequiringSignatureAreSigned(signedMessage);

                Association association = this.GetSpecificAssociation(signedMessage);
                if (association != null)
                {
                    string signature = GetSignature(signedMessage, association);
                    if (!string.Equals(signedMessage.Signature, signature, StringComparison.Ordinal))
                    {
                        Logger.Error("Signature verification failed.");
                        throw new InvalidSignatureException(message);
                    }
                }
                else
                {
                    ErrorUtilities.VerifyInternal(this.Channel != null, "Cannot verify private association signature because we don't have a channel.");

                    // We did not recognize the association the provider used to sign the message.
                    // Ask the provider to check the signature then.
                    var indirectSignedResponse = (IndirectSignedResponse)signedMessage;
                    var checkSignatureRequest  = new CheckAuthenticationRequest(indirectSignedResponse);
                    var checkSignatureResponse = this.Channel.Request <CheckAuthenticationResponse>(checkSignatureRequest);
                    if (!checkSignatureResponse.IsValid)
                    {
                        Logger.Error("Provider reports signature verification failed.");
                        throw new InvalidSignatureException(message);
                    }

                    // If the OP confirms that a handle should be invalidated as well, do that.
                    if (!string.IsNullOrEmpty(checkSignatureResponse.InvalidateHandle))
                    {
                        if (this.rpAssociations != null)
                        {
                            this.rpAssociations.RemoveAssociation(indirectSignedResponse.ProviderEndpoint, checkSignatureResponse.InvalidateHandle);
                        }
                    }
                }

                return(true);
            }

            return(false);
        }
Esempio n. 51
0
        /// <summary>
        /// Prepares a message for sending based on the rules of this channel binding element.
        /// </summary>
        /// <param name="message">The message to prepare for sending.</param>
        /// <returns>
        /// True if the <paramref name="message"/> applied to this binding element
        /// and the operation was successful.  False otherwise.
        /// </returns>
        /// <remarks>
        /// Implementations that provide message protection must honor the
        /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
        /// </remarks>
        public bool PrepareMessageForSending(IProtocolMessage message)
        {
            // We only add a nonce to 1.x auth requests.
            SignedResponseRequest request = message as SignedResponseRequest;

            if (request != null && request.Version.Major < 2)
            {
                request.AddReturnToArguments(NonceParameter, CustomNonce.NewNonce().Serialize());

                return(true);
            }

            return(false);
        }
Esempio n. 52
0
        /// <summary>
        /// Prepares a message for sending based on the rules of this channel binding element.
        /// </summary>
        /// <param name="message">The message to prepare for sending.</param>
        /// <returns>
        /// The protections (if any) that this binding element applied to the message.
        /// Null if this binding element did not even apply to this binding element.
        /// </returns>
        public MessageProtections?ProcessOutgoingMessage(IProtocolMessage message)
        {
            foreach (IChannelBindingElement signer in this.signers)
            {
                ErrorUtilities.VerifyInternal(signer.Channel != null, "A binding element's Channel property is unexpectedly null.");
                MessageProtections?result = signer.ProcessOutgoingMessage(message);
                if (result.HasValue)
                {
                    return(result);
                }
            }

            return(null);
        }
Esempio n. 53
0
        public void ProcessRequest(HttpContext context)
        {
            IProtocolMessage         request      = m_Provider.ReadRequest();
            UnauthorizedTokenRequest requestToken = null;
            UserAuthorizationRequest requestAuth  = null;
            AuthorizedTokenRequest   requestAccessToken;

            if ((requestToken = request as UnauthorizedTokenRequest) != null)
            {
                UnauthorizedTokenResponse response = m_Provider.PrepareUnauthorizedTokenMessage(requestToken);
                m_Provider.Channel.Send(response);
            }
            else if ((requestAuth = request as UserAuthorizationRequest) != null)
            {
                string token = ((ITokenContainingMessage)requestAuth).Token;

                ((TokenProvider)m_Provider.TokenManager).UpdatePendingUserAuthorizationRequest(token, requestAuth);

                TokenProvider.SetTokenCookie(token);

                if (context == null)
                {
                    throw new ArgumentNullException("context");
                }

                context.Response.Redirect(ActionProvider.FindAction(ActionProvider.OAuthPageActionId).AbsoluteNavigateUrl);
            }
            else if ((requestAccessToken = request as AuthorizedTokenRequest) != null)
            {
                AuthorizedTokenResponse response = m_Provider.PrepareAccessTokenMessage(requestAccessToken);

                OAuthDataSet.OAuthTokenRow row = (OAuthDataSet.OAuthTokenRow)m_Provider.TokenManager.GetAccessToken(response.AccessToken);
                response.ExtraData.Add(new KeyValuePair <string, string>("api_token", LoginProvider.Current.GetToken(row.LoginId)));

                if (!row.IsOrganizationIdNull())
                {
                    response.ExtraData.Add(new KeyValuePair <string, string>("org", OrganizationProvider.GetOrganization(row.OrganizationId).PseudoId));
                    if (!row.IsInstanceIdNull())
                    {
                        response.ExtraData.Add(new KeyValuePair <string, string>("dept", InstanceProvider.GetInstance(row.InstanceId, row.OrganizationId).PseudoId));
                    }
                }

                m_Provider.Channel.Send(response);
            }
            else
            {
                throw new InvalidOperationException();
            }
        }
Esempio n. 54
0
        public void SendDirectMessageResponseHonorsHttpStatusCodes()
        {
            IProtocolMessage message = MessagingTestBase.GetStandardTestMessage(MessagingTestBase.FieldFill.AllRequired);
            var directResponse       = this.channel.PrepareDirectResponseTestHook(message);

            Assert.AreEqual(HttpStatusCode.OK, directResponse.StatusCode);

            var httpMessage = new TestDirectResponseMessageWithHttpStatus();

            MessagingTestBase.GetStandardTestMessage(MessagingTestBase.FieldFill.AllRequired, httpMessage);
            httpMessage.HttpStatusCode = HttpStatusCode.NotAcceptable;
            directResponse             = this.channel.PrepareDirectResponseTestHook(httpMessage);
            Assert.AreEqual(HttpStatusCode.NotAcceptable, directResponse.StatusCode);
        }
Esempio n. 55
0
        public static byte[] SerializeMessage(IProtocolMessage message)
        {
            var be = Binary.BigEndian;

            switch (message)
            {
            case ISelfSerialize selfSerialize:
                return(selfSerialize.ToByteArray());

            case KeepAlive:
                return(new byte[4] {
                    0, 0, 0, 0
                });

            case Choke:
                return(new byte[5] {
                    0, 0, 0, 1, 0
                });

            case Unchoke:
                return(new byte[5] {
                    0, 0, 0, 1, 1
                });

            case Interested:
                return(new byte[5] {
                    0, 0, 0, 1, 2
                });

            case NotInterested:
                return(new byte[5] {
                    0, 0, 0, 1, 3
                });

            case Have have:
                return(new byte[] { 0, 0, 0, 5, 4 }
                       .Concat(be.GetBytes(have.PieceIndex))
                       .ToArray());

            case Bitfield bitfield:
                return(be.GetBytes(bitfield.Bits.Length + 1)
                       .Concat(new byte[] { 5 })
                       .Concat(bitfield.Bits)
                       .ToArray());

            default:
                throw new NotImplementedException($"No serialization implemented for protocol message type {message.GetType()}");
            }
        }
Esempio n. 56
0
        /// <summary>
        /// Prepares a message for sending based on the rules of this channel binding element.
        /// </summary>
        /// <param name="message">The message to prepare for sending.</param>
        /// <returns>
        /// The protections (if any) that this binding element applied to the message.
        /// Null if this binding element did not even apply to this binding element.
        /// </returns>
        /// <remarks>
        /// Implementations that provide message protection must honor the
        /// <see cref="MessagePartAttribute.RequiredProtection"/> properties where applicable.
        /// </remarks>
        public MessageProtections?ProcessOutgoingMessage(IProtocolMessage message)
        {
            // We only add a nonce to some auth requests.
            SignedResponseRequest request = message as SignedResponseRequest;

            if (this.UseRequestNonce(request))
            {
                request.AddReturnToArguments(NonceParameter, CustomNonce.NewNonce().Serialize());
                request.SignReturnTo = true;                 // a nonce without a signature is completely pointless

                return(MessageProtections.ReplayProtection);
            }

            return(null);
        }
        /// <summary>
        /// Gets the dictionary of message parts that should be deserialized into extensions.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="ignoreUnsigned">If set to <c>true</c> only signed extensions will be available.</param>
        /// <returns>
        /// A dictionary of message parts, including only signed parts when appropriate.
        /// </returns>
        private IDictionary <string, string> GetExtensionsDictionary(IProtocolMessage message, bool ignoreUnsigned)
        {
            RequiresEx.ValidState(this.Channel != null);

            IndirectSignedResponse signedResponse = message as IndirectSignedResponse;

            if (signedResponse != null && ignoreUnsigned)
            {
                return(signedResponse.GetSignedMessageParts(this.Channel));
            }
            else
            {
                return(this.Channel.MessageDescriptions.GetAccessor(message));
            }
        }
Esempio n. 58
0
        /// <summary>
        /// 读取httpRequest信息转换为TRequest
        /// </summary>
        /// <typeparam name="TRequest"></typeparam>
        /// <param name="httpRequest"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public TRequest TryReadFromRequestAsync <TRequest>(HttpRequestMessage httpRequest, CancellationToken cancellationToken)
            where TRequest : class, IProtocolMessage
        {
            IProtocolMessage untypeRequest = this.ReadFromRequestAsync(httpRequest, cancellationToken);

            if (untypeRequest == null)
            {
                return(null);
            }
            var request = untypeRequest as TRequest;

            ErrorUtilities.VerifyProtocol(request != null, MessagingStrings.UnexpectedMessageReceived, typeof(TRequest), untypeRequest.GetType());

            return(request);
        }
Esempio n. 59
0
        public async Task DirectResponsesSentUsingKeyValueForm()
        {
            IProtocolMessage  message       = MessagingTestBase.GetStandardTestMessage(MessagingTestBase.FieldFill.AllRequired);
            MessageDictionary messageFields = this.MessageDescriptions.GetAccessor(message);

            byte[] expectedBytes       = KeyValueFormEncoding.GetBytes(messageFields);
            string expectedContentType = OpenIdChannel.KeyValueFormContentType;

            var directResponse = this.channel.PrepareDirectResponseTestHook(message);

            Assert.AreEqual(expectedContentType, directResponse.Content.Headers.ContentType.MediaType);
            byte[] actualBytes = await directResponse.Content.ReadAsByteArrayAsync();

            Assert.IsTrue(MessagingUtilities.AreEquivalent(expectedBytes, actualBytes));
        }
Esempio n. 60
0
        MessageProtections?IChannelBindingElement.ProcessIncomingMessage(IProtocolMessage message)
        {
            ITamperResistantProtocolMessage signedMessage = message as ITamperResistantProtocolMessage;

            if (signedMessage != null)
            {
                if (signedMessage.Signature != MessageSignature)
                {
                    throw new InvalidSignatureException(message);
                }
                return(MessageProtections.TamperProtection);
            }

            return(null);
        }