summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2009-04-10 19:31:58 -0700
committerAndrew Arnott <andrewarnott@gmail.com>2009-04-10 19:31:58 -0700
commitc550dae3f973b551ab4988b20768eefa967bbce4 (patch)
tree32791a2857df2d587e914d50873b2f899063a105
parent82781e309db03f8afd09629f2b1bbce10fa355c5 (diff)
downloadDotNetOpenAuth-c550dae3f973b551ab4988b20768eefa967bbce4.zip
DotNetOpenAuth-c550dae3f973b551ab4988b20768eefa967bbce4.tar.gz
DotNetOpenAuth-c550dae3f973b551ab4988b20768eefa967bbce4.tar.bz2
Fixed OpenIdAjaxTextBox extension passing to Javascript.
The underlying problem was that we were not actually using a non-verifying OpenID channel as we thought we were, and this is a requirement. Fixes Google Code issue 236.
-rw-r--r--src/DotNetOpenAuth/DotNetOpenAuth.csproj1
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs45
-rw-r--r--src/DotNetOpenAuth/OpenId/ChannelElements/SkipSecurityBindingElement.cs87
-rw-r--r--src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs2
4 files changed, 123 insertions, 12 deletions
diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
index 75abc40..a15b3a8 100644
--- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj
+++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj
@@ -314,6 +314,7 @@
<Compile Include="OpenId\ChannelElements\OpenIdChannel.cs" />
<Compile Include="OpenId\ChannelElements\OpenIdMessageFactory.cs" />
<Compile Include="OpenId\ChannelElements\ReturnToSignatureBindingElement.cs" />
+ <Compile Include="OpenId\ChannelElements\SkipSecurityBindingElement.cs" />
<Compile Include="OpenId\Extensions\AliasManager.cs" />
<Compile Include="OpenId\Extensions\AttributeExchange\AttributeRequest.cs" />
<Compile Include="OpenId\Extensions\AttributeExchange\AttributeValues.cs" />
diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs
index f89ac73..d1c5db4 100644
--- a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs
+++ b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs
@@ -49,7 +49,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="nonceStore">The nonce store to use.</param>
/// <param name="securitySettings">The security settings to apply.</param>
internal OpenIdChannel(IAssociationStore<Uri> associationStore, INonceStore nonceStore, RelyingPartySecuritySettings securitySettings)
- : this(associationStore, nonceStore, new OpenIdMessageFactory(), securitySettings) {
+ : this(associationStore, nonceStore, new OpenIdMessageFactory(), securitySettings, false) {
Contract.Requires(securitySettings != null);
}
@@ -73,8 +73,9 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="nonceStore">The nonce store to use.</param>
/// <param name="messageTypeProvider">An object that knows how to distinguish the various OpenID message types for deserialization purposes.</param>
/// <param name="securitySettings">The security settings to apply.</param>
- private OpenIdChannel(IAssociationStore<Uri> associationStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, RelyingPartySecuritySettings securitySettings) :
- this(messageTypeProvider, InitializeBindingElements(associationStore, nonceStore, securitySettings)) {
+ /// <param name="nonVerifying">A value indicating whether the channel is set up with no functional security binding elements.</param>
+ private OpenIdChannel(IAssociationStore<Uri> associationStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, RelyingPartySecuritySettings securitySettings, bool nonVerifying) :
+ this(messageTypeProvider, InitializeBindingElements(associationStore, nonceStore, securitySettings, nonVerifying)) {
Contract.Requires(messageTypeProvider != null);
Contract.Requires(securitySettings != null);
}
@@ -88,7 +89,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="messageTypeProvider">An object that knows how to distinguish the various OpenID message types for deserialization purposes.</param>
/// <param name="securitySettings">The security settings.</param>
private OpenIdChannel(IAssociationStore<AssociationRelyingPartyType> associationStore, INonceStore nonceStore, IMessageFactory messageTypeProvider, ProviderSecuritySettings securitySettings) :
- this(messageTypeProvider, InitializeBindingElements(associationStore, nonceStore, securitySettings)) {
+ this(messageTypeProvider, InitializeBindingElements(associationStore, nonceStore, securitySettings, false)) {
Contract.Requires(messageTypeProvider != null);
Contract.Requires(securitySettings != null);
}
@@ -130,6 +131,21 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
}
/// <summary>
+ /// A value indicating whether the channel is set up
+ /// with no functional security binding elements.
+ /// </summary>
+ /// <remarks>
+ /// <para>A value of <c>true</c> allows the relying party to preview incoming
+ /// messages without invalidating nonces or checking signatures.</para>
+ /// <para>Setting this to <c>true</c> poses a great security risk and is only
+ /// present to support the <see cref="OpenIdAjaxTextBox"/> which needs to preview
+ /// messages, and will validate them later.</para>
+ /// </remarks>
+ internal static OpenIdChannel CreateNonVerifyingChannel() {
+ return new OpenIdChannel(null, null, new OpenIdMessageFactory(), new RelyingPartySecuritySettings(), true);
+ }
+
+ /// <summary>
/// Verifies the integrity and applicability of an incoming message.
/// </summary>
/// <param name="message">The message just received.</param>
@@ -291,16 +307,19 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
/// <param name="associationStore">The association store.</param>
/// <param name="nonceStore">The nonce store to use.</param>
/// <param name="securitySettings">The security settings to apply. Must be an instance of either <see cref="RelyingPartySecuritySettings"/> or <see cref="ProviderSecuritySettings"/>.</param>
+ /// <param name="nonVerifying">A value indicating whether the channel is set up with no functional security binding elements.</param>
/// <returns>
/// An array of binding elements which may be used to construct the channel.
/// </returns>
- private static IChannelBindingElement[] InitializeBindingElements<T>(IAssociationStore<T> associationStore, INonceStore nonceStore, SecuritySettings securitySettings) {
+ private static IChannelBindingElement[] InitializeBindingElements<T>(IAssociationStore<T> associationStore, INonceStore nonceStore, SecuritySettings securitySettings, bool nonVerifying) {
Contract.Requires(securitySettings != null);
+ Contract.Requires(!nonVerifying || securitySettings is RelyingPartySecuritySettings);
ErrorUtilities.VerifyArgumentNotNull(securitySettings, "securitySettings");
var rpSecuritySettings = securitySettings as RelyingPartySecuritySettings;
var opSecuritySettings = securitySettings as ProviderSecuritySettings;
ErrorUtilities.VerifyInternal(rpSecuritySettings != null || opSecuritySettings != null, "Expected an RP or OP security settings instance.");
+ ErrorUtilities.VerifyInternal(!nonVerifying || rpSecuritySettings != null, "Non-verifying channels can only be constructed for relying parties.");
bool isRelyingPartyRole = rpSecuritySettings != null;
var rpAssociationStore = associationStore as IAssociationStore<Uri>;
@@ -309,7 +328,7 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
SigningBindingElement signingElement;
if (isRelyingPartyRole) {
- signingElement = new SigningBindingElement(rpAssociationStore);
+ signingElement = nonVerifying ? null : new SigningBindingElement(rpAssociationStore);
} else {
signingElement = new SigningBindingElement(opAssociationStore, opSecuritySettings);
}
@@ -338,12 +357,16 @@ namespace DotNetOpenAuth.OpenId.ChannelElements {
ErrorUtilities.VerifyArgumentNotNull(nonceStore, "nonceStore");
}
- if (nonceStore != null) {
- elements.Add(new StandardReplayProtectionBindingElement(nonceStore, true));
- }
+ if (nonVerifying) {
+ elements.Add(new SkipSecurityBindingElement());
+ } else {
+ if (nonceStore != null) {
+ elements.Add(new StandardReplayProtectionBindingElement(nonceStore, true));
+ }
- elements.Add(new StandardExpirationBindingElement());
- elements.Add(signingElement);
+ elements.Add(new StandardExpirationBindingElement());
+ elements.Add(signingElement);
+ }
return elements.ToArray();
}
diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/SkipSecurityBindingElement.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/SkipSecurityBindingElement.cs
new file mode 100644
index 0000000..ad65a83
--- /dev/null
+++ b/src/DotNetOpenAuth/OpenId/ChannelElements/SkipSecurityBindingElement.cs
@@ -0,0 +1,87 @@
+//-----------------------------------------------------------------------
+// <copyright file="SkipSecurityBindingElement.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.OpenId.ChannelElements {
+ using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
+ using System.Linq;
+ using System.Text;
+ using DotNetOpenAuth.Messaging;
+
+ /// <summary>
+ /// Spoofs security checks on incoming OpenID messages.
+ /// </summary>
+ internal class SkipSecurityBindingElement : IChannelBindingElement {
+ #region IChannelBindingElement Members
+
+ /// <summary>
+ /// Gets or sets the channel that this binding element belongs to.
+ /// </summary>
+ /// <value></value>
+ /// <remarks>
+ /// This property is set by the channel when it is first constructed.
+ /// </remarks>
+ public Channel Channel { get; set; }
+
+ /// <summary>
+ /// Gets the protection commonly offered (if any) by this binding element.
+ /// </summary>
+ /// <value><see cref="MessageProtections.All"/></value>
+ /// <remarks>
+ /// This value is used to assist in sorting binding elements in the channel stack.
+ /// </remarks>
+ public MessageProtections Protection {
+ get { return MessageProtections.All; }
+ }
+
+ /// <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) {
+ Debug.Fail("SkipSecurityBindingElement.ProcessOutgoingMessage should never be called.");
+ 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>
+ /// <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;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
index 167a7fe..a78c2e9 100644
--- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
+++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs
@@ -385,7 +385,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty {
/// </remarks>
internal static OpenIdRelyingParty CreateNonVerifying() {
OpenIdRelyingParty rp = new OpenIdRelyingParty();
- rp.Channel = new OpenIdChannel(null, null, rp.SecuritySettings);
+ rp.Channel = OpenIdChannel.CreateNonVerifyingChannel();
return rp;
}