diff options
author | Andrew Arnott <andrewarnott@gmail.com> | 2009-01-03 07:47:24 -0800 |
---|---|---|
committer | Andrew <andrewarnott@gmail.com> | 2009-01-03 07:47:24 -0800 |
commit | 1f0d70697cc819de7c0b422a6b17301ac5e3c0e8 (patch) | |
tree | 83b7973d4af3475c86bad1bd5780d9fce5bb08d8 /src | |
parent | 5e4490a04b2696011e47d95ff8b501710ee4b0a0 (diff) | |
download | DotNetOpenAuth-1f0d70697cc819de7c0b422a6b17301ac5e3c0e8.zip DotNetOpenAuth-1f0d70697cc819de7c0b422a6b17301ac5e3c0e8.tar.gz DotNetOpenAuth-1f0d70697cc819de7c0b422a6b17301ac5e3c0e8.tar.bz2 |
CRLF -> LF
Diffstat (limited to 'src')
4 files changed, 871 insertions, 871 deletions
diff --git a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj index b680db2..e763374 100644 --- a/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj +++ b/src/DotNetOpenAuth.Test/DotNetOpenAuth.Test.csproj @@ -1,190 +1,190 @@ -<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProductVersion>9.0.30729</ProductVersion>
- <SchemaVersion>2.0</SchemaVersion>
- <ProjectGuid>{4376ECC9-C346-4A99-B13C-FA93C0FBD2C9}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>DotNetOpenAuth.Test</RootNamespace>
- <AssemblyName>DotNetOpenAuth.Test</AssemblyName>
- <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>..\..\bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>..\..\bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Sign)' == 'true' ">
- <SignAssembly>true</SignAssembly>
- <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\..\lib\log4net.dll</HintPath>
- </Reference>
- <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
- <Reference Include="System" />
- <Reference Include="System.configuration" />
- <Reference Include="System.Core">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Data" />
- <Reference Include="System.Data.DataSetExtensions">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Runtime.Serialization">
- <RequiredTargetFramework>3.0</RequiredTargetFramework>
- </Reference>
- <Reference Include="System.Web" />
- <Reference Include="System.Xml" />
- <Reference Include="System.Xml.Linq">
- <RequiredTargetFramework>3.5</RequiredTargetFramework>
- </Reference>
- </ItemGroup>
- <ItemGroup>
- <Compile Include="CoordinatorBase.cs" />
- <Compile Include="Hosting\AspNetHost.cs" />
- <Compile Include="Hosting\HttpHost.cs" />
- <Compile Include="Hosting\TestingWorkerRequest.cs" />
- <Compile Include="Messaging\CollectionAssert.cs" />
- <Compile Include="Messaging\ErrorUtilitiesTests.cs" />
- <Compile Include="Messaging\MessageSerializerTests.cs" />
- <Compile Include="Messaging\Reflection\MessageDescriptionTests.cs" />
- <Compile Include="Messaging\Reflection\MessageDictionaryTests.cs" />
- <Compile Include="Messaging\MessagingTestBase.cs" />
- <Compile Include="Messaging\MessagingUtilitiesTests.cs" />
- <Compile Include="Messaging\ChannelTests.cs" />
- <Compile Include="Messaging\HttpRequestInfoTests.cs" />
- <Compile Include="Messaging\ProtocolExceptionTests.cs" />
- <Compile Include="Messaging\Bindings\StandardExpirationBindingElementTests.cs" />
- <Compile Include="Messaging\Reflection\MessagePartTests.cs" />
- <Compile Include="Messaging\Reflection\ValueMappingTests.cs" />
- <Compile Include="Mocks\CoordinatingChannel.cs" />
- <Compile Include="Mocks\InMemoryTokenManager.cs" />
- <Compile Include="Mocks\MockHttpRequest.cs" />
- <Compile Include="Mocks\MockIdentifier.cs" />
- <Compile Include="Mocks\MockOpenIdExtension.cs" />
- <Compile Include="Mocks\MockTransformationBindingElement.cs" />
- <Compile Include="Mocks\MockReplayProtectionBindingElement.cs" />
- <Compile Include="Mocks\TestBaseMessage.cs" />
- <Compile Include="Mocks\TestDerivedMessage.cs" />
- <Compile Include="Mocks\TestReplayProtectedMessage.cs" />
- <Compile Include="Mocks\TestDirectedMessage.cs" />
- <Compile Include="Mocks\TestBadChannel.cs" />
- <Compile Include="Mocks\TestExpiringMessage.cs" />
- <Compile Include="Mocks\TestSignedDirectedMessage.cs" />
- <Compile Include="Mocks\MockSigningBindingElement.cs" />
- <Compile Include="Mocks\TestWebRequestHandler.cs" />
- <Compile Include="Mocks\TestChannel.cs" />
- <Compile Include="Mocks\TestMessage.cs" />
- <Compile Include="Mocks\TestMessageFactory.cs" />
- <Compile Include="OAuth\ChannelElements\HmacSha1SigningBindingElementTests.cs" />
- <Compile Include="OAuth\ChannelElements\OAuthChannelTests.cs" />
- <Compile Include="OAuth\ChannelElements\PlaintextSigningBindingElementTest.cs" />
- <Compile Include="OAuth\ChannelElements\SigningBindingElementBaseTests.cs" />
- <Compile Include="OAuth\ConsumerDescription.cs" />
- <Compile Include="OAuth\ProtocolTests.cs" />
- <Compile Include="OAuth\ServiceProviderDescriptionTests.cs" />
- <Compile Include="OpenId\AssociationsTests.cs" />
- <Compile Include="OpenId\AssociationTests.cs" />
- <Compile Include="OpenId\AuthenticationTests.cs" />
- <Compile Include="OpenId\ChannelElements\ExtensionsBindingElementTests.cs" />
- <Compile Include="OpenId\ChannelElements\KeyValueFormEncodingTests.cs" />
- <Compile Include="Messaging\Bindings\StandardReplayProtectionBindingElementTests.cs" />
- <Compile Include="OpenId\DiffieHellmanTests.cs" />
- <Compile Include="OpenId\Extensions\SimpleRegistration\ClaimsResponseTests.cs" />
- <Compile Include="OpenId\Extensions\ExtensionTestBase.cs" />
- <Compile Include="OpenId\Extensions\SimpleRegistration\ClaimsRequestTests.cs" />
- <Compile Include="OpenId\IdentifierTests.cs" />
- <Compile Include="OpenId\Messages\AssociateDiffieHellmanRequestTests.cs" />
- <Compile Include="OpenId\Messages\AssociateRequestTests.cs" />
- <Compile Include="OpenId\Messages\AssociateUnsuccessfulResponseTests.cs" />
- <Compile Include="OpenId\Messages\AssociateUnencryptedResponseTests.cs" />
- <Compile Include="OpenId\ChannelElements\OpenIdChannelTests.cs" />
- <Compile Include="OpenId\Messages\CheckIdRequestTests.cs" />
- <Compile Include="OpenId\Messages\CheckAuthenticationResponseTests.cs" />
- <Compile Include="OpenId\Messages\CheckAuthenticationRequestTests.cs" />
- <Compile Include="OpenId\Messages\IndirectSignedResponseTests.cs" />
- <Compile Include="OpenId\Messages\NegativeAssertionResponseTests.cs" />
- <Compile Include="OpenId\Messages\DirectErrorResponseTests.cs" />
- <Compile Include="OpenId\Messages\IndirectErrorResponseTests.cs" />
- <Compile Include="OpenId\Messages\PositiveAssertionResponseTests.cs" />
- <Compile Include="OpenId\Messages\SignedResponseRequestTests.cs" />
- <Compile Include="OpenId\OpenIdCoordinator.cs" />
- <Compile Include="OpenId\AssociationHandshakeTests.cs" />
- <Compile Include="OpenId\OpenIdTestBase.cs" />
- <Compile Include="OpenId\RealmTests.cs" />
- <Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyTests.cs" />
- <Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettingsTests.cs" />
- <Compile Include="OpenId\RelyingParty\ServiceEndpointTests.cs" />
- <Compile Include="OpenId\TestSupport.cs" />
- <Compile Include="OpenId\UI\UITestSupport.cs" />
- <Compile Include="OpenId\UriIdentifierTests.cs" />
- <Compile Include="OpenId\XriIdentifierTests.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="Messaging\ResponseTests.cs" />
- <Compile Include="OAuth\AppendixScenarios.cs" />
- <Compile Include="Mocks\CoordinatingOAuthChannel.cs" />
- <Compile Include="OAuth\OAuthCoordinator.cs" />
- <Compile Include="TestBase.cs" />
- <Compile Include="TestUtilities.cs" />
- <Compile Include="UriUtilTests.cs" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\DotNetOpenAuth\DotNetOpenAuth.csproj">
- <Project>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</Project>
- <Name>DotNetOpenAuth</Name>
- </ProjectReference>
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="Logging.config" />
- </ItemGroup>
- <ItemGroup>
- <Shadow Include="Test References\DotNetOpenAuth.accessor" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html1020.html" />
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html10both.html" />
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html10del.html" />
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html10prov.html" />
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html2010.html" />
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html2010combinedA.html" />
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html2010combinedB.html" />
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html2010combinedC.html" />
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html20both.html" />
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html20del.html" />
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html20prov.html" />
- <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html20relative.html" />
- <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds-irrelevant.xml" />
- <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds10.xml" />
- <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds1020.xml" />
- <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds11.xml" />
- <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds20.xml" />
- <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds2010a.xml" />
- <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds2010b.xml" />
- <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\XrdsReferencedInHead.html" />
- <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\XrdsReferencedInHttpHeader.html" />
- </ItemGroup>
- <ItemGroup>
- <EmbeddedResource Include="OpenId\dhpriv.txt" />
- </ItemGroup>
- <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
- <Import Project="..\..\tools\DotNetOpenAuth.Versioning.targets" />
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>9.0.30729</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{4376ECC9-C346-4A99-B13C-FA93C0FBD2C9}</ProjectGuid> + <OutputType>Library</OutputType> + <AppDesignerFolder>Properties</AppDesignerFolder> + <RootNamespace>DotNetOpenAuth.Test</RootNamespace> + <AssemblyName>DotNetOpenAuth.Test</AssemblyName> + <TargetFrameworkVersion>v3.5</TargetFrameworkVersion> + <FileAlignment>512</FileAlignment> + <ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <DebugType>full</DebugType> + <Optimize>false</Optimize> + <OutputPath>..\..\bin\Debug\</OutputPath> + <DefineConstants>DEBUG;TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <DebugType>pdbonly</DebugType> + <Optimize>true</Optimize> + <OutputPath>..\..\bin\Release\</OutputPath> + <DefineConstants>TRACE</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + </PropertyGroup> + <PropertyGroup Condition=" '$(Sign)' == 'true' "> + <SignAssembly>true</SignAssembly> + <AssemblyOriginatorKeyFile>..\official-build-key.pfx</AssemblyOriginatorKeyFile> + </PropertyGroup> + <ItemGroup> + <Reference Include="log4net, Version=1.2.10.0, Culture=neutral, PublicKeyToken=1b44e1d426115821, processorArchitecture=MSIL"> + <SpecificVersion>False</SpecificVersion> + <HintPath>..\..\lib\log4net.dll</HintPath> + </Reference> + <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" /> + <Reference Include="System" /> + <Reference Include="System.configuration" /> + <Reference Include="System.Core"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Data" /> + <Reference Include="System.Data.DataSetExtensions"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + <Reference Include="System.Runtime.Serialization"> + <RequiredTargetFramework>3.0</RequiredTargetFramework> + </Reference> + <Reference Include="System.Web" /> + <Reference Include="System.Xml" /> + <Reference Include="System.Xml.Linq"> + <RequiredTargetFramework>3.5</RequiredTargetFramework> + </Reference> + </ItemGroup> + <ItemGroup> + <Compile Include="CoordinatorBase.cs" /> + <Compile Include="Hosting\AspNetHost.cs" /> + <Compile Include="Hosting\HttpHost.cs" /> + <Compile Include="Hosting\TestingWorkerRequest.cs" /> + <Compile Include="Messaging\CollectionAssert.cs" /> + <Compile Include="Messaging\ErrorUtilitiesTests.cs" /> + <Compile Include="Messaging\MessageSerializerTests.cs" /> + <Compile Include="Messaging\Reflection\MessageDescriptionTests.cs" /> + <Compile Include="Messaging\Reflection\MessageDictionaryTests.cs" /> + <Compile Include="Messaging\MessagingTestBase.cs" /> + <Compile Include="Messaging\MessagingUtilitiesTests.cs" /> + <Compile Include="Messaging\ChannelTests.cs" /> + <Compile Include="Messaging\HttpRequestInfoTests.cs" /> + <Compile Include="Messaging\ProtocolExceptionTests.cs" /> + <Compile Include="Messaging\Bindings\StandardExpirationBindingElementTests.cs" /> + <Compile Include="Messaging\Reflection\MessagePartTests.cs" /> + <Compile Include="Messaging\Reflection\ValueMappingTests.cs" /> + <Compile Include="Mocks\CoordinatingChannel.cs" /> + <Compile Include="Mocks\InMemoryTokenManager.cs" /> + <Compile Include="Mocks\MockHttpRequest.cs" /> + <Compile Include="Mocks\MockIdentifier.cs" /> + <Compile Include="Mocks\MockOpenIdExtension.cs" /> + <Compile Include="Mocks\MockTransformationBindingElement.cs" /> + <Compile Include="Mocks\MockReplayProtectionBindingElement.cs" /> + <Compile Include="Mocks\TestBaseMessage.cs" /> + <Compile Include="Mocks\TestDerivedMessage.cs" /> + <Compile Include="Mocks\TestReplayProtectedMessage.cs" /> + <Compile Include="Mocks\TestDirectedMessage.cs" /> + <Compile Include="Mocks\TestBadChannel.cs" /> + <Compile Include="Mocks\TestExpiringMessage.cs" /> + <Compile Include="Mocks\TestSignedDirectedMessage.cs" /> + <Compile Include="Mocks\MockSigningBindingElement.cs" /> + <Compile Include="Mocks\TestWebRequestHandler.cs" /> + <Compile Include="Mocks\TestChannel.cs" /> + <Compile Include="Mocks\TestMessage.cs" /> + <Compile Include="Mocks\TestMessageFactory.cs" /> + <Compile Include="OAuth\ChannelElements\HmacSha1SigningBindingElementTests.cs" /> + <Compile Include="OAuth\ChannelElements\OAuthChannelTests.cs" /> + <Compile Include="OAuth\ChannelElements\PlaintextSigningBindingElementTest.cs" /> + <Compile Include="OAuth\ChannelElements\SigningBindingElementBaseTests.cs" /> + <Compile Include="OAuth\ConsumerDescription.cs" /> + <Compile Include="OAuth\ProtocolTests.cs" /> + <Compile Include="OAuth\ServiceProviderDescriptionTests.cs" /> + <Compile Include="OpenId\AssociationsTests.cs" /> + <Compile Include="OpenId\AssociationTests.cs" /> + <Compile Include="OpenId\AuthenticationTests.cs" /> + <Compile Include="OpenId\ChannelElements\ExtensionsBindingElementTests.cs" /> + <Compile Include="OpenId\ChannelElements\KeyValueFormEncodingTests.cs" /> + <Compile Include="Messaging\Bindings\StandardReplayProtectionBindingElementTests.cs" /> + <Compile Include="OpenId\DiffieHellmanTests.cs" /> + <Compile Include="OpenId\Extensions\SimpleRegistration\ClaimsResponseTests.cs" /> + <Compile Include="OpenId\Extensions\ExtensionTestBase.cs" /> + <Compile Include="OpenId\Extensions\SimpleRegistration\ClaimsRequestTests.cs" /> + <Compile Include="OpenId\IdentifierTests.cs" /> + <Compile Include="OpenId\Messages\AssociateDiffieHellmanRequestTests.cs" /> + <Compile Include="OpenId\Messages\AssociateRequestTests.cs" /> + <Compile Include="OpenId\Messages\AssociateUnsuccessfulResponseTests.cs" /> + <Compile Include="OpenId\Messages\AssociateUnencryptedResponseTests.cs" /> + <Compile Include="OpenId\ChannelElements\OpenIdChannelTests.cs" /> + <Compile Include="OpenId\Messages\CheckIdRequestTests.cs" /> + <Compile Include="OpenId\Messages\CheckAuthenticationResponseTests.cs" /> + <Compile Include="OpenId\Messages\CheckAuthenticationRequestTests.cs" /> + <Compile Include="OpenId\Messages\IndirectSignedResponseTests.cs" /> + <Compile Include="OpenId\Messages\NegativeAssertionResponseTests.cs" /> + <Compile Include="OpenId\Messages\DirectErrorResponseTests.cs" /> + <Compile Include="OpenId\Messages\IndirectErrorResponseTests.cs" /> + <Compile Include="OpenId\Messages\PositiveAssertionResponseTests.cs" /> + <Compile Include="OpenId\Messages\SignedResponseRequestTests.cs" /> + <Compile Include="OpenId\OpenIdCoordinator.cs" /> + <Compile Include="OpenId\AssociationHandshakeTests.cs" /> + <Compile Include="OpenId\OpenIdTestBase.cs" /> + <Compile Include="OpenId\RealmTests.cs" /> + <Compile Include="OpenId\RelyingParty\OpenIdRelyingPartyTests.cs" /> + <Compile Include="OpenId\RelyingParty\RelyingPartySecuritySettingsTests.cs" /> + <Compile Include="OpenId\RelyingParty\ServiceEndpointTests.cs" /> + <Compile Include="OpenId\TestSupport.cs" /> + <Compile Include="OpenId\UI\UITestSupport.cs" /> + <Compile Include="OpenId\UriIdentifierTests.cs" /> + <Compile Include="OpenId\XriIdentifierTests.cs" /> + <Compile Include="Properties\AssemblyInfo.cs" /> + <Compile Include="Messaging\ResponseTests.cs" /> + <Compile Include="OAuth\AppendixScenarios.cs" /> + <Compile Include="Mocks\CoordinatingOAuthChannel.cs" /> + <Compile Include="OAuth\OAuthCoordinator.cs" /> + <Compile Include="TestBase.cs" /> + <Compile Include="TestUtilities.cs" /> + <Compile Include="UriUtilTests.cs" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\DotNetOpenAuth\DotNetOpenAuth.csproj"> + <Project>{3191B653-F76D-4C1A-9A5A-347BC3AAAAB7}</Project> + <Name>DotNetOpenAuth</Name> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="Logging.config" /> + </ItemGroup> + <ItemGroup> + <Shadow Include="Test References\DotNetOpenAuth.accessor" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html1020.html" /> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html10both.html" /> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html10del.html" /> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html10prov.html" /> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html2010.html" /> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html2010combinedA.html" /> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html2010combinedB.html" /> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html2010combinedC.html" /> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html20both.html" /> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html20del.html" /> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html20prov.html" /> + <EmbeddedResource Include="OpenId\Discovery\htmldiscovery\html20relative.html" /> + <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds-irrelevant.xml" /> + <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds10.xml" /> + <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds1020.xml" /> + <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds11.xml" /> + <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds20.xml" /> + <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds2010a.xml" /> + <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\xrds2010b.xml" /> + <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\XrdsReferencedInHead.html" /> + <EmbeddedResource Include="OpenId\Discovery\xrdsdiscovery\XrdsReferencedInHttpHeader.html" /> + </ItemGroup> + <ItemGroup> + <EmbeddedResource Include="OpenId\dhpriv.txt" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> + <Import Project="..\..\tools\DotNetOpenAuth.Versioning.targets" /> </Project>
\ No newline at end of file diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs index a300124..9d3d778 100644 --- a/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs +++ b/src/DotNetOpenAuth/OpenId/ChannelElements/OpenIdChannel.cs @@ -1,223 +1,223 @@ -//-----------------------------------------------------------------------
-// <copyright file="OpenIdChannel.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.ChannelElements {
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Net;
- using System.Text;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.Messaging.Bindings;
- using DotNetOpenAuth.OpenId.Extensions;
- using DotNetOpenAuth.OpenId.Messages;
-
- /// <summary>
- /// A channel that knows how to send and receive OpenID messages.
- /// </summary>
- internal class OpenIdChannel : Channel {
- /// <summary>
- /// The HTTP Content-Type to use in Key-Value Form responses.
- /// </summary>
- /// <remarks>
- /// OpenID 2.0 section 5.1.2 says this SHOULD be text/plain. But this value
- /// does not prevent free hosters like GoDaddy from tacking on their ads
- /// to the end of the direct response, corrupting the data. So we deviate
- /// from the spec a bit here to improve the story for free Providers.
- /// </remarks>
- private const string KeyValueFormContentType = "application/x-openid-kvf";
-
- /// <summary>
- /// The encoder that understands how to read and write Key-Value Form.
- /// </summary>
- private KeyValueFormEncoding keyValueForm = new KeyValueFormEncoding();
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdChannel"/> class
- /// for use by a Relying Party.
- /// </summary>
- /// <param name="associationStore">The association store to use.</param>
- /// <param name="nonceStore">The nonce store to use.</param>
- /// <param name="secretStore">The secret store to use.</param>
- internal OpenIdChannel(IAssociationStore<Uri> associationStore, INonceStore nonceStore, IPrivateSecretStore secretStore)
- : this(associationStore, nonceStore, secretStore, new OpenIdMessageFactory()) {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdChannel"/> class
- /// for use by a Provider.
- /// </summary>
- /// <param name="associationStore">The association store to use.</param>
- /// <param name="nonceStore">The nonce store to use.</param>
- internal OpenIdChannel(IAssociationStore<AssociationRelyingPartyType> associationStore, INonceStore nonceStore)
- : this(associationStore, nonceStore, new OpenIdMessageFactory()) {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdChannel"/> class
- /// for use by a Relying Party.
- /// </summary>
- /// <param name="associationStore">The association store to use.</param>
- /// <param name="nonceStore">The nonce store to use.</param>
- /// <param name="secretStore">The secret store to use.</param>
- /// <param name="messageTypeProvider">An object that knows how to distinguish the various OpenID message types for deserialization purposes.</param>
- private OpenIdChannel(IAssociationStore<Uri> associationStore, INonceStore nonceStore, IPrivateSecretStore secretStore, IMessageFactory messageTypeProvider) :
- this(messageTypeProvider, InitializeBindingElements(new SigningBindingElement(associationStore), nonceStore, secretStore, true)) {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdChannel"/> class
- /// for use by a Provider.
- /// </summary>
- /// <param name="associationStore">The association store to use.</param>
- /// <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>
- private OpenIdChannel(IAssociationStore<AssociationRelyingPartyType> associationStore, INonceStore nonceStore, IMessageFactory messageTypeProvider) :
- this(messageTypeProvider, InitializeBindingElements(new SigningBindingElement(associationStore), nonceStore, null, false)) {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="OpenIdChannel"/> class.
- /// </summary>
- /// <param name="messageTypeProvider">A class prepared to analyze incoming messages and indicate what concrete
- /// message types can deserialize from it.</param>
- /// <param name="bindingElements">The binding elements to use in sending and receiving messages.</param>
- private OpenIdChannel(IMessageFactory messageTypeProvider, IChannelBindingElement[] bindingElements)
- : base(messageTypeProvider, bindingElements) {
- // Customize the binding element order, since we play some tricks for higher
- // security and backward compatibility with older OpenID versions.
- var outgoingBindingElements = new List<IChannelBindingElement>(bindingElements);
- var incomingBindingElements = new List<IChannelBindingElement>(bindingElements);
- incomingBindingElements.Reverse();
-
- // Customize the order of the incoming elements by moving the return_to elements in front.
- var backwardCompatibility = incomingBindingElements.OfType<BackwardCompatibilityBindingElement>().SingleOrDefault();
- var returnToSign = incomingBindingElements.OfType<ReturnToSignatureBindingElement>().SingleOrDefault();
- if (backwardCompatibility != null && returnToSign != null) {
- incomingBindingElements.MoveTo(0, returnToSign);
- incomingBindingElements.MoveTo(1, backwardCompatibility);
- }
-
- CustomizeBindingElementOrder(outgoingBindingElements, incomingBindingElements);
- }
-
- /// <summary>
- /// Gets the extension factory that can be used to register OpenID extensions.
- /// </summary>
- internal OpenIdExtensionFactory Extensions { get; private set; }
-
- /// <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 VerifyMessageAfterReceiving(IProtocolMessage message) {
- var checkAuthRequest = message as CheckAuthenticationRequest;
- if (checkAuthRequest != null) {
- IndirectSignedResponse originalResponse = new IndirectSignedResponse(checkAuthRequest);
- try {
- base.VerifyMessageAfterReceiving(originalResponse);
- checkAuthRequest.IsValid = true;
- } catch (ProtocolException) {
- checkAuthRequest.IsValid = false;
- }
- } else {
- base.VerifyMessageAfterReceiving(message);
- }
- }
-
- /// <summary>
- /// Prepares an HTTP request that carries a given message.
- /// </summary>
- /// <param name="request">The message to send.</param>
- /// <returns>
- /// The <see cref="HttpWebRequest"/> prepared to send the request.
- /// </returns>
- protected override HttpWebRequest CreateHttpRequest(IDirectedProtocolMessage request) {
- return this.InitializeRequestAsPost(request);
- }
-
- /// <summary>
- /// Gets the protocol message that may be in the given HTTP response.
- /// </summary>
- /// <param name="response">The response that is anticipated to contain an protocol message.</param>
- /// <returns>
- /// The deserialized message parts, if found. Null otherwise.
- /// </returns>
- protected override IDictionary<string, string> ReadFromResponseInternal(DirectWebResponse response) {
- if (response == null) {
- throw new ArgumentNullException("response");
- }
-
- return this.keyValueForm.GetDictionary(response.ResponseStream);
- }
-
- /// <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 UserAgentResponse SendDirectMessageResponse(IProtocolMessage response) {
- if (response == null) {
- throw new ArgumentNullException("response");
- }
-
- var serializer = MessageSerializer.Get(response.GetType());
- var fields = serializer.Serialize(response);
- byte[] keyValueEncoding = KeyValueFormEncoding.GetBytes(fields);
-
- UserAgentResponse preparedResponse = new UserAgentResponse();
- preparedResponse.Headers.Add(HttpResponseHeader.ContentType, KeyValueFormContentType);
- preparedResponse.OriginalMessage = response;
- preparedResponse.ResponseStream = new MemoryStream(keyValueEncoding);
-
- return preparedResponse;
- }
-
- /// <summary>
- /// Initializes the binding elements.
- /// </summary>
- /// <param name="signingElement">The signing element, previously constructed.</param>
- /// <param name="nonceStore">The nonce store to use.</param>
- /// <param name="secretStore">The secret store to use.</param>
- /// <param name="isRelyingPartyRole">A value indicating whether this channel is being constructed for a Relying Party (as opposed to a Provider).</param>
- /// <returns>
- /// An array of binding elements which may be used to construct the channel.
- /// </returns>
- private static IChannelBindingElement[] InitializeBindingElements(SigningBindingElement signingElement, INonceStore nonceStore, IPrivateSecretStore secretStore, bool isRelyingPartyRole) {
- ErrorUtilities.VerifyArgumentNotNull(signingElement, "signingElement");
-
- List<IChannelBindingElement> elements = new List<IChannelBindingElement>(7);
- elements.Add(new ExtensionsBindingElement(new OpenIdExtensionFactory()));
- if (isRelyingPartyRole) {
- ErrorUtilities.VerifyArgumentNotNull(secretStore, "secretStore");
- secretStore.InitializeSecretIfUnset();
-
- // It is important that the return_to signing element comes last
- // so that the nonce is included in the signature.
- elements.Add(new BackwardCompatibilityBindingElement());
- elements.Add(new ReturnToNonceBindingElement(nonceStore));
- elements.Add(new ReturnToSignatureBindingElement(secretStore));
- }
-
- elements.Add(new StandardReplayProtectionBindingElement(nonceStore, true));
- elements.Add(new StandardExpirationBindingElement());
- elements.Add(signingElement);
-
- return elements.ToArray();
- }
- }
-}
+//----------------------------------------------------------------------- +// <copyright file="OpenIdChannel.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.ChannelElements { + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Net; + using System.Text; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging.Bindings; + using DotNetOpenAuth.OpenId.Extensions; + using DotNetOpenAuth.OpenId.Messages; + + /// <summary> + /// A channel that knows how to send and receive OpenID messages. + /// </summary> + internal class OpenIdChannel : Channel { + /// <summary> + /// The HTTP Content-Type to use in Key-Value Form responses. + /// </summary> + /// <remarks> + /// OpenID 2.0 section 5.1.2 says this SHOULD be text/plain. But this value + /// does not prevent free hosters like GoDaddy from tacking on their ads + /// to the end of the direct response, corrupting the data. So we deviate + /// from the spec a bit here to improve the story for free Providers. + /// </remarks> + private const string KeyValueFormContentType = "application/x-openid-kvf"; + + /// <summary> + /// The encoder that understands how to read and write Key-Value Form. + /// </summary> + private KeyValueFormEncoding keyValueForm = new KeyValueFormEncoding(); + + /// <summary> + /// Initializes a new instance of the <see cref="OpenIdChannel"/> class + /// for use by a Relying Party. + /// </summary> + /// <param name="associationStore">The association store to use.</param> + /// <param name="nonceStore">The nonce store to use.</param> + /// <param name="secretStore">The secret store to use.</param> + internal OpenIdChannel(IAssociationStore<Uri> associationStore, INonceStore nonceStore, IPrivateSecretStore secretStore) + : this(associationStore, nonceStore, secretStore, new OpenIdMessageFactory()) { + } + + /// <summary> + /// Initializes a new instance of the <see cref="OpenIdChannel"/> class + /// for use by a Provider. + /// </summary> + /// <param name="associationStore">The association store to use.</param> + /// <param name="nonceStore">The nonce store to use.</param> + internal OpenIdChannel(IAssociationStore<AssociationRelyingPartyType> associationStore, INonceStore nonceStore) + : this(associationStore, nonceStore, new OpenIdMessageFactory()) { + } + + /// <summary> + /// Initializes a new instance of the <see cref="OpenIdChannel"/> class + /// for use by a Relying Party. + /// </summary> + /// <param name="associationStore">The association store to use.</param> + /// <param name="nonceStore">The nonce store to use.</param> + /// <param name="secretStore">The secret store to use.</param> + /// <param name="messageTypeProvider">An object that knows how to distinguish the various OpenID message types for deserialization purposes.</param> + private OpenIdChannel(IAssociationStore<Uri> associationStore, INonceStore nonceStore, IPrivateSecretStore secretStore, IMessageFactory messageTypeProvider) : + this(messageTypeProvider, InitializeBindingElements(new SigningBindingElement(associationStore), nonceStore, secretStore, true)) { + } + + /// <summary> + /// Initializes a new instance of the <see cref="OpenIdChannel"/> class + /// for use by a Provider. + /// </summary> + /// <param name="associationStore">The association store to use.</param> + /// <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> + private OpenIdChannel(IAssociationStore<AssociationRelyingPartyType> associationStore, INonceStore nonceStore, IMessageFactory messageTypeProvider) : + this(messageTypeProvider, InitializeBindingElements(new SigningBindingElement(associationStore), nonceStore, null, false)) { + } + + /// <summary> + /// Initializes a new instance of the <see cref="OpenIdChannel"/> class. + /// </summary> + /// <param name="messageTypeProvider">A class prepared to analyze incoming messages and indicate what concrete + /// message types can deserialize from it.</param> + /// <param name="bindingElements">The binding elements to use in sending and receiving messages.</param> + private OpenIdChannel(IMessageFactory messageTypeProvider, IChannelBindingElement[] bindingElements) + : base(messageTypeProvider, bindingElements) { + // Customize the binding element order, since we play some tricks for higher + // security and backward compatibility with older OpenID versions. + var outgoingBindingElements = new List<IChannelBindingElement>(bindingElements); + var incomingBindingElements = new List<IChannelBindingElement>(bindingElements); + incomingBindingElements.Reverse(); + + // Customize the order of the incoming elements by moving the return_to elements in front. + var backwardCompatibility = incomingBindingElements.OfType<BackwardCompatibilityBindingElement>().SingleOrDefault(); + var returnToSign = incomingBindingElements.OfType<ReturnToSignatureBindingElement>().SingleOrDefault(); + if (backwardCompatibility != null && returnToSign != null) { + incomingBindingElements.MoveTo(0, returnToSign); + incomingBindingElements.MoveTo(1, backwardCompatibility); + } + + CustomizeBindingElementOrder(outgoingBindingElements, incomingBindingElements); + } + + /// <summary> + /// Gets the extension factory that can be used to register OpenID extensions. + /// </summary> + internal OpenIdExtensionFactory Extensions { get; private set; } + + /// <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 VerifyMessageAfterReceiving(IProtocolMessage message) { + var checkAuthRequest = message as CheckAuthenticationRequest; + if (checkAuthRequest != null) { + IndirectSignedResponse originalResponse = new IndirectSignedResponse(checkAuthRequest); + try { + base.VerifyMessageAfterReceiving(originalResponse); + checkAuthRequest.IsValid = true; + } catch (ProtocolException) { + checkAuthRequest.IsValid = false; + } + } else { + base.VerifyMessageAfterReceiving(message); + } + } + + /// <summary> + /// Prepares an HTTP request that carries a given message. + /// </summary> + /// <param name="request">The message to send.</param> + /// <returns> + /// The <see cref="HttpWebRequest"/> prepared to send the request. + /// </returns> + protected override HttpWebRequest CreateHttpRequest(IDirectedProtocolMessage request) { + return this.InitializeRequestAsPost(request); + } + + /// <summary> + /// Gets the protocol message that may be in the given HTTP response. + /// </summary> + /// <param name="response">The response that is anticipated to contain an protocol message.</param> + /// <returns> + /// The deserialized message parts, if found. Null otherwise. + /// </returns> + protected override IDictionary<string, string> ReadFromResponseInternal(DirectWebResponse response) { + if (response == null) { + throw new ArgumentNullException("response"); + } + + return this.keyValueForm.GetDictionary(response.ResponseStream); + } + + /// <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 UserAgentResponse SendDirectMessageResponse(IProtocolMessage response) { + if (response == null) { + throw new ArgumentNullException("response"); + } + + var serializer = MessageSerializer.Get(response.GetType()); + var fields = serializer.Serialize(response); + byte[] keyValueEncoding = KeyValueFormEncoding.GetBytes(fields); + + UserAgentResponse preparedResponse = new UserAgentResponse(); + preparedResponse.Headers.Add(HttpResponseHeader.ContentType, KeyValueFormContentType); + preparedResponse.OriginalMessage = response; + preparedResponse.ResponseStream = new MemoryStream(keyValueEncoding); + + return preparedResponse; + } + + /// <summary> + /// Initializes the binding elements. + /// </summary> + /// <param name="signingElement">The signing element, previously constructed.</param> + /// <param name="nonceStore">The nonce store to use.</param> + /// <param name="secretStore">The secret store to use.</param> + /// <param name="isRelyingPartyRole">A value indicating whether this channel is being constructed for a Relying Party (as opposed to a Provider).</param> + /// <returns> + /// An array of binding elements which may be used to construct the channel. + /// </returns> + private static IChannelBindingElement[] InitializeBindingElements(SigningBindingElement signingElement, INonceStore nonceStore, IPrivateSecretStore secretStore, bool isRelyingPartyRole) { + ErrorUtilities.VerifyArgumentNotNull(signingElement, "signingElement"); + + List<IChannelBindingElement> elements = new List<IChannelBindingElement>(7); + elements.Add(new ExtensionsBindingElement(new OpenIdExtensionFactory())); + if (isRelyingPartyRole) { + ErrorUtilities.VerifyArgumentNotNull(secretStore, "secretStore"); + secretStore.InitializeSecretIfUnset(); + + // It is important that the return_to signing element comes last + // so that the nonce is included in the signature. + elements.Add(new BackwardCompatibilityBindingElement()); + elements.Add(new ReturnToNonceBindingElement(nonceStore)); + elements.Add(new ReturnToSignatureBindingElement(secretStore)); + } + + elements.Add(new StandardReplayProtectionBindingElement(nonceStore, true)); + elements.Add(new StandardExpirationBindingElement()); + elements.Add(signingElement); + + return elements.ToArray(); + } + } +} diff --git a/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs index 46c3bcc..7c0015f 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/IndirectSignedResponse.cs @@ -1,355 +1,355 @@ -//-----------------------------------------------------------------------
-// <copyright file="IndirectSignedResponse.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.Messages {
- using System;
- using System.Collections.Generic;
- using System.Collections.Specialized;
- using System.Diagnostics;
- using System.Globalization;
- using System.Linq;
- using System.Net.Security;
- using System.Web;
- using DotNetOpenAuth.Messaging;
- using DotNetOpenAuth.Messaging.Bindings;
- using DotNetOpenAuth.Messaging.Reflection;
- using DotNetOpenAuth.OpenId.ChannelElements;
-
- /// <summary>
- /// An indirect message from a Provider to a Relying Party where at least part of the
- /// payload is signed so the Relying Party can verify it has not been tampered with.
- /// </summary>
- [DebuggerDisplay("OpenID {Version} {Mode} (no id assertion)")]
- internal class IndirectSignedResponse : IndirectResponseBase, ITamperResistantOpenIdMessage, IProtocolMessageWithExtensions {
- /// <summary>
- /// The allowed date/time formats for the response_nonce parameter.
- /// </summary>
- /// <remarks>
- /// This array of formats is not yet a complete list.
- /// </remarks>
- private static readonly string[] PermissibleDateTimeFormats = { "yyyy-MM-ddTHH:mm:ssZ" };
-
- /// <summary>
- /// Backing store for the <see cref="Extensions"/> property.
- /// </summary>
- private IList<IExtensionMessage> extensions = new List<IExtensionMessage>();
-
- /// <summary>
- /// Backing field for the <see cref="IExpiringProtocolMessage.UtcCreationDate"/> property.
- /// </summary>
- private DateTime creationDateUtc = DateTime.UtcNow;
-
- /// <summary>
- /// Backing store for the <see cref="ReturnToParameters"/> property.
- /// </summary>
- private IDictionary<string, string> returnToParameters;
-
- /// <summary>
- /// Backing store for the <see cref="ReturnToParametersSignatureValidated"/> property.
- /// </summary>
- private bool returnToParametersSignatureValidated;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="IndirectSignedResponse"/> class.
- /// </summary>
- /// <param name="request">
- /// The authentication request that caused this assertion to be generated.
- /// </param>
- internal IndirectSignedResponse(SignedResponseRequest request)
- : base(request, Protocol.Lookup(GetVersion(request)).Args.Mode.id_res) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
-
- this.ReturnTo = request.ReturnTo;
- this.ProviderEndpoint = request.Recipient;
- ((ITamperResistantOpenIdMessage)this).AssociationHandle = request.AssociationHandle;
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="IndirectSignedResponse"/> class
- /// in order to perform signature verification at the Provider.
- /// </summary>
- /// <param name="previouslySignedMessage">The previously signed message.</param>
- internal IndirectSignedResponse(CheckAuthenticationRequest previouslySignedMessage)
- : base(GetVersion(previouslySignedMessage), previouslySignedMessage.ReturnTo, Protocol.Lookup(GetVersion(previouslySignedMessage)).Args.Mode.id_res) {
- // Copy all message parts from the check_authentication message into this one,
- // except for the openid.mode parameter.
- MessageDictionary checkPayload = new MessageDictionary(previouslySignedMessage);
- MessageDictionary thisPayload = new MessageDictionary(this);
- foreach (var pair in checkPayload) {
- if (!string.Equals(pair.Key, this.Protocol.openid.mode)) {
- thisPayload[pair.Key] = pair.Value;
- }
- }
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="IndirectSignedResponse"/> class
- /// for unsolicited assertions.
- /// </summary>
- /// <param name="version">The OpenID version to use.</param>
- /// <param name="relyingPartyReturnTo">The return_to URL of the Relying Party.
- /// This value will commonly be from <see cref="SignedResponseRequest.ReturnTo"/>,
- /// but for unsolicited assertions may come from the Provider performing RP discovery
- /// to find the appropriate return_to URL to use.</param>
- internal IndirectSignedResponse(Version version, Uri relyingPartyReturnTo)
- : base(version, relyingPartyReturnTo, Protocol.Lookup(version).Args.Mode.id_res) {
- }
-
- #region IProtocolMessageWithExtensions Members
-
- /// <summary>
- /// Gets the list of extensions that are included with this message.
- /// </summary>
- /// <value></value>
- /// <remarks>
- /// Implementations of this interface should ensure that this property never returns null.
- /// </remarks>
- public IList<IExtensionMessage> Extensions {
- get { return this.extensions; }
- }
-
- #endregion
-
- /// <summary>
- /// Gets the level of protection this message requires.
- /// </summary>
- /// <value>
- /// <see cref="MessageProtections.All"/> for OpenID 2.0 messages.
- /// <see cref="MessageProtections.TamperProtection"/> for OpenID 1.x messages.
- /// </value>
- /// <remarks>
- /// Although the required protection is reduced for OpenID 1.x,
- /// this library will provide Relying Party hosts with all protections
- /// by adding its own specially-crafted nonce to the authentication request
- /// messages.
- /// </remarks>
- public override MessageProtections RequiredProtection {
- // TODO: Fix up Provider side to only use private associations (dumb mode),
- // and then to add a special nonce value of its own to provide replay
- // protection to the Provider's users even when logging into 1.0 RPs.
- // When this is done, remove this conditional getter and always return
- // that All protections are required.
- get { return this.Version.Major < 2 ? MessageProtections.TamperProtection : MessageProtections.All; }
- }
-
- /// <summary>
- /// Gets or sets the message signature.
- /// </summary>
- /// <value>Base 64 encoded signature calculated as specified in Section 6 (Generating Signatures).</value>
- [MessagePart("openid.sig", IsRequired = true, AllowEmpty = false)]
- string ITamperResistantProtocolMessage.Signature { get; set; }
-
- /// <summary>
- /// Gets or sets the signed parameter order.
- /// </summary>
- /// <value>Comma-separated list of signed fields.</value>
- /// <example>"op_endpoint,identity,claimed_id,return_to,assoc_handle,response_nonce"</example>
- /// <remarks>
- /// This entry consists of the fields without the "openid." prefix that the signature covers.
- /// This list MUST contain at least "op_endpoint", "return_to" "response_nonce" and "assoc_handle",
- /// and if present in the response, "claimed_id" and "identity".
- /// Additional keys MAY be signed as part of the message. See Generating Signatures.
- /// </remarks>
- [MessagePart("openid.signed", IsRequired = true, AllowEmpty = false)]
- string ITamperResistantOpenIdMessage.SignedParameterOrder { get; set; }
-
- /// <summary>
- /// Gets or sets the association handle used to sign the message.
- /// </summary>
- /// <value>The handle for the association that was used to sign this assertion. </value>
- [MessagePart("openid.assoc_handle", IsRequired = true, AllowEmpty = false, RequiredProtection = ProtectionLevel.Sign)]
- string ITamperResistantOpenIdMessage.AssociationHandle { get; set; }
-
- /// <summary>
- /// Gets or sets the nonce that will protect the message from replay attacks.
- /// </summary>
- string IReplayProtectedProtocolMessage.Nonce { get; set; }
-
- /// <summary>
- /// Gets or sets the UTC date/time the message was originally sent onto the network.
- /// </summary>
- /// <remarks>
- /// The property setter should ensure a UTC date/time,
- /// and throw an exception if this is not possible.
- /// </remarks>
- /// <exception cref="ArgumentException">
- /// Thrown when a DateTime that cannot be converted to UTC is set.
- /// </exception>
- DateTime IExpiringProtocolMessage.UtcCreationDate {
- get { return this.creationDateUtc; }
- set { this.creationDateUtc = value.ToUniversalTime(); }
- }
-
- /// <summary>
- /// Gets or sets the association handle that the Provider wants the Relying Party to not use any more.
- /// </summary>
- /// <value>If the Relying Party sent an invalid association handle with the request, it SHOULD be included here.</value>
- [MessagePart("openid.invalidate_handle", IsRequired = false, AllowEmpty = false)]
- string ITamperResistantOpenIdMessage.InvalidateHandle { get; set; }
-
- /// <summary>
- /// Gets or sets the Provider Endpoint URI.
- /// </summary>
- [MessagePart("openid.op_endpoint", IsRequired = true, AllowEmpty = false, RequiredProtection = ProtectionLevel.Sign, MinVersion = "2.0")]
- internal Uri ProviderEndpoint { get; set; }
-
- /// <summary>
- /// Gets or sets the return_to parameter as the relying party provided
- /// it in <see cref="SignedResponseRequest.ReturnTo"/>.
- /// </summary>
- /// <value>Verbatim copy of the return_to URL parameter sent in the
- /// request, before the Provider modified it. </value>
- [MessagePart("openid.return_to", IsRequired = true, AllowEmpty = false, RequiredProtection = ProtectionLevel.Sign, Encoder = typeof(OriginalStringUriEncoder))]
- internal Uri ReturnTo { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether the <see cref="ReturnTo"/>
- /// URI's query string is unaltered between when the Relying Party
- /// sent the original request and when the response was received.
- /// </summary>
- /// <remarks>
- /// This property is not persisted in the transmitted message, and
- /// has no effect on the Provider-side of the communication.
- /// </remarks>
- internal bool ReturnToParametersSignatureValidated {
- get {
- return this.returnToParametersSignatureValidated;
- }
-
- set {
- if (this.returnToParametersSignatureValidated == value) {
- return;
- }
-
- this.returnToParametersSignatureValidated = value;
- this.returnToParameters = null;
- }
- }
-
- /// <summary>
- /// Gets or sets the nonce that will protect the message from replay attacks.
- /// </summary>
- /// <value>
- /// <para>A string 255 characters or less in length, that MUST be unique to
- /// this particular successful authentication response. The nonce MUST start
- /// with the current time on the server, and MAY contain additional ASCII
- /// characters in the range 33-126 inclusive (printable non-whitespace characters),
- /// as necessary to make each response unique. The date and time MUST be
- /// formatted as specified in section 5.6 of [RFC3339]
- /// (Klyne, G. and C. Newman, “Date and Time on the Internet: Timestamps,” .),
- /// with the following restrictions:</para>
- /// <list type="bullet">
- /// <item>All times must be in the UTC timezone, indicated with a "Z".</item>
- /// <item>No fractional seconds are allowed</item>
- /// </list>
- /// </value>
- /// <example>2005-05-15T17:11:51ZUNIQUE</example>
- [MessagePart("openid.response_nonce", IsRequired = true, AllowEmpty = false, RequiredProtection = ProtectionLevel.Sign, MinVersion = "2.0")]
- private string ResponseNonce {
- get {
- string uniqueFragment = ((IReplayProtectedProtocolMessage)this).Nonce;
- return this.creationDateUtc.ToString(PermissibleDateTimeFormats[0], CultureInfo.InvariantCulture) + uniqueFragment;
- }
-
- set {
- if (value == null) {
- ((IReplayProtectedProtocolMessage)this).Nonce = null;
- } else {
- int indexOfZ = value.IndexOf("Z", StringComparison.Ordinal);
- ErrorUtilities.VerifyProtocol(indexOfZ >= 0, MessagingStrings.UnexpectedMessagePartValue, Protocol.openid.response_nonce, value);
- this.creationDateUtc = DateTime.Parse(value.Substring(0, indexOfZ + 1), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal);
- ((IReplayProtectedProtocolMessage)this).Nonce = value.Substring(indexOfZ + 1);
- }
- }
- }
-
- /// <summary>
- /// Gets the querystring key=value pairs in the return_to URL.
- /// </summary>
- private IDictionary<string, string> ReturnToParameters {
- get {
- if (this.returnToParameters == null) {
- // Only return data that can be validated as untampered with.
- if (this.ReturnToParametersSignatureValidated) {
- this.returnToParameters = HttpUtility.ParseQueryString(this.ReturnTo.Query).ToDictionary();
- } else {
- // Store an empty dictionary since we can't consider any callback data reliable.
- this.returnToParameters = new Dictionary<string, string>(0);
- }
- }
-
- return this.returnToParameters;
- }
- }
-
- /// <summary>
- /// Checks the message state for conformity to the protocol specification
- /// and throws an exception if the message is invalid.
- /// </summary>
- /// <remarks>
- /// <para>Some messages have required fields, or combinations of fields that must relate to each other
- /// in specialized ways. After deserializing a message, this method checks the state of the
- /// message to see if it conforms to the protocol.</para>
- /// <para>Note that this property should <i>not</i> check signatures or perform any state checks
- /// outside this scope of this particular message.</para>
- /// </remarks>
- /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception>
- public override void EnsureValidMessage() {
- base.EnsureValidMessage();
-
- this.VerifyReturnToMatchesRecipient();
- }
-
- /// <summary>
- /// Gets the value of a named parameter in the return_to URL.
- /// </summary>
- /// <param name="key">The full name of the parameter whose value is being sought.</param>
- /// <returns>The value of the parameter if it is present and unaltered from when
- /// the Relying Party signed it; <c>null</c> otherwise.</returns>
- /// <remarks>
- /// This method will always return null on the Provider-side, since Providers
- /// cannot verify the private signature made by the relying party.
- /// </remarks>
- internal string GetReturnToArgument(string key) {
- ErrorUtilities.VerifyNonZeroLength(key, "key");
- ErrorUtilities.VerifyInternal(this.ReturnTo != null, "ReturnTo was expected to be required but is null.");
-
- string value;
- this.ReturnToParameters.TryGetValue(key, out value);
- return value;
- }
-
- /// <summary>
- /// Verifies that the openid.return_to field matches the URL of the actual HTTP request.
- /// </summary>
- /// <remarks>
- /// From OpenId Authentication 2.0 section 11.1:
- /// To verify that the "openid.return_to" URL matches the URL that is processing this assertion:
- /// * The URL scheme, authority, and path MUST be the same between the two URLs.
- /// * Any query parameters that are present in the "openid.return_to" URL MUST
- /// also be present with the same values in the URL of the HTTP request the RP received.
- /// </remarks>
- private void VerifyReturnToMatchesRecipient() {
- ErrorUtilities.VerifyProtocol(
- string.Equals(this.Recipient.Scheme, this.ReturnTo.Scheme, StringComparison.OrdinalIgnoreCase) &&
- string.Equals(this.Recipient.Authority, this.ReturnTo.Authority, StringComparison.OrdinalIgnoreCase) &&
- string.Equals(this.Recipient.AbsolutePath, this.ReturnTo.AbsolutePath, StringComparison.Ordinal),
- OpenIdStrings.ReturnToParamDoesNotMatchRequestUrl,
- Protocol.openid.return_to,
- this.ReturnTo,
- this.Recipient);
-
- NameValueCollection returnToArgs = HttpUtility.ParseQueryString(this.ReturnTo.Query);
- NameValueCollection requestArgs = HttpUtility.ParseQueryString(this.Recipient.Query);
- ErrorUtilities.VerifyProtocol(
- returnToArgs.Keys.Cast<string>().All(returnToKey => string.Equals(returnToArgs[returnToKey], requestArgs[returnToKey], StringComparison.Ordinal)),
- OpenIdStrings.ReturnToParamDoesNotMatchRequestUrl,
- Protocol.openid.return_to,
- this.ReturnTo,
- this.Recipient);
- }
- }
-}
+//----------------------------------------------------------------------- +// <copyright file="IndirectSignedResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Messages { + using System; + using System.Collections.Generic; + using System.Collections.Specialized; + using System.Diagnostics; + using System.Globalization; + using System.Linq; + using System.Net.Security; + using System.Web; + using DotNetOpenAuth.Messaging; + using DotNetOpenAuth.Messaging.Bindings; + using DotNetOpenAuth.Messaging.Reflection; + using DotNetOpenAuth.OpenId.ChannelElements; + + /// <summary> + /// An indirect message from a Provider to a Relying Party where at least part of the + /// payload is signed so the Relying Party can verify it has not been tampered with. + /// </summary> + [DebuggerDisplay("OpenID {Version} {Mode} (no id assertion)")] + internal class IndirectSignedResponse : IndirectResponseBase, ITamperResistantOpenIdMessage, IProtocolMessageWithExtensions { + /// <summary> + /// The allowed date/time formats for the response_nonce parameter. + /// </summary> + /// <remarks> + /// This array of formats is not yet a complete list. + /// </remarks> + private static readonly string[] PermissibleDateTimeFormats = { "yyyy-MM-ddTHH:mm:ssZ" }; + + /// <summary> + /// Backing store for the <see cref="Extensions"/> property. + /// </summary> + private IList<IExtensionMessage> extensions = new List<IExtensionMessage>(); + + /// <summary> + /// Backing field for the <see cref="IExpiringProtocolMessage.UtcCreationDate"/> property. + /// </summary> + private DateTime creationDateUtc = DateTime.UtcNow; + + /// <summary> + /// Backing store for the <see cref="ReturnToParameters"/> property. + /// </summary> + private IDictionary<string, string> returnToParameters; + + /// <summary> + /// Backing store for the <see cref="ReturnToParametersSignatureValidated"/> property. + /// </summary> + private bool returnToParametersSignatureValidated; + + /// <summary> + /// Initializes a new instance of the <see cref="IndirectSignedResponse"/> class. + /// </summary> + /// <param name="request"> + /// The authentication request that caused this assertion to be generated. + /// </param> + internal IndirectSignedResponse(SignedResponseRequest request) + : base(request, Protocol.Lookup(GetVersion(request)).Args.Mode.id_res) { + ErrorUtilities.VerifyArgumentNotNull(request, "request"); + + this.ReturnTo = request.ReturnTo; + this.ProviderEndpoint = request.Recipient; + ((ITamperResistantOpenIdMessage)this).AssociationHandle = request.AssociationHandle; + } + + /// <summary> + /// Initializes a new instance of the <see cref="IndirectSignedResponse"/> class + /// in order to perform signature verification at the Provider. + /// </summary> + /// <param name="previouslySignedMessage">The previously signed message.</param> + internal IndirectSignedResponse(CheckAuthenticationRequest previouslySignedMessage) + : base(GetVersion(previouslySignedMessage), previouslySignedMessage.ReturnTo, Protocol.Lookup(GetVersion(previouslySignedMessage)).Args.Mode.id_res) { + // Copy all message parts from the check_authentication message into this one, + // except for the openid.mode parameter. + MessageDictionary checkPayload = new MessageDictionary(previouslySignedMessage); + MessageDictionary thisPayload = new MessageDictionary(this); + foreach (var pair in checkPayload) { + if (!string.Equals(pair.Key, this.Protocol.openid.mode)) { + thisPayload[pair.Key] = pair.Value; + } + } + } + + /// <summary> + /// Initializes a new instance of the <see cref="IndirectSignedResponse"/> class + /// for unsolicited assertions. + /// </summary> + /// <param name="version">The OpenID version to use.</param> + /// <param name="relyingPartyReturnTo">The return_to URL of the Relying Party. + /// This value will commonly be from <see cref="SignedResponseRequest.ReturnTo"/>, + /// but for unsolicited assertions may come from the Provider performing RP discovery + /// to find the appropriate return_to URL to use.</param> + internal IndirectSignedResponse(Version version, Uri relyingPartyReturnTo) + : base(version, relyingPartyReturnTo, Protocol.Lookup(version).Args.Mode.id_res) { + } + + #region IProtocolMessageWithExtensions Members + + /// <summary> + /// Gets the list of extensions that are included with this message. + /// </summary> + /// <value></value> + /// <remarks> + /// Implementations of this interface should ensure that this property never returns null. + /// </remarks> + public IList<IExtensionMessage> Extensions { + get { return this.extensions; } + } + + #endregion + + /// <summary> + /// Gets the level of protection this message requires. + /// </summary> + /// <value> + /// <see cref="MessageProtections.All"/> for OpenID 2.0 messages. + /// <see cref="MessageProtections.TamperProtection"/> for OpenID 1.x messages. + /// </value> + /// <remarks> + /// Although the required protection is reduced for OpenID 1.x, + /// this library will provide Relying Party hosts with all protections + /// by adding its own specially-crafted nonce to the authentication request + /// messages. + /// </remarks> + public override MessageProtections RequiredProtection { + // TODO: Fix up Provider side to only use private associations (dumb mode), + // and then to add a special nonce value of its own to provide replay + // protection to the Provider's users even when logging into 1.0 RPs. + // When this is done, remove this conditional getter and always return + // that All protections are required. + get { return this.Version.Major < 2 ? MessageProtections.TamperProtection : MessageProtections.All; } + } + + /// <summary> + /// Gets or sets the message signature. + /// </summary> + /// <value>Base 64 encoded signature calculated as specified in Section 6 (Generating Signatures).</value> + [MessagePart("openid.sig", IsRequired = true, AllowEmpty = false)] + string ITamperResistantProtocolMessage.Signature { get; set; } + + /// <summary> + /// Gets or sets the signed parameter order. + /// </summary> + /// <value>Comma-separated list of signed fields.</value> + /// <example>"op_endpoint,identity,claimed_id,return_to,assoc_handle,response_nonce"</example> + /// <remarks> + /// This entry consists of the fields without the "openid." prefix that the signature covers. + /// This list MUST contain at least "op_endpoint", "return_to" "response_nonce" and "assoc_handle", + /// and if present in the response, "claimed_id" and "identity". + /// Additional keys MAY be signed as part of the message. See Generating Signatures. + /// </remarks> + [MessagePart("openid.signed", IsRequired = true, AllowEmpty = false)] + string ITamperResistantOpenIdMessage.SignedParameterOrder { get; set; } + + /// <summary> + /// Gets or sets the association handle used to sign the message. + /// </summary> + /// <value>The handle for the association that was used to sign this assertion. </value> + [MessagePart("openid.assoc_handle", IsRequired = true, AllowEmpty = false, RequiredProtection = ProtectionLevel.Sign)] + string ITamperResistantOpenIdMessage.AssociationHandle { get; set; } + + /// <summary> + /// Gets or sets the nonce that will protect the message from replay attacks. + /// </summary> + string IReplayProtectedProtocolMessage.Nonce { get; set; } + + /// <summary> + /// Gets or sets the UTC date/time the message was originally sent onto the network. + /// </summary> + /// <remarks> + /// The property setter should ensure a UTC date/time, + /// and throw an exception if this is not possible. + /// </remarks> + /// <exception cref="ArgumentException"> + /// Thrown when a DateTime that cannot be converted to UTC is set. + /// </exception> + DateTime IExpiringProtocolMessage.UtcCreationDate { + get { return this.creationDateUtc; } + set { this.creationDateUtc = value.ToUniversalTime(); } + } + + /// <summary> + /// Gets or sets the association handle that the Provider wants the Relying Party to not use any more. + /// </summary> + /// <value>If the Relying Party sent an invalid association handle with the request, it SHOULD be included here.</value> + [MessagePart("openid.invalidate_handle", IsRequired = false, AllowEmpty = false)] + string ITamperResistantOpenIdMessage.InvalidateHandle { get; set; } + + /// <summary> + /// Gets or sets the Provider Endpoint URI. + /// </summary> + [MessagePart("openid.op_endpoint", IsRequired = true, AllowEmpty = false, RequiredProtection = ProtectionLevel.Sign, MinVersion = "2.0")] + internal Uri ProviderEndpoint { get; set; } + + /// <summary> + /// Gets or sets the return_to parameter as the relying party provided + /// it in <see cref="SignedResponseRequest.ReturnTo"/>. + /// </summary> + /// <value>Verbatim copy of the return_to URL parameter sent in the + /// request, before the Provider modified it. </value> + [MessagePart("openid.return_to", IsRequired = true, AllowEmpty = false, RequiredProtection = ProtectionLevel.Sign, Encoder = typeof(OriginalStringUriEncoder))] + internal Uri ReturnTo { get; set; } + + /// <summary> + /// Gets or sets a value indicating whether the <see cref="ReturnTo"/> + /// URI's query string is unaltered between when the Relying Party + /// sent the original request and when the response was received. + /// </summary> + /// <remarks> + /// This property is not persisted in the transmitted message, and + /// has no effect on the Provider-side of the communication. + /// </remarks> + internal bool ReturnToParametersSignatureValidated { + get { + return this.returnToParametersSignatureValidated; + } + + set { + if (this.returnToParametersSignatureValidated == value) { + return; + } + + this.returnToParametersSignatureValidated = value; + this.returnToParameters = null; + } + } + + /// <summary> + /// Gets or sets the nonce that will protect the message from replay attacks. + /// </summary> + /// <value> + /// <para>A string 255 characters or less in length, that MUST be unique to + /// this particular successful authentication response. The nonce MUST start + /// with the current time on the server, and MAY contain additional ASCII + /// characters in the range 33-126 inclusive (printable non-whitespace characters), + /// as necessary to make each response unique. The date and time MUST be + /// formatted as specified in section 5.6 of [RFC3339] + /// (Klyne, G. and C. Newman, “Date and Time on the Internet: Timestamps,” .), + /// with the following restrictions:</para> + /// <list type="bullet"> + /// <item>All times must be in the UTC timezone, indicated with a "Z".</item> + /// <item>No fractional seconds are allowed</item> + /// </list> + /// </value> + /// <example>2005-05-15T17:11:51ZUNIQUE</example> + [MessagePart("openid.response_nonce", IsRequired = true, AllowEmpty = false, RequiredProtection = ProtectionLevel.Sign, MinVersion = "2.0")] + private string ResponseNonce { + get { + string uniqueFragment = ((IReplayProtectedProtocolMessage)this).Nonce; + return this.creationDateUtc.ToString(PermissibleDateTimeFormats[0], CultureInfo.InvariantCulture) + uniqueFragment; + } + + set { + if (value == null) { + ((IReplayProtectedProtocolMessage)this).Nonce = null; + } else { + int indexOfZ = value.IndexOf("Z", StringComparison.Ordinal); + ErrorUtilities.VerifyProtocol(indexOfZ >= 0, MessagingStrings.UnexpectedMessagePartValue, Protocol.openid.response_nonce, value); + this.creationDateUtc = DateTime.Parse(value.Substring(0, indexOfZ + 1), CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal); + ((IReplayProtectedProtocolMessage)this).Nonce = value.Substring(indexOfZ + 1); + } + } + } + + /// <summary> + /// Gets the querystring key=value pairs in the return_to URL. + /// </summary> + private IDictionary<string, string> ReturnToParameters { + get { + if (this.returnToParameters == null) { + // Only return data that can be validated as untampered with. + if (this.ReturnToParametersSignatureValidated) { + this.returnToParameters = HttpUtility.ParseQueryString(this.ReturnTo.Query).ToDictionary(); + } else { + // Store an empty dictionary since we can't consider any callback data reliable. + this.returnToParameters = new Dictionary<string, string>(0); + } + } + + return this.returnToParameters; + } + } + + /// <summary> + /// Checks the message state for conformity to the protocol specification + /// and throws an exception if the message is invalid. + /// </summary> + /// <remarks> + /// <para>Some messages have required fields, or combinations of fields that must relate to each other + /// in specialized ways. After deserializing a message, this method checks the state of the + /// message to see if it conforms to the protocol.</para> + /// <para>Note that this property should <i>not</i> check signatures or perform any state checks + /// outside this scope of this particular message.</para> + /// </remarks> + /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> + public override void EnsureValidMessage() { + base.EnsureValidMessage(); + + this.VerifyReturnToMatchesRecipient(); + } + + /// <summary> + /// Gets the value of a named parameter in the return_to URL. + /// </summary> + /// <param name="key">The full name of the parameter whose value is being sought.</param> + /// <returns>The value of the parameter if it is present and unaltered from when + /// the Relying Party signed it; <c>null</c> otherwise.</returns> + /// <remarks> + /// This method will always return null on the Provider-side, since Providers + /// cannot verify the private signature made by the relying party. + /// </remarks> + internal string GetReturnToArgument(string key) { + ErrorUtilities.VerifyNonZeroLength(key, "key"); + ErrorUtilities.VerifyInternal(this.ReturnTo != null, "ReturnTo was expected to be required but is null."); + + string value; + this.ReturnToParameters.TryGetValue(key, out value); + return value; + } + + /// <summary> + /// Verifies that the openid.return_to field matches the URL of the actual HTTP request. + /// </summary> + /// <remarks> + /// From OpenId Authentication 2.0 section 11.1: + /// To verify that the "openid.return_to" URL matches the URL that is processing this assertion: + /// * The URL scheme, authority, and path MUST be the same between the two URLs. + /// * Any query parameters that are present in the "openid.return_to" URL MUST + /// also be present with the same values in the URL of the HTTP request the RP received. + /// </remarks> + private void VerifyReturnToMatchesRecipient() { + ErrorUtilities.VerifyProtocol( + string.Equals(this.Recipient.Scheme, this.ReturnTo.Scheme, StringComparison.OrdinalIgnoreCase) && + string.Equals(this.Recipient.Authority, this.ReturnTo.Authority, StringComparison.OrdinalIgnoreCase) && + string.Equals(this.Recipient.AbsolutePath, this.ReturnTo.AbsolutePath, StringComparison.Ordinal), + OpenIdStrings.ReturnToParamDoesNotMatchRequestUrl, + Protocol.openid.return_to, + this.ReturnTo, + this.Recipient); + + NameValueCollection returnToArgs = HttpUtility.ParseQueryString(this.ReturnTo.Query); + NameValueCollection requestArgs = HttpUtility.ParseQueryString(this.Recipient.Query); + ErrorUtilities.VerifyProtocol( + returnToArgs.Keys.Cast<string>().All(returnToKey => string.Equals(returnToArgs[returnToKey], requestArgs[returnToKey], StringComparison.Ordinal)), + OpenIdStrings.ReturnToParamDoesNotMatchRequestUrl, + Protocol.openid.return_to, + this.ReturnTo, + this.Recipient); + } + } +} diff --git a/src/DotNetOpenAuth/OpenId/Messages/NegativeAssertionResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/NegativeAssertionResponse.cs index 0c9e05a..ed25a1d 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/NegativeAssertionResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/NegativeAssertionResponse.cs @@ -1,104 +1,104 @@ -//-----------------------------------------------------------------------
-// <copyright file="NegativeAssertionResponse.cs" company="Andrew Arnott">
-// Copyright (c) Andrew Arnott. All rights reserved.
-// </copyright>
-//-----------------------------------------------------------------------
-
-namespace DotNetOpenAuth.OpenId.Messages {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using DotNetOpenAuth.Messaging;
-
- /// <summary>
- /// The message OpenID Providers send back to Relying Parties to refuse
- /// to assert the identity of a user.
- /// </summary>
- internal class NegativeAssertionResponse : IndirectResponseBase {
- /// <summary>
- /// Initializes a new instance of the <see cref="NegativeAssertionResponse"/> class.
- /// </summary>
- /// <param name="request">The request that the relying party sent.</param>
- internal NegativeAssertionResponse(CheckIdRequest request)
- : base(request, GetMode(request)) {
- }
-
- /// <summary>
- /// Initializes a new instance of the <see cref="NegativeAssertionResponse"/> class.
- /// </summary>
- /// <param name="version">The version.</param>
- /// <param name="relyingPartyReturnTo">The relying party return to.</param>
- /// <param name="mode">The value of the openid.mode parameter.</param>
- internal NegativeAssertionResponse(Version version, Uri relyingPartyReturnTo, string mode)
- : base(version, relyingPartyReturnTo, mode) {
- }
-
- /// <summary>
- /// Gets or sets the URL the relying party can use to upgrade their authentication
- /// request from an immediate to a setup message.
- /// </summary>
- /// <value>URL to redirect User-Agent to so the End User can do whatever's necessary to fulfill the assertion.</value>
- /// <remarks>
- /// This part is only included
- /// </remarks>
- [MessagePart("openid.user_setup_url", AllowEmpty = false, IsRequired = false, MaxVersion = "1.1")]
- internal Uri UserSetupUrl { get; set; }
-
- /// <summary>
- /// Gets a value indicating whether this <see cref="NegativeAssertionResponse"/>
- /// is in response to an authentication request made in immediate mode.
- /// </summary>
- /// <value><c>true</c> if the request was in immediate mode; otherwise, <c>false</c>.</value>
- internal bool Immediate {
- get {
- if (this.OriginatingRequest != null) {
- return this.OriginatingRequest.Immediate;
- } else {
- if (String.Equals(this.Mode, Protocol.Args.Mode.setup_needed, StringComparison.Ordinal)) {
- return true;
- } else if (String.Equals(this.Mode, Protocol.Args.Mode.cancel, StringComparison.Ordinal)) {
- return false;
- } else {
- throw ErrorUtilities.ThrowProtocol(MessagingStrings.UnexpectedMessagePartValue, Protocol.openid.mode, this.Mode);
- }
- }
- }
- }
-
- /// <summary>
- /// Checks the message state for conformity to the protocol specification
- /// and throws an exception if the message is invalid.
- /// </summary>
- /// <remarks>
- /// <para>Some messages have required fields, or combinations of fields that must relate to each other
- /// in specialized ways. After deserializing a message, this method checks the state of the
- /// message to see if it conforms to the protocol.</para>
- /// <para>Note that this property should <i>not</i> check signatures or perform any state checks
- /// outside this scope of this particular message.</para>
- /// </remarks>
- /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception>
- public override void EnsureValidMessage() {
- base.EnsureValidMessage();
-
- // Since there are a couple of negative assertion modes, ensure that the mode given is one of the allowed ones.
- ErrorUtilities.VerifyProtocol(String.Equals(this.Mode, Protocol.Args.Mode.setup_needed, StringComparison.Ordinal) || String.Equals(this.Mode, Protocol.Args.Mode.cancel, StringComparison.Ordinal), MessagingStrings.UnexpectedMessagePartValue, Protocol.openid.mode, this.Mode);
-
- if (this.Immediate && Protocol.Version.Major < 2) {
- ErrorUtilities.VerifyProtocol(this.UserSetupUrl != null, OpenIdStrings.UserSetupUrlRequiredInImmediateNegativeResponse);
- }
- }
-
- /// <summary>
- /// Gets the value for the openid.mode that is appropriate for this response.
- /// </summary>
- /// <param name="request">The request that we're responding to.</param>
- /// <returns>The value of the openid.mode parameter to use.</returns>
- private static string GetMode(CheckIdRequest request) {
- ErrorUtilities.VerifyArgumentNotNull(request, "request");
-
- Protocol protocol = Protocol.Lookup(request.Version);
- return request.Immediate ? protocol.Args.Mode.setup_needed : protocol.Args.Mode.cancel;
- }
- }
-}
+//----------------------------------------------------------------------- +// <copyright file="NegativeAssertionResponse.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.OpenId.Messages { + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; + using DotNetOpenAuth.Messaging; + + /// <summary> + /// The message OpenID Providers send back to Relying Parties to refuse + /// to assert the identity of a user. + /// </summary> + internal class NegativeAssertionResponse : IndirectResponseBase { + /// <summary> + /// Initializes a new instance of the <see cref="NegativeAssertionResponse"/> class. + /// </summary> + /// <param name="request">The request that the relying party sent.</param> + internal NegativeAssertionResponse(CheckIdRequest request) + : base(request, GetMode(request)) { + } + + /// <summary> + /// Initializes a new instance of the <see cref="NegativeAssertionResponse"/> class. + /// </summary> + /// <param name="version">The version.</param> + /// <param name="relyingPartyReturnTo">The relying party return to.</param> + /// <param name="mode">The value of the openid.mode parameter.</param> + internal NegativeAssertionResponse(Version version, Uri relyingPartyReturnTo, string mode) + : base(version, relyingPartyReturnTo, mode) { + } + + /// <summary> + /// Gets or sets the URL the relying party can use to upgrade their authentication + /// request from an immediate to a setup message. + /// </summary> + /// <value>URL to redirect User-Agent to so the End User can do whatever's necessary to fulfill the assertion.</value> + /// <remarks> + /// This part is only included + /// </remarks> + [MessagePart("openid.user_setup_url", AllowEmpty = false, IsRequired = false, MaxVersion = "1.1")] + internal Uri UserSetupUrl { get; set; } + + /// <summary> + /// Gets a value indicating whether this <see cref="NegativeAssertionResponse"/> + /// is in response to an authentication request made in immediate mode. + /// </summary> + /// <value><c>true</c> if the request was in immediate mode; otherwise, <c>false</c>.</value> + internal bool Immediate { + get { + if (this.OriginatingRequest != null) { + return this.OriginatingRequest.Immediate; + } else { + if (String.Equals(this.Mode, Protocol.Args.Mode.setup_needed, StringComparison.Ordinal)) { + return true; + } else if (String.Equals(this.Mode, Protocol.Args.Mode.cancel, StringComparison.Ordinal)) { + return false; + } else { + throw ErrorUtilities.ThrowProtocol(MessagingStrings.UnexpectedMessagePartValue, Protocol.openid.mode, this.Mode); + } + } + } + } + + /// <summary> + /// Checks the message state for conformity to the protocol specification + /// and throws an exception if the message is invalid. + /// </summary> + /// <remarks> + /// <para>Some messages have required fields, or combinations of fields that must relate to each other + /// in specialized ways. After deserializing a message, this method checks the state of the + /// message to see if it conforms to the protocol.</para> + /// <para>Note that this property should <i>not</i> check signatures or perform any state checks + /// outside this scope of this particular message.</para> + /// </remarks> + /// <exception cref="ProtocolException">Thrown if the message is invalid.</exception> + public override void EnsureValidMessage() { + base.EnsureValidMessage(); + + // Since there are a couple of negative assertion modes, ensure that the mode given is one of the allowed ones. + ErrorUtilities.VerifyProtocol(String.Equals(this.Mode, Protocol.Args.Mode.setup_needed, StringComparison.Ordinal) || String.Equals(this.Mode, Protocol.Args.Mode.cancel, StringComparison.Ordinal), MessagingStrings.UnexpectedMessagePartValue, Protocol.openid.mode, this.Mode); + + if (this.Immediate && Protocol.Version.Major < 2) { + ErrorUtilities.VerifyProtocol(this.UserSetupUrl != null, OpenIdStrings.UserSetupUrlRequiredInImmediateNegativeResponse); + } + } + + /// <summary> + /// Gets the value for the openid.mode that is appropriate for this response. + /// </summary> + /// <param name="request">The request that we're responding to.</param> + /// <returns>The value of the openid.mode parameter to use.</returns> + private static string GetMode(CheckIdRequest request) { + ErrorUtilities.VerifyArgumentNotNull(request, "request"); + + Protocol protocol = Protocol.Lookup(request.Version); + return request.Immediate ? protocol.Args.Mode.setup_needed : protocol.Args.Mode.cancel; + } + } +} |