diff options
Diffstat (limited to 'src/DotNetOpenAuth')
48 files changed, 948 insertions, 414 deletions
diff --git a/src/DotNetOpenAuth/ComponentModel/ConverterBase.cs b/src/DotNetOpenAuth/ComponentModel/ConverterBase.cs index 980d90f..c41ac47 100644 --- a/src/DotNetOpenAuth/ComponentModel/ConverterBase.cs +++ b/src/DotNetOpenAuth/ComponentModel/ConverterBase.cs @@ -143,6 +143,7 @@ using System.Reflection; /// <exception cref="T:System.NotSupportedException"> /// The conversion cannot be performed. /// </exception> + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Assume(System.Boolean,System.String,System.String)", Justification = "No localization required.")] public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) { Contract.Assume(destinationType != null, "Missing contract."); if (destinationType.IsInstanceOfType(value)) { diff --git a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd index 626fed3..689ad2e 100644 --- a/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd +++ b/src/DotNetOpenAuth/Configuration/DotNetOpenAuth.xsd @@ -226,6 +226,16 @@ </xs:documentation> </xs:annotation> </xs:attribute> + <xs:attribute name="maximumIndirectMessageUrlLength" type="xs:int" default="2048"> + <xs:annotation> + <xs:documentation> + The maximum allowable size for a 301 Redirect response before we send + a 200 OK response with a scripted form POST with the parameters instead + in order to ensure successfully sending a large payload to another server + that might have a maximum allowable size restriction on its GET request. + </xs:documentation> + </xs:annotation> + </xs:attribute> </xs:complexType> </xs:element> <xs:element name="openid"> @@ -251,6 +261,44 @@ </xs:documentation> </xs:annotation> <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="trustedProviders"> + <xs:complexType> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:element name="add"> + <xs:complexType> + <xs:attribute name="endpoint" type="xs:string" use="required"> + <xs:annotation> + <xs:documentation> + The OpenID Provider Endpoint (aka "OP Endpoint") that this relying party trusts. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + <xs:element name="remove"> + <xs:complexType> + <xs:attribute name="endpoint" type="xs:string" use="required" /> + </xs:complexType> + </xs:element> + <xs:element name="clear"> + <xs:complexType> + <!--tag is empty--> + </xs:complexType> + </xs:element> + </xs:choice> + <xs:attribute name="rejectAssertionsFromUntrustedProviders" type="xs:boolean" default="false"> + <xs:annotation> + <xs:documentation> + A value indicating whether any login attempt coming from an OpenID Provider Endpoint that is not on this + whitelist of trusted OP Endpoints will be rejected. If the trusted providers list is empty and this value + is true, all assertions are rejected. + </xs:documentation> + </xs:annotation> + </xs:attribute> + </xs:complexType> + </xs:element> + </xs:choice> <xs:attribute name="requireSsl" type="xs:boolean" default="false"> <xs:annotation> <xs:documentation> @@ -277,7 +325,7 @@ <xs:attribute name="minimumHashBitLength" type="xs:int"> <xs:annotation> <xs:documentation> - Shared associations with OpenID Providers will only be formed or used if they + Shared associations with OpenID Providers will only be formed or used if they are willing to form associations equal to or greater than a given level of protection. </xs:documentation> </xs:annotation> @@ -532,7 +580,7 @@ so security is comparable to OpenID 2.0 relying parties. </xs:documentation> </xs:annotation> - </xs:attribute> + </xs:attribute> <xs:attribute name="unsolicitedAssertionVerification"> <xs:annotation> <xs:documentation> @@ -743,7 +791,7 @@ </xs:documentation> </xs:annotation> <xs:complexType> - + </xs:complexType> </xs:element> </xs:choice> @@ -864,7 +912,7 @@ <xs:attribute name="includeEventStatistics" type="xs:boolean" default="true"> <xs:annotation> <xs:documentation> - Whether a set of counters that track how often certain events (such as an + Whether a set of counters that track how often certain events (such as an successful or failed authentication) is included in the report. </xs:documentation> </xs:annotation> diff --git a/src/DotNetOpenAuth/Configuration/MessagingElement.cs b/src/DotNetOpenAuth/Configuration/MessagingElement.cs index fae18ec..24c0953 100644 --- a/src/DotNetOpenAuth/Configuration/MessagingElement.cs +++ b/src/DotNetOpenAuth/Configuration/MessagingElement.cs @@ -42,6 +42,20 @@ namespace DotNetOpenAuth.Configuration { private const string StrictConfigName = "strict"; /// <summary> + /// The default value for the <see cref="MaximumIndirectMessageUrlLength"/> property. + /// </summary> + /// <value> + /// 2KB, recommended by OpenID group + /// </value> + private const int DefaultMaximumIndirectMessageUrlLength = 2 * 1024; + + /// <summary> + /// The name of the attribute that controls the maximum length of a URL before it is converted + /// to a POST payload. + /// </summary> + private const string MaximumIndirectMessageUrlLengthConfigName = "maximumIndirectMessageUrlLength"; + + /// <summary> /// Gets the actual maximum message lifetime that a program should allow. /// </summary> /// <value>The sum of the <see cref="MaximumMessageLifetime"/> and @@ -129,5 +143,19 @@ namespace DotNetOpenAuth.Configuration { get { return (UntrustedWebRequestElement)this[UntrustedWebRequestElementName] ?? new UntrustedWebRequestElement(); } set { this[UntrustedWebRequestElementName] = value; } } + + /// <summary> + /// Gets or sets the maximum allowable size for a 301 Redirect response before we send + /// a 200 OK response with a scripted form POST with the parameters instead + /// in order to ensure successfully sending a large payload to another server + /// that might have a maximum allowable size restriction on its GET request. + /// </summary> + /// <value>The default value is 2048.</value> + [ConfigurationProperty(MaximumIndirectMessageUrlLengthConfigName, DefaultValue = DefaultMaximumIndirectMessageUrlLength)] + [IntegerValidator(MinValue = 500, MaxValue = 4096)] + internal int MaximumIndirectMessageUrlLength { + get { return (int)this[MaximumIndirectMessageUrlLengthConfigName]; } + set { this[MaximumIndirectMessageUrlLengthConfigName] = value; } + } } } diff --git a/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs b/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs index 1bf2ebc..4347e2c 100644 --- a/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs +++ b/src/DotNetOpenAuth/Configuration/OpenIdRelyingPartySecuritySettingsElement.cs @@ -81,6 +81,11 @@ namespace DotNetOpenAuth.Configuration { private const string ProtectDownlevelReplayAttacksConfigName = "protectDownlevelReplayAttacks"; /// <summary> + /// The name of the <trustedProviders> sub-element. + /// </summary> + private const string TrustedProvidersElementName = "trustedProviders"; + + /// <summary> /// Initializes a new instance of the <see cref="OpenIdRelyingPartySecuritySettingsElement"/> class. /// </summary> public OpenIdRelyingPartySecuritySettingsElement() { @@ -235,6 +240,16 @@ namespace DotNetOpenAuth.Configuration { } /// <summary> + /// Gets or sets the set of trusted OpenID Provider Endpoints. + /// </summary> + [ConfigurationProperty(TrustedProvidersElementName, IsDefaultCollection = false)] + [ConfigurationCollection(typeof(TrustedProviderConfigurationCollection))] + public TrustedProviderConfigurationCollection TrustedProviders { + get { return (TrustedProviderConfigurationCollection)this[TrustedProvidersElementName] ?? new TrustedProviderConfigurationCollection(); } + set { this[TrustedProvidersElementName] = value; } + } + + /// <summary> /// Initializes a programmatically manipulatable bag of these security settings with the settings from the config file. /// </summary> /// <returns>The newly created security settings object.</returns> @@ -256,6 +271,11 @@ namespace DotNetOpenAuth.Configuration { settings.AllowApproximateIdentifierDiscovery = this.AllowApproximateIdentifierDiscovery; settings.ProtectDownlevelReplayAttacks = this.ProtectDownlevelReplayAttacks; + settings.RejectAssertionsFromUntrustedProviders = this.TrustedProviders.RejectAssertionsFromUntrustedProviders; + foreach (TrustedProviderEndpointConfigurationElement opEndpoint in this.TrustedProviders) { + settings.TrustedProviderEndpoints.Add(opEndpoint.ProviderEndpoint); + } + return settings; } } diff --git a/src/DotNetOpenAuth/Configuration/TrustedProviderConfigurationCollection.cs b/src/DotNetOpenAuth/Configuration/TrustedProviderConfigurationCollection.cs new file mode 100644 index 0000000..f5e62f4 --- /dev/null +++ b/src/DotNetOpenAuth/Configuration/TrustedProviderConfigurationCollection.cs @@ -0,0 +1,74 @@ +//----------------------------------------------------------------------- +// <copyright file="TrustedProviderConfigurationCollection.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Configuration { + using System; + using System.Collections.Generic; + using System.Configuration; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + + /// <summary> + /// A configuration collection of trusted OP Endpoints. + /// </summary> + internal class TrustedProviderConfigurationCollection : ConfigurationElementCollection { + /// <summary> + /// The name of the "rejectAssertionsFromUntrustedProviders" element. + /// </summary> + private const string RejectAssertionsFromUntrustedProvidersConfigName = "rejectAssertionsFromUntrustedProviders"; + + /// <summary> + /// Initializes a new instance of the <see cref="TrustedProviderConfigurationCollection"/> class. + /// </summary> + internal TrustedProviderConfigurationCollection() { + } + + /// <summary> + /// Initializes a new instance of the <see cref="TrustedProviderConfigurationCollection"/> class. + /// </summary> + /// <param name="elements">The elements to initialize the collection with.</param> + [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors", Justification = "Seems unavoidable")] + internal TrustedProviderConfigurationCollection(IEnumerable<TrustedProviderEndpointConfigurationElement> elements) { + Contract.Requires<ArgumentNullException>(elements != null); + + foreach (TrustedProviderEndpointConfigurationElement element in elements) { + this.BaseAdd(element); + } + } + + /// <summary> + /// Gets or sets a value indicating whether any login attempt coming from an OpenID Provider Endpoint that is not on this + /// whitelist of trusted OP Endpoints will be rejected. If the trusted providers list is empty and this value + /// is true, all assertions are rejected. + /// </summary> + [ConfigurationProperty(RejectAssertionsFromUntrustedProvidersConfigName, DefaultValue = false)] + internal bool RejectAssertionsFromUntrustedProviders { + get { return (bool)this[RejectAssertionsFromUntrustedProvidersConfigName]; } + set { this[RejectAssertionsFromUntrustedProvidersConfigName] = value; } + } + + /// <summary> + /// When overridden in a derived class, creates a new <see cref="T:System.Configuration.ConfigurationElement"/>. + /// </summary> + /// <returns> + /// A new <see cref="T:System.Configuration.ConfigurationElement"/>. + /// </returns> + protected override ConfigurationElement CreateNewElement() { + return new TrustedProviderEndpointConfigurationElement(); + } + + /// <summary> + /// Gets the element key for a specified configuration element when overridden in a derived class. + /// </summary> + /// <param name="element">The <see cref="T:System.Configuration.ConfigurationElement"/> to return the key for.</param> + /// <returns> + /// An <see cref="T:System.Object"/> that acts as the key for the specified <see cref="T:System.Configuration.ConfigurationElement"/>. + /// </returns> + protected override object GetElementKey(ConfigurationElement element) { + return ((TrustedProviderEndpointConfigurationElement)element).ProviderEndpoint; + } + } +} diff --git a/src/DotNetOpenAuth/Configuration/TrustedProviderEndpointConfigurationElement.cs b/src/DotNetOpenAuth/Configuration/TrustedProviderEndpointConfigurationElement.cs new file mode 100644 index 0000000..2576eb0 --- /dev/null +++ b/src/DotNetOpenAuth/Configuration/TrustedProviderEndpointConfigurationElement.cs @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------- +// <copyright file="TrustedProviderEndpointConfigurationElement.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Configuration { + using System; + using System.Configuration; + + /// <summary> + /// A configuration element that records a trusted Provider Endpoint. + /// </summary> + internal class TrustedProviderEndpointConfigurationElement : ConfigurationElement { + /// <summary> + /// The name of the attribute that stores the <see cref="ProviderEndpoint"/> value. + /// </summary> + private const string ProviderEndpointConfigName = "endpoint"; + + /// <summary> + /// Initializes a new instance of the <see cref="TrustedProviderEndpointConfigurationElement"/> class. + /// </summary> + public TrustedProviderEndpointConfigurationElement() { + } + + /// <summary> + /// Gets or sets the OpenID Provider Endpoint (aka "OP Endpoint") that this relying party trusts. + /// </summary> + [ConfigurationProperty(ProviderEndpointConfigName, IsRequired = true, IsKey = true)] + public Uri ProviderEndpoint { + get { return (Uri)this[ProviderEndpointConfigName]; } + set { this[ProviderEndpointConfigName] = value; } + } + } +} diff --git a/src/DotNetOpenAuth/DotNetOpenAuth.csproj b/src/DotNetOpenAuth/DotNetOpenAuth.csproj index bfc10a1..574bd53 100644 --- a/src/DotNetOpenAuth/DotNetOpenAuth.csproj +++ b/src/DotNetOpenAuth/DotNetOpenAuth.csproj @@ -84,7 +84,7 @@ http://opensource.org/licenses/ms-pl.html <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs> <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions> <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly> - <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet>Migrated rules for DotNetOpenAuth.ruleset</CodeAnalysisRuleSet> <CodeContractsExtraRewriteOptions /> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> @@ -125,7 +125,7 @@ http://opensource.org/licenses/ms-pl.html <CodeContractsEmitXMLDocs>True</CodeContractsEmitXMLDocs> <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions> <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly> - <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> + <CodeAnalysisRuleSet>Migrated rules for DotNetOpenAuth.ruleset</CodeAnalysisRuleSet> <CodeContractsExtraRewriteOptions /> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseNoUI|AnyCPU'"> @@ -165,6 +165,7 @@ http://opensource.org/licenses/ms-pl.html <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions> <CodeContractsReferenceAssembly>Build</CodeContractsReferenceAssembly> <CodeContractsExtraRewriteOptions /> + <CodeAnalysisRuleSet>Migrated rules for DotNetOpenAuth.ruleset</CodeAnalysisRuleSet> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'CodeAnalysis|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -181,7 +182,7 @@ http://opensource.org/licenses/ms-pl.html </CodeContractsCustomRewriterAssembly> <CodeContractsCustomRewriterClass> </CodeContractsCustomRewriterClass> - <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel> + <CodeContractsRuntimeCheckingLevel>Preconditions</CodeContractsRuntimeCheckingLevel> <CodeContractsRunCodeAnalysis>True</CodeContractsRunCodeAnalysis> <CodeContractsBuildReferenceAssembly>True</CodeContractsBuildReferenceAssembly> <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations> @@ -296,6 +297,8 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="Configuration\OpenIdRelyingPartyElement.cs" /> <Compile Include="Configuration\OpenIdRelyingPartySecuritySettingsElement.cs" /> <Compile Include="Configuration\ReportingElement.cs" /> + <Compile Include="Configuration\TrustedProviderConfigurationCollection.cs" /> + <Compile Include="Configuration\TrustedProviderEndpointConfigurationElement.cs" /> <Compile Include="Configuration\TypeConfigurationCollection.cs" /> <Compile Include="Configuration\TypeConfigurationElement.cs" /> <Compile Include="Configuration\UntrustedWebRequestElement.cs" /> @@ -318,6 +321,7 @@ http://opensource.org/licenses/ms-pl.html <Compile Include="Messaging\CachedDirectWebResponse.cs" /> <Compile Include="Messaging\ChannelContract.cs" /> <Compile Include="Messaging\IHttpIndirectResponse.cs" /> + <Compile Include="Messaging\IMessageOriginalPayload.cs" /> <Compile Include="Messaging\DirectWebRequestOptions.cs" /> <Compile Include="Messaging\EnumerableCache.cs" /> <Compile Include="Messaging\HostErrorException.cs" /> @@ -866,10 +870,11 @@ http://opensource.org/licenses/ms-pl.html OutputFile="$(ILMergeOutputAssembly)" KeyFile="$(PublicKeyFile)" DelaySign="true" + ToolPath="$(ProjectRoot)tools\ILMerge" TargetPlatformVersion="$(ClrVersion).0" TargetPlatformDirectory="$(ILMergeTargetPlatformDirectory)" /> </Target> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(ProjectRoot)tools\DotNetOpenAuth.targets" /> <Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))\EnlistmentInfo.targets" Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildProjectDirectory), EnlistmentInfo.targets))' != '' " /> -</Project>
\ No newline at end of file +</Project> diff --git a/src/DotNetOpenAuth/GlobalSuppressions.cs b/src/DotNetOpenAuth/GlobalSuppressions.cs index 9b1bcfa..8539422 100644 --- a/src/DotNetOpenAuth/GlobalSuppressions.cs +++ b/src/DotNetOpenAuth/GlobalSuppressions.cs @@ -9,54 +9,61 @@ // "In Project Suppression File". // You do not need to add suppressions to this file manually. -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sha", Scope = "type", Target = "DotNetOpenAuth.OAuth.ChannelElements.HmacSha1SigningBindingElement")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hmac", Scope = "type", Target = "DotNetOpenAuth.OAuth.ChannelElements.HmacSha1SigningBindingElement")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Rsa", Scope = "type", Target = "DotNetOpenAuth.OAuth.ChannelElements.RsaSha1SigningBindingElement")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sha", Scope = "type", Target = "DotNetOpenAuth.OAuth.ChannelElements.RsaSha1SigningBindingElement")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "Diffie-Hellman", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "checkInput", Scope = "member", Target = "Org.Mentalis.Security.Cryptography.DiffieHellmanManaged.#Initialize(Mono.Math.BigInteger,Mono.Math.BigInteger,Mono.Math.BigInteger,System.Int32,System.Boolean)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Org.Mentalis.Security.Cryptography.DiffieHellmanManaged.#.ctor(System.Int32,System.Int32,Org.Mentalis.Security.Cryptography.DHKeyGeneration)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Org.Mentalis.Security.Cryptography.DiffieHellmanManaged.#.ctor(System.Byte[],System.Byte[],System.Int32)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Org.Mentalis.Security.Cryptography.DiffieHellmanManaged.#.ctor(System.Byte[],System.Byte[],System.Byte[])")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Org.Mentalis.Security.Cryptography.DiffieHellman.#FromXmlString(System.String)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "PostTrialDivisionTest", Scope = "member", Target = "Mono.Math.Prime.Generator.SequentialSearchPrimeGeneratorBase.#GenerateNewPrime(System.Int32,System.Object)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes", Scope = "member", Target = "Mono.Math.Prime.PrimalityTests.#GetSPPRounds(Mono.Math.BigInteger,Mono.Math.Prime.ConfidenceFactor)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes", Scope = "member", Target = "Mono.Math.BigInteger+ModulusRing.#BarrettReduction(Mono.Math.BigInteger)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes", Scope = "member", Target = "Mono.Math.BigInteger.#op_Multiply(Mono.Math.BigInteger,Mono.Math.BigInteger)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "sign", Scope = "member", Target = "Mono.Math.BigInteger.#.ctor(Mono.Math.BigInteger+Sign,System.UInt32)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "notUsed", Scope = "member", Target = "Mono.Math.BigInteger.#isProbablePrime(System.Int32)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "returnto", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "openid", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "claimedid", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xri", Scope = "type", Target = "DotNetOpenAuth.OpenId.XriIdentifier")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "yyyy-MM-dd", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "usersetupurl", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "birthdate", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "rehydrated", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.Messaging.Bindings")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.ChannelElements")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Extensions")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Extensions.SimpleRegistration")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Messages")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames", Justification = "We sign it when producing drops.")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Extensions.OAuth")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Extensions.UI")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.Messaging.Reflection")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "oauthverifier", Scope = "resource", Target = "DotNetOpenAuth.OAuth.OAuthStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "whitelist", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "icam", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "idmanagement", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "no-pii", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "req", Scope = "member", Target = "DotNetOpenAuth.OpenId.Provider.IAuthenticationRequestContract.#DotNetOpenAuth.OpenId.Provider.IAuthenticationRequest.ClaimedIdentifier")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "runat", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.RelyingParty.IRelyingPartyBehavior.OnOutgoingAuthenticationRequest(DotNetOpenAuth.OpenId.RelyingParty.IAuthenticationRequest)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.RelyingParty.IRelyingPartyBehavior.OnIncomingPositiveAssertion(DotNetOpenAuth.OpenId.RelyingParty.IAuthenticationResponse)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.RelyingParty.IRelyingPartyBehavior.ApplySecuritySettings(DotNetOpenAuth.OpenId.RelyingParty.RelyingPartySecuritySettings)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.Provider.IProviderBehavior.OnOutgoingResponse(DotNetOpenAuth.OpenId.Provider.IAuthenticationRequest)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.Provider.IProviderBehavior.OnIncomingRequest(DotNetOpenAuth.OpenId.Provider.IRequest)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.Provider.IProviderBehavior.ApplySecuritySettings(DotNetOpenAuth.OpenId.Provider.ProviderSecuritySettings)")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2243:AttributeStringLiteralsShouldParseCorrectly")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.Mvc")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Mvc", Scope = "namespace", Target = "DotNetOpenAuth.Mvc")] -[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")] +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sha", Scope = "type", Target = "DotNetOpenAuth.OAuth.ChannelElements.HmacSha1SigningBindingElement")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Hmac", Scope = "type", Target = "DotNetOpenAuth.OAuth.ChannelElements.HmacSha1SigningBindingElement")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Rsa", Scope = "type", Target = "DotNetOpenAuth.OAuth.ChannelElements.RsaSha1SigningBindingElement")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Sha", Scope = "type", Target = "DotNetOpenAuth.OAuth.ChannelElements.RsaSha1SigningBindingElement")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "Diffie-Hellman", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "checkInput", Scope = "member", Target = "Org.Mentalis.Security.Cryptography.DiffieHellmanManaged.#Initialize(Mono.Math.BigInteger,Mono.Math.BigInteger,Mono.Math.BigInteger,System.Int32,System.Boolean)")] +[assembly: SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Org.Mentalis.Security.Cryptography.DiffieHellmanManaged.#.ctor(System.Int32,System.Int32,Org.Mentalis.Security.Cryptography.DHKeyGeneration)")] +[assembly: SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Org.Mentalis.Security.Cryptography.DiffieHellmanManaged.#.ctor(System.Byte[],System.Byte[],System.Int32)")] +[assembly: SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Org.Mentalis.Security.Cryptography.DiffieHellmanManaged.#.ctor(System.Byte[],System.Byte[],System.Byte[])")] +[assembly: SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Scope = "member", Target = "Org.Mentalis.Security.Cryptography.DiffieHellman.#FromXmlString(System.String)")] +[assembly: SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "PostTrialDivisionTest", Scope = "member", Target = "Mono.Math.Prime.Generator.SequentialSearchPrimeGeneratorBase.#GenerateNewPrime(System.Int32,System.Object)")] +[assembly: SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes", Scope = "member", Target = "Mono.Math.Prime.PrimalityTests.#GetSPPRounds(Mono.Math.BigInteger,Mono.Math.Prime.ConfidenceFactor)")] +[assembly: SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes", Scope = "member", Target = "Mono.Math.BigInteger+ModulusRing.#BarrettReduction(Mono.Math.BigInteger)")] +[assembly: SuppressMessage("Microsoft.Usage", "CA2201:DoNotRaiseReservedExceptionTypes", Scope = "member", Target = "Mono.Math.BigInteger.#op_Multiply(Mono.Math.BigInteger,Mono.Math.BigInteger)")] +[assembly: SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "sign", Scope = "member", Target = "Mono.Math.BigInteger.#.ctor(Mono.Math.BigInteger+Sign,System.UInt32)")] +[assembly: SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "notUsed", Scope = "member", Target = "Mono.Math.BigInteger.#isProbablePrime(System.Int32)")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "returnto", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "openid", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "claimedid", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Xri", Scope = "type", Target = "DotNetOpenAuth.OpenId.XriIdentifier")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "yyyy-MM-dd", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "usersetupurl", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "birthdate", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "rehydrated", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.Messaging.Bindings")] +[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.ChannelElements")] +[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Extensions")] +[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Extensions.SimpleRegistration")] +[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Messages")] +[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Extensions.ProviderAuthenticationPolicy")] +[assembly: SuppressMessage("Microsoft.Design", "CA2210:AssembliesShouldHaveValidStrongNames", Justification = "We sign it when producing drops.")] +[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Extensions.OAuth")] +[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.OpenId.Extensions.UI")] +[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.Messaging.Reflection")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "oauthverifier", Scope = "resource", Target = "DotNetOpenAuth.OAuth.OAuthStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "whitelist", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "icam", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "idmanagement", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "no-pii", Scope = "resource", Target = "DotNetOpenAuth.OpenId.Behaviors.BehaviorStrings.resources")] +[assembly: SuppressMessage("Microsoft.Performance", "CA1804:RemoveUnusedLocals", MessageId = "req", Scope = "member", Target = "DotNetOpenAuth.OpenId.Provider.IAuthenticationRequestContract.#DotNetOpenAuth.OpenId.Provider.IAuthenticationRequest.ClaimedIdentifier")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "runat", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.RelyingParty.IRelyingPartyBehavior.OnOutgoingAuthenticationRequest(DotNetOpenAuth.OpenId.RelyingParty.IAuthenticationRequest)")] +[assembly: SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.RelyingParty.IRelyingPartyBehavior.OnIncomingPositiveAssertion(DotNetOpenAuth.OpenId.RelyingParty.IAuthenticationResponse)")] +[assembly: SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.RelyingParty.IRelyingPartyBehavior.ApplySecuritySettings(DotNetOpenAuth.OpenId.RelyingParty.RelyingPartySecuritySettings)")] +[assembly: SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.Provider.IProviderBehavior.OnOutgoingResponse(DotNetOpenAuth.OpenId.Provider.IAuthenticationRequest)")] +[assembly: SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.Provider.IProviderBehavior.OnIncomingRequest(DotNetOpenAuth.OpenId.Provider.IRequest)")] +[assembly: SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes", Scope = "member", Target = "DotNetOpenAuth.OpenId.Behaviors.AXFetchAsSregTransform.#DotNetOpenAuth.OpenId.Provider.IProviderBehavior.ApplySecuritySettings(DotNetOpenAuth.OpenId.Provider.ProviderSecuritySettings)")] +[assembly: SuppressMessage("Microsoft.Usage", "CA2243:AttributeStringLiteralsShouldParseCorrectly")] +[assembly: SuppressMessage("Microsoft.Design", "CA1020:AvoidNamespacesWithFewTypes", Scope = "namespace", Target = "DotNetOpenAuth.Mvc")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Mvc", Scope = "namespace", Target = "DotNetOpenAuth.Mvc")] +[assembly: SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Web.Routing, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")] +[assembly: SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Scope = "member", Target = "DotNetOpenAuth.OpenId.DiffieHellmanUtilities.#.cctor()")] +[assembly: SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Scope = "member", Target = "DotNetOpenAuth.OAuth.Messages.SignedMessageBase.#DotNetOpenAuth.Messaging.IMessageOriginalPayload.OriginalPayload")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "iframe", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1703:ResourceStringsShouldBeSpelledCorrectly", MessageId = "Sig", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] +[assembly: SuppressMessage("Microsoft.Naming", "CA1701:ResourceStringCompoundWordsShouldBeCasedCorrectly", MessageId = "DSig", Scope = "resource", Target = "DotNetOpenAuth.OpenId.OpenIdStrings.resources")] diff --git a/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs b/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs index 2ac2b7e..3dd892a 100644 --- a/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs +++ b/src/DotNetOpenAuth/InfoCard/ReceivingTokenEventArgs.cs @@ -71,6 +71,7 @@ namespace DotNetOpenAuth.InfoCard { /// Adds an X.509 certificate with a private key that may be used to decrypt the incoming token. /// </summary> /// <param name="certificate">The certificate.</param> + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive")] public void AddDecryptingToken(X509Certificate2 certificate) { Contract.Requires<ArgumentNullException>(certificate != null); Contract.Requires<ArgumentException>(certificate.HasPrivateKey); diff --git a/src/DotNetOpenAuth/InfoCard/Token/Token.cs b/src/DotNetOpenAuth/InfoCard/Token/Token.cs index 89fa3a3..3b6f573 100644 --- a/src/DotNetOpenAuth/InfoCard/Token/Token.cs +++ b/src/DotNetOpenAuth/InfoCard/Token/Token.cs @@ -41,6 +41,7 @@ namespace DotNetOpenAuth.InfoCard { /// <param name="audience">The audience. May be <c>null</c> to avoid audience checking.</param> /// <param name="decryptor">The decryptor to use to decrypt the token, if necessary..</param> /// <exception cref="InformationCardException">Thrown for any problem decoding or decrypting the token.</exception> + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Not a problem for this type."), SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive")] private Token(string tokenXml, Uri audience, TokenDecryptor decryptor) { Contract.Requires<ArgumentException>(!String.IsNullOrEmpty(tokenXml)); Contract.Requires<ArgumentException>(decryptor != null || !IsEncrypted(tokenXml)); @@ -64,7 +65,14 @@ namespace DotNetOpenAuth.InfoCard { } } - this.Xml = new XPathDocument(new StringReader(decryptedString)).CreateNavigator(); + var stringReader = new StringReader(decryptedString); + try { + this.Xml = new XPathDocument(stringReader).CreateNavigator(); + } catch { + stringReader.Dispose(); + throw; + } + Logger.InfoCard.DebugFormat("Incoming SAML token, after any decryption: {0}", this.Xml.InnerXml); this.AuthorizationContext = TokenUtility.AuthenticateToken(this.Xml.ReadSubtree(), audience); } @@ -191,13 +199,26 @@ namespace DotNetOpenAuth.InfoCard { /// <returns> /// <c>true</c> if the specified token XML is encrypted; otherwise, <c>false</c>. /// </returns> - [Pure] + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive"), Pure] internal static bool IsEncrypted(string tokenXml) { Contract.Requires<ArgumentNullException>(tokenXml != null); - using (XmlReader tokenReader = XmlReader.Create(new StringReader(tokenXml))) { + var stringReader = new StringReader(tokenXml); + XmlReader tokenReader; + try { + tokenReader = XmlReader.Create(stringReader); + } catch { + stringReader.Dispose(); + throw; + } + + try { Contract.Assume(tokenReader != null); // CC missing for XmlReader.Create return IsEncrypted(tokenReader); + } catch { + IDisposable disposableReader = tokenReader; + disposableReader.Dispose(); + throw; } } diff --git a/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs b/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs index c9bc1d3..111d636 100644 --- a/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs +++ b/src/DotNetOpenAuth/Messaging/CachedDirectWebResponse.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.Messaging { using System; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.IO; using System.Net; @@ -156,6 +157,7 @@ namespace DotNetOpenAuth.Messaging { /// <param name="response">The response whose stream is to be cloned.</param> /// <param name="maximumBytesToRead">The maximum bytes to cache.</param> /// <returns>The seekable Stream instance that contains a copy of what was returned in the HTTP response.</returns> + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Assume(System.Boolean,System.String,System.String)", Justification = "No localization required.")] private static MemoryStream CacheNetworkStreamAndClose(HttpWebResponse response, int maximumBytesToRead) { Contract.Requires<ArgumentNullException>(response != null); Contract.Ensures(Contract.Result<MemoryStream>() != null); @@ -163,15 +165,20 @@ namespace DotNetOpenAuth.Messaging { // Now read and cache the network stream Stream networkStream = response.GetResponseStream(); MemoryStream cachedStream = new MemoryStream(response.ContentLength < 0 ? 4 * 1024 : Math.Min((int)response.ContentLength, maximumBytesToRead)); - Contract.Assume(networkStream.CanRead, "HttpWebResponse.GetResponseStream() always returns a readable stream."); // CC missing - Contract.Assume(cachedStream.CanWrite, "This is a MemoryStream -- it's always writable."); // CC missing - networkStream.CopyTo(cachedStream); - cachedStream.Seek(0, SeekOrigin.Begin); - - networkStream.Dispose(); - response.Close(); - - return cachedStream; + try { + Contract.Assume(networkStream.CanRead, "HttpWebResponse.GetResponseStream() always returns a readable stream."); // CC missing + Contract.Assume(cachedStream.CanWrite, "This is a MemoryStream -- it's always writable."); // CC missing + networkStream.CopyTo(cachedStream); + cachedStream.Seek(0, SeekOrigin.Begin); + + networkStream.Dispose(); + response.Close(); + + return cachedStream; + } catch { + cachedStream.Dispose(); + throw; + } } } } diff --git a/src/DotNetOpenAuth/Messaging/Channel.cs b/src/DotNetOpenAuth/Messaging/Channel.cs index 95ee5f5..f9961bf 100644 --- a/src/DotNetOpenAuth/Messaging/Channel.cs +++ b/src/DotNetOpenAuth/Messaging/Channel.cs @@ -27,6 +27,7 @@ namespace DotNetOpenAuth.Messaging { /// <summary> /// Manages sending direct messages to a remote party and receiving responses. /// </summary> + [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Unavoidable.")] [ContractVerification(true)] [ContractClass(typeof(ChannelContract))] public abstract class Channel : IDisposable { @@ -59,14 +60,6 @@ namespace DotNetOpenAuth.Messaging { protected internal static readonly ContentType HttpFormUrlEncodedContentType = new ContentType(HttpFormUrlEncoded) { CharSet = PostEntityEncoding.WebName }; /// <summary> - /// The maximum allowable size for a 301 Redirect response before we send - /// a 200 OK response with a scripted form POST with the parameters instead - /// in order to ensure successfully sending a large payload to another server - /// that might have a maximum allowable size restriction on its GET request. - /// </summary> - private const int IndirectMessageGetToPostThreshold = 2 * 1024; // 2KB, recommended by OpenID group - - /// <summary> /// The HTML that should be returned to the user agent as part of a 301 Redirect. /// </summary> /// <value>A string that should be used as the first argument to String.Format, where the {0} should be replaced with the URL to redirect to.</value> @@ -132,6 +125,11 @@ namespace DotNetOpenAuth.Messaging { private RequestCachePolicy cachePolicy = new HttpRequestCachePolicy(HttpRequestCacheLevel.NoCacheNoStore); /// <summary> + /// Backing field for the <see cref="MaximumIndirectMessageUrlLength"/> property. + /// </summary> + private int maximumIndirectMessageUrlLength = Configuration.DotNetOpenAuthSection.Configuration.Messaging.MaximumIndirectMessageUrlLength; + + /// <summary> /// Initializes a new instance of the <see cref="Channel"/> class. /// </summary> /// <param name="messageTypeProvider"> @@ -176,6 +174,24 @@ namespace DotNetOpenAuth.Messaging { public IDirectWebRequestHandler WebRequestHandler { get; set; } /// <summary> + /// Gets or sets the maximum allowable size for a 301 Redirect response before we send + /// a 200 OK response with a scripted form POST with the parameters instead + /// in order to ensure successfully sending a large payload to another server + /// that might have a maximum allowable size restriction on its GET request. + /// </summary> + /// <value>The default value is 2048.</value> + public int MaximumIndirectMessageUrlLength { + get { + return this.maximumIndirectMessageUrlLength; + } + + set { + Contract.Requires<ArgumentOutOfRangeException>(value >= 500 && value <= 4096); + this.maximumIndirectMessageUrlLength = value; + } + } + + /// <summary> /// Gets or sets the message descriptions. /// </summary> internal virtual MessageDescriptionCollection MessageDescriptions { @@ -767,7 +783,7 @@ namespace DotNetOpenAuth.Messaging { // First try creating a 301 redirect, and fallback to a form POST // if the message is too big. response = this.Create301RedirectResponse(message, fields, payloadInFragment); - tooLargeForGet = response.Headers[HttpResponseHeader.Location].Length > IndirectMessageGetToPostThreshold; + tooLargeForGet = response.Headers[HttpResponseHeader.Location].Length > this.MaximumIndirectMessageUrlLength; } // Make sure that if the message is too large for GET that POST is allowed. diff --git a/src/DotNetOpenAuth/Messaging/IMessageOriginalPayload.cs b/src/DotNetOpenAuth/Messaging/IMessageOriginalPayload.cs new file mode 100644 index 0000000..d18be20 --- /dev/null +++ b/src/DotNetOpenAuth/Messaging/IMessageOriginalPayload.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------- +// <copyright file="IMessageOriginalPayload.cs" company="Andrew Arnott"> +// Copyright (c) Andrew Arnott. All rights reserved. +// </copyright> +//----------------------------------------------------------------------- + +namespace DotNetOpenAuth.Messaging { + using System; + using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; + using System.Text; + + /// <summary> + /// An interface that appears on messages that need to retain a description of + /// what their literal payload was when they were deserialized. + /// </summary> + [ContractClass(typeof(IMessageOriginalPayloadContract))] + public interface IMessageOriginalPayload { + /// <summary> + /// Gets or sets the original message parts, before any normalization or default values were assigned. + /// </summary> + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "By design")] + IDictionary<string, string> OriginalPayload { get; set; } + } + + /// <summary> + /// Code contract for the <see cref="IMessageOriginalPayload"/> interface. + /// </summary> + [ContractClassFor(typeof(IMessageOriginalPayload))] + internal abstract class IMessageOriginalPayloadContract : IMessageOriginalPayload { + /// <summary> + /// Gets or sets the original message parts, before any normalization or default values were assigned. + /// </summary> + IDictionary<string, string> IMessageOriginalPayload.OriginalPayload { + get { throw new NotImplementedException(); } + set { throw new NotImplementedException(); } + } + } +} diff --git a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs index d6448ae..0ad3da5 100644 --- a/src/DotNetOpenAuth/Messaging/MessageSerializer.cs +++ b/src/DotNetOpenAuth/Messaging/MessageSerializer.cs @@ -176,7 +176,13 @@ namespace DotNetOpenAuth.Messaging { } catch (ArgumentException ex) { throw ErrorUtilities.Wrap(ex, MessagingStrings.ErrorDeserializingMessage, this.messageType.Name); } + messageDictionary.Message.EnsureValidMessage(); + + var originalPayloadMessage = messageDictionary.Message as IMessageOriginalPayload; + if (originalPayloadMessage != null) { + originalPayloadMessage.OriginalPayload = fields; + } } /// <summary> diff --git a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs index 402db28..d2e0add 100644 --- a/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs +++ b/src/DotNetOpenAuth/Messaging/MessagingUtilities.cs @@ -829,9 +829,14 @@ namespace DotNetOpenAuth.Messaging { Contract.Requires<ArgumentException>(copyFrom.CanRead); MemoryStream copyTo = new MemoryStream(copyFrom.CanSeek ? (int)copyFrom.Length : 4 * 1024); - copyFrom.CopyTo(copyTo); - copyTo.Position = 0; - return copyTo; + try { + copyFrom.CopyTo(copyTo); + copyTo.Position = 0; + return copyTo; + } catch { + copyTo.Dispose(); + throw; + } } /// <summary> diff --git a/src/DotNetOpenAuth/Messaging/MultipartPostPart.cs b/src/DotNetOpenAuth/Messaging/MultipartPostPart.cs index f9a5988..029cd48 100644 --- a/src/DotNetOpenAuth/Messaging/MultipartPostPart.cs +++ b/src/DotNetOpenAuth/Messaging/MultipartPostPart.cs @@ -103,9 +103,14 @@ namespace DotNetOpenAuth.Messaging { Contract.Requires<ArgumentException>(value != null); var part = new MultipartPostPart("form-data"); - part.ContentAttributes["name"] = name; - part.Content = new MemoryStream(Encoding.UTF8.GetBytes(value)); - return part; + try { + part.ContentAttributes["name"] = name; + part.Content = new MemoryStream(Encoding.UTF8.GetBytes(value)); + return part; + } catch { + part.Dispose(); + throw; + } } /// <summary> @@ -121,7 +126,13 @@ namespace DotNetOpenAuth.Messaging { Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(contentType)); string fileName = Path.GetFileName(filePath); - return CreateFormFilePart(name, fileName, contentType, File.OpenRead(filePath)); + var fileStream = File.OpenRead(filePath); + try { + return CreateFormFilePart(name, fileName, contentType, fileStream); + } catch { + fileStream.Dispose(); + throw; + } } /// <summary> @@ -139,14 +150,20 @@ namespace DotNetOpenAuth.Messaging { Contract.Requires<ArgumentException>(content != null); var part = new MultipartPostPart("file"); - part.ContentAttributes["name"] = name; - part.ContentAttributes["filename"] = fileName; - part.PartHeaders[HttpRequestHeader.ContentType] = contentType; - if (!contentType.StartsWith("text/", StringComparison.Ordinal)) { - part.PartHeaders["Content-Transfer-Encoding"] = "binary"; + try { + part.ContentAttributes["name"] = name; + part.ContentAttributes["filename"] = fileName; + part.PartHeaders[HttpRequestHeader.ContentType] = contentType; + if (!contentType.StartsWith("text/", StringComparison.Ordinal)) { + part.PartHeaders["Content-Transfer-Encoding"] = "binary"; + } + + part.Content = content; + return part; + } catch { + part.Dispose(); + throw; } - part.Content = content; - return part; } /// <summary> diff --git a/src/DotNetOpenAuth/Messaging/NetworkDirectWebResponse.cs b/src/DotNetOpenAuth/Messaging/NetworkDirectWebResponse.cs index 643cf81..800d2ba 100644 --- a/src/DotNetOpenAuth/Messaging/NetworkDirectWebResponse.cs +++ b/src/DotNetOpenAuth/Messaging/NetworkDirectWebResponse.cs @@ -109,6 +109,8 @@ namespace DotNetOpenAuth.Messaging { this.httpWebResponse = null; } } + + base.Dispose(disposing); } } } diff --git a/src/DotNetOpenAuth/Messaging/Reflection/MessageDescriptionCollection.cs b/src/DotNetOpenAuth/Messaging/Reflection/MessageDescriptionCollection.cs index ab73b10..2747e31 100644 --- a/src/DotNetOpenAuth/Messaging/Reflection/MessageDescriptionCollection.cs +++ b/src/DotNetOpenAuth/Messaging/Reflection/MessageDescriptionCollection.cs @@ -61,6 +61,7 @@ namespace DotNetOpenAuth.Messaging.Reflection { /// <param name="messageType">A type that implements <see cref="IMessage"/>.</param> /// <param name="messageVersion">The protocol version of the message.</param> /// <returns>A <see cref="MessageDescription"/> instance.</returns> + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Assume(System.Boolean,System.String,System.String)", Justification = "No localization required.")] [Pure] internal MessageDescription Get(Type messageType, Version messageVersion) { Contract.Requires<ArgumentNullException>(messageType != null); diff --git a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs index df6dc73..bdd2827 100644 --- a/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs +++ b/src/DotNetOpenAuth/Messaging/Reflection/MessagePart.cs @@ -113,7 +113,7 @@ namespace DotNetOpenAuth.Messaging.Reflection { /// The attribute discovered on <paramref name="member"/> that describes the /// serialization requirements of the message part. /// </param> - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Code contracts requires it.")] + [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification = "Unavoidable"), SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Code contracts requires it.")] internal MessagePart(MemberInfo member, MessagePartAttribute attribute) { Contract.Requires<ArgumentNullException>(member != null); Contract.Requires<ArgumentException>(member is FieldInfo || member is PropertyInfo); @@ -319,6 +319,7 @@ namespace DotNetOpenAuth.Messaging.Reflection { /// <param name="toString">The function to convert the custom type to a string.</param> /// <param name="toOriginalString">The mapping function that converts some custom value to its original (non-normalized) string. May be null if the same as the <paramref name="toString"/> function.</param> /// <param name="toValue">The function to convert a string to the custom type.</param> + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentNullException>(System.Boolean,System.String,System.String)", Justification = "Code contracts"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "toString", Justification = "Code contracts"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "toValue", Justification = "Code contracts")] private static void Map<T>(Func<T, string> toString, Func<T, string> toOriginalString, Func<string, T> toValue) { Contract.Requires<ArgumentNullException>(toString != null, "toString"); Contract.Requires<ArgumentNullException>(toValue != null, "toValue"); diff --git a/src/DotNetOpenAuth/Migrated rules for DotNetOpenAuth.ruleset b/src/DotNetOpenAuth/Migrated rules for DotNetOpenAuth.ruleset index db238b6..0ba4e6e 100644 --- a/src/DotNetOpenAuth/Migrated rules for DotNetOpenAuth.ruleset +++ b/src/DotNetOpenAuth/Migrated rules for DotNetOpenAuth.ruleset @@ -5,6 +5,7 @@ <Rule Id="CA1054" Action="None" /> <Rule Id="CA1055" Action="None" /> <Rule Id="CA1056" Action="None" /> + <Rule Id="CA1062" Action="None" /> <Rule Id="CA2104" Action="None" /> </Rules> </RuleSet>
\ No newline at end of file diff --git a/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs b/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs index ffde271..adde6b6 100644 --- a/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs +++ b/src/DotNetOpenAuth/Mvc/OpenIdHelper.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.Mvc { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Globalization; using System.IO; @@ -35,10 +36,11 @@ namespace DotNetOpenAuth.Mvc { Contract.Requires<ArgumentNullException>(html != null); Contract.Ensures(Contract.Result<string>() != null); - StringWriter result = new StringWriter(); - result.WriteStylesheetLink(OpenId.RelyingParty.OpenIdSelector.EmbeddedStylesheetResourceName); - result.WriteStylesheetLink(OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedStylesheetResourceName); - return result.ToString(); + using (var result = new StringWriter(CultureInfo.CurrentCulture)) { + result.WriteStylesheetLink(OpenId.RelyingParty.OpenIdSelector.EmbeddedStylesheetResourceName); + result.WriteStylesheetLink(OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedStylesheetResourceName); + return result.ToString(); + } } /// <summary> @@ -59,43 +61,45 @@ namespace DotNetOpenAuth.Mvc { /// <returns> /// HTML that should be sent directly to the browser. /// </returns> + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "False positive")] public static string OpenIdSelectorScripts(this HtmlHelper html, OpenIdSelector selectorOptions, OpenIdAjaxOptions additionalOptions) { Contract.Requires<ArgumentNullException>(html != null); Contract.Ensures(Contract.Result<string>() != null); + bool selectorOptionsOwned = false; if (selectorOptions == null) { + selectorOptionsOwned = true; selectorOptions = new OpenId.RelyingParty.OpenIdSelector(); } + try { + if (additionalOptions == null) { + additionalOptions = new OpenIdAjaxOptions(); + } - if (additionalOptions == null) { - additionalOptions = new OpenIdAjaxOptions(); - } - - StringWriter result = new StringWriter(); - - if (additionalOptions.ShowDiagnosticIFrame || additionalOptions.ShowDiagnosticTrace) { - string scriptFormat = @"window.openid_visible_iframe = {0}; // causes the hidden iframe to show up + using (StringWriter result = new StringWriter(CultureInfo.CurrentCulture)) { + if (additionalOptions.ShowDiagnosticIFrame || additionalOptions.ShowDiagnosticTrace) { + string scriptFormat = @"window.openid_visible_iframe = {0}; // causes the hidden iframe to show up window.openid_trace = {1}; // causes lots of messages"; - result.WriteScriptBlock(string.Format( - CultureInfo.InvariantCulture, - scriptFormat, - additionalOptions.ShowDiagnosticIFrame ? "true" : "false", - additionalOptions.ShowDiagnosticTrace ? "true" : "false")); - } - var scriptResources = new[] { + result.WriteScriptBlock(string.Format( + CultureInfo.InvariantCulture, + scriptFormat, + additionalOptions.ShowDiagnosticIFrame ? "true" : "false", + additionalOptions.ShowDiagnosticTrace ? "true" : "false")); + } + var scriptResources = new[] { OpenIdRelyingPartyControlBase.EmbeddedJavascriptResource, OpenIdRelyingPartyAjaxControlBase.EmbeddedAjaxJavascriptResource, OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedScriptResourceName, }; - result.WriteScriptTags(scriptResources); + result.WriteScriptTags(scriptResources); - if (selectorOptions.DownloadYahooUILibrary) { - result.WriteScriptTagsUrls(new[] { "https://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/yuiloader/yuiloader-min.js" }); - } + if (selectorOptions.DownloadYahooUILibrary) { + result.WriteScriptTagsUrls(new[] { "https://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/build/yuiloader/yuiloader-min.js" }); + } - var blockBuilder = new StringWriter(); - if (selectorOptions.DownloadYahooUILibrary) { - blockBuilder.WriteLine(@" try { + using (var blockBuilder = new StringWriter(CultureInfo.CurrentCulture)) { + if (selectorOptions.DownloadYahooUILibrary) { + blockBuilder.WriteLine(@" try { if (YAHOO) { var loader = new YAHOO.util.YUILoader({ require: ['button', 'menu'], @@ -106,25 +110,25 @@ window.openid_trace = {1}; // causes lots of messages"; loader.insert(); } } catch (e) { }"); - } + } - blockBuilder.WriteLine("window.aspnetapppath = '{0}';", VirtualPathUtility.AppendTrailingSlash(HttpContext.Current.Request.ApplicationPath)); + blockBuilder.WriteLine("window.aspnetapppath = '{0}';", VirtualPathUtility.AppendTrailingSlash(HttpContext.Current.Request.ApplicationPath)); - // Positive assertions can last no longer than this library is willing to consider them valid, - // and when they come with OP private associations they last no longer than the OP is willing - // to consider them valid. We assume the OP will hold them valid for at least five minutes. - double assertionLifetimeInMilliseconds = Math.Min(TimeSpan.FromMinutes(5).TotalMilliseconds, Math.Min(DotNetOpenAuthSection.Configuration.OpenId.MaxAuthenticationTime.TotalMilliseconds, DotNetOpenAuthSection.Configuration.Messaging.MaximumMessageLifetime.TotalMilliseconds)); - blockBuilder.WriteLine( - "{0} = {1};", - OpenIdRelyingPartyAjaxControlBase.MaxPositiveAssertionLifetimeJsName, - assertionLifetimeInMilliseconds.ToString(CultureInfo.InvariantCulture)); + // Positive assertions can last no longer than this library is willing to consider them valid, + // and when they come with OP private associations they last no longer than the OP is willing + // to consider them valid. We assume the OP will hold them valid for at least five minutes. + double assertionLifetimeInMilliseconds = Math.Min(TimeSpan.FromMinutes(5).TotalMilliseconds, Math.Min(DotNetOpenAuthSection.Configuration.OpenId.MaxAuthenticationTime.TotalMilliseconds, DotNetOpenAuthSection.Configuration.Messaging.MaximumMessageLifetime.TotalMilliseconds)); + blockBuilder.WriteLine( + "{0} = {1};", + OpenIdRelyingPartyAjaxControlBase.MaxPositiveAssertionLifetimeJsName, + assertionLifetimeInMilliseconds.ToString(CultureInfo.InvariantCulture)); - if (additionalOptions.PreloadedDiscoveryResults != null) { - blockBuilder.WriteLine(additionalOptions.PreloadedDiscoveryResults); - } + if (additionalOptions.PreloadedDiscoveryResults != null) { + blockBuilder.WriteLine(additionalOptions.PreloadedDiscoveryResults); + } - string discoverUrl = VirtualPathUtility.AppendTrailingSlash(HttpContext.Current.Request.ApplicationPath) + html.RouteCollection["OpenIdDiscover"].GetVirtualPath(html.ViewContext.RequestContext, new RouteValueDictionary(new { identifier = "xxx" })).VirtualPath; - string blockFormat = @" {0} = function (argument, resultFunction, errorCallback) {{ + string discoverUrl = VirtualPathUtility.AppendTrailingSlash(HttpContext.Current.Request.ApplicationPath) + html.RouteCollection["OpenIdDiscover"].GetVirtualPath(html.ViewContext.RequestContext, new RouteValueDictionary(new { identifier = "xxx" })).VirtualPath; + string blockFormat = @" {0} = function (argument, resultFunction, errorCallback) {{ jQuery.ajax({{ async: true, dataType: 'text', @@ -133,22 +137,22 @@ window.openid_trace = {1}; // causes lots of messages"; url: '{1}'.replace('xxx', encodeURIComponent(argument)) }}); }};"; - blockBuilder.WriteLine(blockFormat, OpenIdRelyingPartyAjaxControlBase.CallbackJSFunctionAsync, discoverUrl); + blockBuilder.WriteLine(blockFormat, OpenIdRelyingPartyAjaxControlBase.CallbackJSFunctionAsync, discoverUrl); - blockFormat = @" window.postLoginAssertion = function (positiveAssertion) {{ + blockFormat = @" window.postLoginAssertion = function (positiveAssertion) {{ $('#{0}')[0].setAttribute('value', positiveAssertion); if ($('#{1}')[0] && !$('#{1}')[0].value) {{ // popups have no ReturnUrl predefined, but full page LogOn does. $('#{1}')[0].setAttribute('value', window.parent.location.href); }} document.forms[{2}].submit(); }};"; - blockBuilder.WriteLine( - blockFormat, - additionalOptions.AssertionHiddenFieldId, - additionalOptions.ReturnUrlHiddenFieldId, - additionalOptions.FormKey); + blockBuilder.WriteLine( + blockFormat, + additionalOptions.AssertionHiddenFieldId, + additionalOptions.ReturnUrlHiddenFieldId, + additionalOptions.FormKey); - blockFormat = @" $(function () {{ + blockFormat = @" $(function () {{ var box = document.getElementsByName('openid_identifier')[0]; initAjaxOpenId(box, {0}, {1}, {2}, {3}, {4}, {5}, null, // js function to invoke on receiving a positive assertion @@ -156,32 +160,41 @@ window.openid_trace = {1}; // causes lots of messages"; false, // auto postback null); // PostBackEventReference (unused in MVC) }});"; - blockBuilder.WriteLine( - blockFormat, - MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenIdTextBox.EmbeddedLogoResourceName)), - MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedSpinnerResourceName)), - MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName)), - MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginFailureResourceName)), - selectorOptions.Throttle, - selectorOptions.Timeout.TotalMilliseconds, - MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnText), - MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnToolTip), - selectorOptions.TextBox.ShowLogOnPostBackButton ? "true" : "false", - MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnPostBackToolTip), - MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.RetryText), - MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.RetryToolTip), - MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.BusyToolTip), - MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.IdentifierRequiredMessage), - MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnInProgressMessage), - MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.AuthenticationSucceededToolTip), - MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.AuthenticatedAsToolTip), - MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.AuthenticationFailedToolTip)); - - result.WriteScriptBlock(blockBuilder.ToString()); - result.WriteScriptTags(OpenId.RelyingParty.OpenIdSelector.EmbeddedScriptResourceName); - - Reporting.RecordFeatureUse("MVC " + typeof(OpenIdSelector).Name); - return result.ToString(); + blockBuilder.WriteLine( + blockFormat, + MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenIdTextBox.EmbeddedLogoResourceName)), + MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedSpinnerResourceName)), + MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName)), + MessagingUtilities.GetSafeJavascriptValue(Util.GetWebResourceUrl(typeof(OpenIdRelyingPartyControlBase), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginFailureResourceName)), + selectorOptions.Throttle, + selectorOptions.Timeout.TotalMilliseconds, + MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnText), + MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnToolTip), + selectorOptions.TextBox.ShowLogOnPostBackButton ? "true" : "false", + MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnPostBackToolTip), + MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.RetryText), + MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.RetryToolTip), + MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.BusyToolTip), + MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.IdentifierRequiredMessage), + MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.LogOnInProgressMessage), + MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.AuthenticationSucceededToolTip), + MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.AuthenticatedAsToolTip), + MessagingUtilities.GetSafeJavascriptValue(selectorOptions.TextBox.AuthenticationFailedToolTip)); + + result.WriteScriptBlock(blockBuilder.ToString()); + result.WriteScriptTags(OpenId.RelyingParty.OpenIdSelector.EmbeddedScriptResourceName); + + Reporting.RecordFeatureUse("MVC " + typeof(OpenIdSelector).Name); + return result.ToString(); + } + } + } catch { + if (selectorOptionsOwned) { + selectorOptions.Dispose(); + } + + throw; + } } /// <summary> @@ -227,40 +240,42 @@ window.openid_trace = {1}; // causes lots of messages"; /// <returns> /// HTML that should be sent directly to the browser. /// </returns> + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Not a problem for this type.")] public static string OpenIdSelector(this HtmlHelper html, params SelectorButton[] buttons) { Contract.Requires<ArgumentNullException>(html != null); Contract.Requires<ArgumentNullException>(buttons != null); Contract.Ensures(Contract.Result<string>() != null); - var writer = new StringWriter(); - var h = new HtmlTextWriter(writer); + using (var writer = new StringWriter(CultureInfo.CurrentCulture)) { + using (var h = new HtmlTextWriter(writer)) { + h.AddAttribute(HtmlTextWriterAttribute.Class, "OpenIdProviders"); + h.RenderBeginTag(HtmlTextWriterTag.Ul); - h.AddAttribute(HtmlTextWriterAttribute.Class, "OpenIdProviders"); - h.RenderBeginTag(HtmlTextWriterTag.Ul); + foreach (SelectorButton button in buttons) { + var op = button as SelectorProviderButton; + if (op != null) { + h.Write(OpenIdSelectorOPButton(html, op.OPIdentifier, op.Image)); + continue; + } - foreach (SelectorButton button in buttons) { - var op = button as SelectorProviderButton; - if (op != null) { - h.Write(OpenIdSelectorOPButton(html, op.OPIdentifier, op.Image)); - continue; - } + var openid = button as SelectorOpenIdButton; + if (openid != null) { + h.Write(OpenIdSelectorOpenIdButton(html, openid.Image)); + continue; + } - var openid = button as SelectorOpenIdButton; - if (openid != null) { - h.Write(OpenIdSelectorOpenIdButton(html, openid.Image)); - continue; - } + ErrorUtilities.VerifySupported(false, "The {0} button is not yet supported for MVC.", button.GetType().Name); + } - ErrorUtilities.VerifySupported(false, "The {0} button is not yet supported for MVC.", button.GetType().Name); - } + h.RenderEndTag(); // ul - h.RenderEndTag(); // ul + if (buttons.OfType<SelectorOpenIdButton>().Any()) { + h.Write(OpenIdAjaxTextBox(html)); + } + } - if (buttons.OfType<SelectorOpenIdButton>().Any()) { - h.Write(OpenIdAjaxTextBox(html)); + return writer.ToString(); } - - return writer.ToString(); } /// <summary> @@ -271,6 +286,7 @@ window.openid_trace = {1}; // causes lots of messages"; /// <returns> /// HTML that should be sent directly to the browser. /// </returns> + [SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "html", Justification = "Breaking change, and it's an extension method so it's useful.")] public static string OpenIdAjaxTextBox(this HtmlHelper html) { return @"<div style='display: none' id='OpenIDForm'> <span class='OpenIdAjaxTextBox' style='display: inline-block; position: relative; font-size: 16px'> @@ -289,48 +305,50 @@ window.openid_trace = {1}; // causes lots of messages"; /// <returns> /// HTML that should be sent directly to the browser. /// </returns> + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Not a problem for this type.")] private static string OpenIdSelectorButton(this HtmlHelper html, string id, string cssClass, string imageUrl) { Contract.Requires<ArgumentNullException>(html != null); Contract.Requires<ArgumentNullException>(id != null); Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(imageUrl)); Contract.Ensures(Contract.Result<string>() != null); - var writer = new StringWriter(); - var h = new HtmlTextWriter(writer); - - h.AddAttribute(HtmlTextWriterAttribute.Id, id); - if (!string.IsNullOrEmpty(cssClass)) { - h.AddAttribute(HtmlTextWriterAttribute.Class, cssClass); - } - h.RenderBeginTag(HtmlTextWriterTag.Li); + using (var writer = new StringWriter(CultureInfo.CurrentCulture)) { + using (var h = new HtmlTextWriter(writer)) { + h.AddAttribute(HtmlTextWriterAttribute.Id, id); + if (!string.IsNullOrEmpty(cssClass)) { + h.AddAttribute(HtmlTextWriterAttribute.Class, cssClass); + } + h.RenderBeginTag(HtmlTextWriterTag.Li); - h.AddAttribute(HtmlTextWriterAttribute.Href, "#"); - h.RenderBeginTag(HtmlTextWriterTag.A); + h.AddAttribute(HtmlTextWriterAttribute.Href, "#"); + h.RenderBeginTag(HtmlTextWriterTag.A); - h.RenderBeginTag(HtmlTextWriterTag.Div); - h.RenderBeginTag(HtmlTextWriterTag.Div); + h.RenderBeginTag(HtmlTextWriterTag.Div); + h.RenderBeginTag(HtmlTextWriterTag.Div); - h.AddAttribute(HtmlTextWriterAttribute.Src, imageUrl); - h.RenderBeginTag(HtmlTextWriterTag.Img); - h.RenderEndTag(); + h.AddAttribute(HtmlTextWriterAttribute.Src, imageUrl); + h.RenderBeginTag(HtmlTextWriterTag.Img); + h.RenderEndTag(); - h.AddAttribute(HtmlTextWriterAttribute.Src, Util.GetWebResourceUrl(typeof(OpenIdSelector), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName)); - h.AddAttribute(HtmlTextWriterAttribute.Class, "loginSuccess"); - h.AddAttribute(HtmlTextWriterAttribute.Title, "Authenticated as {0}"); - h.RenderBeginTag(HtmlTextWriterTag.Img); - h.RenderEndTag(); + h.AddAttribute(HtmlTextWriterAttribute.Src, Util.GetWebResourceUrl(typeof(OpenIdSelector), OpenId.RelyingParty.OpenIdAjaxTextBox.EmbeddedLoginSuccessResourceName)); + h.AddAttribute(HtmlTextWriterAttribute.Class, "loginSuccess"); + h.AddAttribute(HtmlTextWriterAttribute.Title, "Authenticated as {0}"); + h.RenderBeginTag(HtmlTextWriterTag.Img); + h.RenderEndTag(); - h.RenderEndTag(); // div + h.RenderEndTag(); // div - h.AddAttribute(HtmlTextWriterAttribute.Class, "ui-widget-overlay"); - h.RenderBeginTag(HtmlTextWriterTag.Div); - h.RenderEndTag(); // div + h.AddAttribute(HtmlTextWriterAttribute.Class, "ui-widget-overlay"); + h.RenderBeginTag(HtmlTextWriterTag.Div); + h.RenderEndTag(); // div - h.RenderEndTag(); // div - h.RenderEndTag(); // a - h.RenderEndTag(); // li + h.RenderEndTag(); // div + h.RenderEndTag(); // a + h.RenderEndTag(); // li + } - return writer.ToString(); + return writer.ToString(); + } } /// <summary> diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs index 53930bc..5828428 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/HmacSha1SigningBindingElement.cs @@ -32,10 +32,11 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// </remarks> protected override string GetSignature(ITamperResistantOAuthMessage message) { string key = GetConsumerAndTokenSecretString(message); - HashAlgorithm hasher = new HMACSHA1(Encoding.ASCII.GetBytes(key)); - string baseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message)); - byte[] digest = hasher.ComputeHash(Encoding.ASCII.GetBytes(baseString)); - return Convert.ToBase64String(digest); + using (HashAlgorithm hasher = new HMACSHA1(Encoding.ASCII.GetBytes(key))) { + string baseString = ConstructSignatureBaseString(message, this.Channel.MessageDescriptions.GetAccessor(message)); + byte[] digest = hasher.ComputeHash(Encoding.ASCII.GetBytes(baseString)); + return Convert.ToBase64String(digest); + } } /// <summary> diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/ITamperResistantOAuthMessage.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/ITamperResistantOAuthMessage.cs index ff6d6e9..a95001d 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/ITamperResistantOAuthMessage.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/ITamperResistantOAuthMessage.cs @@ -13,7 +13,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// <summary> /// An interface that OAuth messages implement to support signing. /// </summary> - public interface ITamperResistantOAuthMessage : IDirectedProtocolMessage, ITamperResistantProtocolMessage { + public interface ITamperResistantOAuthMessage : IDirectedProtocolMessage, ITamperResistantProtocolMessage, IMessageOriginalPayload { /// <summary> /// Gets or sets the method used to sign the message. /// </summary> diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs index ff7ede0..4b5aebe 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/OAuthChannel.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { using System; using System.Collections.Generic; using System.Diagnostics; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Globalization; using System.IO; @@ -32,6 +33,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// <param name="store">The web application store to use for nonces.</param> /// <param name="tokenManager">The token manager instance to use.</param> /// <param name="securitySettings">The security settings.</param> + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentNullException>(System.Boolean,System.String,System.String)", Justification = "Code contracts"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "securitySettings", Justification = "Code contracts")] internal OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, IConsumerTokenManager tokenManager, ConsumerSecuritySettings securitySettings) : this( signingBindingElement, @@ -52,6 +54,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// <param name="store">The web application store to use for nonces.</param> /// <param name="tokenManager">The token manager instance to use.</param> /// <param name="securitySettings">The security settings.</param> + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentNullException>(System.Boolean,System.String,System.String)", Justification = "Code contracts"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "securitySettings", Justification = "Code contracts")] internal OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, IServiceProviderTokenManager tokenManager, ServiceProviderSecuritySettings securitySettings) : this( signingBindingElement, @@ -75,6 +78,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// <param name="messageTypeProvider">An injected message type provider instance. /// Except for mock testing, this should always be one of /// <see cref="OAuthConsumerMessageFactory"/> or <see cref="OAuthServiceProviderMessageFactory"/>.</param> + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentNullException>(System.Boolean,System.String,System.String)", Justification = "Code contracts"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "securitySettings", Justification = "Code contracts")] internal OAuthChannel(ITamperProtectionChannelBindingElement signingBindingElement, INonceStore store, ITokenManager tokenManager, SecuritySettings securitySettings, IMessageFactory messageTypeProvider) : base(messageTypeProvider, InitializeBindingElements(signingBindingElement, store, tokenManager, securitySettings)) { Contract.Requires<ArgumentNullException>(tokenManager != null); diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBase.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBase.cs index cb81139..31b5149 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBase.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/SigningBindingElementBase.cs @@ -8,6 +8,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { using System; using System.Collections.Generic; using System.Collections.Specialized; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Globalization; using System.Linq; @@ -148,6 +149,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// <remarks> /// This method implements OAuth 1.0 section 9.1. /// </remarks> + [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Unavoidable")] internal static string ConstructSignatureBaseString(ITamperResistantOAuthMessage message, MessageDictionary messageDictionary) { Contract.Requires<ArgumentNullException>(message != null); Contract.Requires<ArgumentException>(!string.IsNullOrEmpty(message.HttpMethod)); @@ -175,6 +177,13 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { partsToInclude = messageDictionary; } + // If this message was deserialized, include only those explicitly included message parts (excludes defaulted values) + // in the signature. + var originalPayloadMessage = (IMessageOriginalPayload)message; + if (originalPayloadMessage.OriginalPayload != null) { + partsToInclude = partsToInclude.Where(pair => originalPayloadMessage.OriginalPayload.ContainsKey(pair.Key)); + } + foreach (var pair in OAuthChannel.GetUriEscapedParameters(partsToInclude)) { encodedDictionary[pair.Key] = pair.Value; } diff --git a/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs b/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs index 329f8c4..bfebd8b 100644 --- a/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs +++ b/src/DotNetOpenAuth/OAuth/ChannelElements/TokenHandlingBindingElement.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Linq; using System.Text; @@ -34,6 +35,7 @@ namespace DotNetOpenAuth.OAuth.ChannelElements { /// </summary> /// <param name="tokenManager">The token manager.</param> /// <param name="securitySettings">The security settings.</param> + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentNullException>(System.Boolean,System.String,System.String)", Justification = "Code contract"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "securitySettings", Justification = "Code contracts")] internal TokenHandlingBindingElement(IServiceProviderTokenManager tokenManager, ServiceProviderSecuritySettings securitySettings) { Contract.Requires<ArgumentNullException>(tokenManager != null); Contract.Requires<ArgumentNullException>(securitySettings != null, "securitySettings"); diff --git a/src/DotNetOpenAuth/OAuth/Messages/SignedMessageBase.cs b/src/DotNetOpenAuth/OAuth/Messages/SignedMessageBase.cs index 57ce470..6084fc0 100644 --- a/src/DotNetOpenAuth/OAuth/Messages/SignedMessageBase.cs +++ b/src/DotNetOpenAuth/OAuth/Messages/SignedMessageBase.cs @@ -6,6 +6,7 @@ namespace DotNetOpenAuth.OAuth.Messages { using System; + using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using DotNetOpenAuth.Messaging; using DotNetOpenAuth.Messaging.Bindings; @@ -131,6 +132,24 @@ namespace DotNetOpenAuth.OAuth.Messages { #endregion + #region IMessageOriginalPayload Members + + /// <summary> + /// Gets or sets the original message parts, before any normalization or default values were assigned. + /// </summary> + IDictionary<string, string> IMessageOriginalPayload.OriginalPayload { + get { return this.OriginalPayload; } + set { this.OriginalPayload = value; } + } + + /// <summary> + /// Gets or sets the original message parts, before any normalization or default values were assigned. + /// </summary> + [SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly", Justification = "By design")] + protected IDictionary<string, string> OriginalPayload { get; set; } + + #endregion + /// <summary> /// Gets or sets the signature method used to sign the request. /// </summary> diff --git a/src/DotNetOpenAuth/OAuth/OAuthStrings.Designer.cs b/src/DotNetOpenAuth/OAuth/OAuthStrings.Designer.cs index fb4c9a1..723839d 100644 --- a/src/DotNetOpenAuth/OAuth/OAuthStrings.Designer.cs +++ b/src/DotNetOpenAuth/OAuth/OAuthStrings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version:4.0.30104.0 +// Runtime Version:4.0.30319.225 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. diff --git a/src/DotNetOpenAuth/OAuth/Protocol.cs b/src/DotNetOpenAuth/OAuth/Protocol.cs index 71a25f8..4418b5e 100644 --- a/src/DotNetOpenAuth/OAuth/Protocol.cs +++ b/src/DotNetOpenAuth/OAuth/Protocol.cs @@ -83,7 +83,7 @@ namespace DotNetOpenAuth.OAuth { internal static readonly List<Protocol> AllVersions = new List<Protocol>() { V10a, V10 }; /// <summary> - /// The default (or most recent) supported version of the OpenID protocol. + /// The default (or most recent) supported version of the OAuth protocol. /// </summary> internal static readonly Protocol Default = AllVersions[0]; diff --git a/src/DotNetOpenAuth/OAuth/ServiceProvider.cs b/src/DotNetOpenAuth/OAuth/ServiceProvider.cs index fda895e..ec9206e 100644 --- a/src/DotNetOpenAuth/OAuth/ServiceProvider.cs +++ b/src/DotNetOpenAuth/OAuth/ServiceProvider.cs @@ -341,7 +341,7 @@ namespace DotNetOpenAuth.OAuth { Contract.Requires<ArgumentException>((consumerKey == null) == (scope == null)); Contract.Requires<InvalidOperationException>(this.TokenManager is ICombinedOpenIdProviderTokenManager); var openidTokenManager = (ICombinedOpenIdProviderTokenManager)this.TokenManager; - ErrorUtilities.VerifyArgument(consumerKey == null || consumerKey == openidTokenManager.GetConsumerKey(openIdAuthenticationRequest.Realm), "The consumer key and the realm did not match according to the token manager."); + ErrorUtilities.VerifyArgument(consumerKey == null || consumerKey == openidTokenManager.GetConsumerKey(openIdAuthenticationRequest.Realm), OAuthStrings.OpenIdOAuthRealmConsumerKeyDoNotMatch); this.AttachAuthorizationResponse(openIdAuthenticationRequest, scope); } diff --git a/src/DotNetOpenAuth/OAuth/VerificationCodeFormat.cs b/src/DotNetOpenAuth/OAuth/VerificationCodeFormat.cs index 3afd44e..a6560d8 100644 --- a/src/DotNetOpenAuth/OAuth/VerificationCodeFormat.cs +++ b/src/DotNetOpenAuth/OAuth/VerificationCodeFormat.cs @@ -37,6 +37,7 @@ namespace DotNetOpenAuth.OAuth { /// </remarks> [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Alikes", Justification = "Breaking change of existing API")] [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "AlphaNumeric", Justification = "Breaking change of existing API")] + [SuppressMessage("Microsoft.Naming", "CA1702:CompoundWordsShouldBeCasedCorrectly", MessageId = "LookAlikes", Justification = "Breaking change of existing API")] AlphaNumericNoLookAlikes, /// <summary> diff --git a/src/DotNetOpenAuth/OpenId/ChannelElements/KeyValueFormEncoding.cs b/src/DotNetOpenAuth/OpenId/ChannelElements/KeyValueFormEncoding.cs index c363c11..46c2139 100644 --- a/src/DotNetOpenAuth/OpenId/ChannelElements/KeyValueFormEncoding.cs +++ b/src/DotNetOpenAuth/OpenId/ChannelElements/KeyValueFormEncoding.cs @@ -99,27 +99,30 @@ namespace DotNetOpenAuth.OpenId.ChannelElements { /// If ordering of the key=value pairs is important, a deterministic enumerator must /// be used. /// </remarks> + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Not a problem for this type.")] public static byte[] GetBytes(IEnumerable<KeyValuePair<string, string>> keysAndValues) { Contract.Requires<ArgumentNullException>(keysAndValues != null); - MemoryStream ms = new MemoryStream(); - using (StreamWriter sw = new StreamWriter(ms, textEncoding)) { - sw.NewLine = NewLineCharacters; - foreach (var pair in keysAndValues) { - if (pair.Key.IndexOfAny(IllegalKeyCharacters) >= 0) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, OpenIdStrings.InvalidCharacterInKeyValueFormInput, pair.Key)); - } - if (pair.Value.IndexOfAny(IllegalValueCharacters) >= 0) { - throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, OpenIdStrings.InvalidCharacterInKeyValueFormInput, pair.Value)); - } + using (MemoryStream ms = new MemoryStream()) { + using (StreamWriter sw = new StreamWriter(ms, textEncoding)) { + sw.NewLine = NewLineCharacters; + foreach (var pair in keysAndValues) { + if (pair.Key.IndexOfAny(IllegalKeyCharacters) >= 0) { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, OpenIdStrings.InvalidCharacterInKeyValueFormInput, pair.Key)); + } + if (pair.Value.IndexOfAny(IllegalValueCharacters) >= 0) { + throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, OpenIdStrings.InvalidCharacterInKeyValueFormInput, pair.Value)); + } - sw.Write(pair.Key); - sw.Write(':'); - sw.Write(pair.Value); - sw.WriteLine(); + sw.Write(pair.Key); + sw.Write(':'); + sw.Write(pair.Value); + sw.WriteLine(); + } } + + return ms.ToArray(); } - return ms.ToArray(); } /// <summary> diff --git a/src/DotNetOpenAuth/OpenId/HostMetaDiscoveryService.cs b/src/DotNetOpenAuth/OpenId/HostMetaDiscoveryService.cs index 0bc1aa3..39891b3 100644 --- a/src/DotNetOpenAuth/OpenId/HostMetaDiscoveryService.cs +++ b/src/DotNetOpenAuth/OpenId/HostMetaDiscoveryService.cs @@ -212,6 +212,7 @@ namespace DotNetOpenAuth.OpenId { /// <param name="response">The response.</param> /// <param name="signingHost">The host name on the certificate that should be used to verify the signature in the XRDS.</param> /// <exception cref="ProtocolException">Thrown if the XRDS document has an invalid or a missing signature.</exception> + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "XmlDSig", Justification = "xml")] private static void ValidateXmlDSig(XrdsDocument document, UriIdentifier identifier, IncomingWebResponse response, string signingHost) { Contract.Requires<ArgumentNullException>(document != null); Contract.Requires<ArgumentNullException>(identifier != null); @@ -223,10 +224,10 @@ namespace DotNetOpenAuth.OpenId { ErrorUtilities.VerifyProtocol(signedInfoNode != null, OpenIdStrings.MissingElement, "SignedInfo"); ErrorUtilities.VerifyProtocol( signedInfoNode.SelectSingleNode("ds:CanonicalizationMethod[@Algorithm='http://docs.oasis-open.org/xri/xrd/2009/01#canonicalize-raw-octets']", document.XmlNamespaceResolver) != null, - "Unrecognized or missing canonicalization method."); + OpenIdStrings.UnsupportedCanonicalizationMethod); ErrorUtilities.VerifyProtocol( signedInfoNode.SelectSingleNode("ds:SignatureMethod[@Algorithm='http://www.w3.org/2000/09/xmldsig#rsa-sha1']", document.XmlNamespaceResolver) != null, - "Unrecognized or missing signature method."); + OpenIdStrings.UnsupportedSignatureMethod); var certNodes = signatureNode.Select("ds:KeyInfo/ds:X509Data/ds:X509Certificate", document.XmlNamespaceResolver); ErrorUtilities.VerifyProtocol(certNodes.Count > 0, OpenIdStrings.MissingElement, "X509Certificate"); var certs = certNodes.Cast<XPathNavigator>().Select(n => new X509Certificate2(Convert.FromBase64String(n.Value.Trim()))).ToList(); @@ -249,7 +250,7 @@ namespace DotNetOpenAuth.OpenId { // Verify that the certificate is issued to the host on whom we are performing discovery. string hostName = certs[0].GetNameInfo(X509NameType.DnsName, false); - ErrorUtilities.VerifyProtocol(string.Equals(hostName, signingHost, StringComparison.OrdinalIgnoreCase), "X.509 signing certificate issued to {0}, but a certificate for {1} was expected.", hostName, signingHost); + ErrorUtilities.VerifyProtocol(string.Equals(hostName, signingHost, StringComparison.OrdinalIgnoreCase), OpenIdStrings.MisdirectedSigningCertificate, hostName, signingHost); // Verify the signature itself byte[] signature = Convert.FromBase64String(response.Headers["Signature"]); @@ -257,7 +258,7 @@ namespace DotNetOpenAuth.OpenId { byte[] data = new byte[response.ResponseStream.Length]; response.ResponseStream.Seek(0, SeekOrigin.Begin); response.ResponseStream.Read(data, 0, data.Length); - ErrorUtilities.VerifyProtocol(provider.VerifyData(data, "SHA1", signature), "Invalid XmlDSig signature on XRDS document."); + ErrorUtilities.VerifyProtocol(provider.VerifyData(data, "SHA1", signature), OpenIdStrings.InvalidDSig); } /// <summary> @@ -271,7 +272,7 @@ namespace DotNetOpenAuth.OpenId { /// an alternative plan. /// </remarks> /// <exception cref="ProtocolException">Thrown if the certificate chain is invalid or unverifiable.</exception> - [SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "By design")] + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "DotNetOpenAuth.Messaging.ErrorUtilities.ThrowProtocol(System.String,System.Object[])", Justification = "The localized portion is a string resource already."), SuppressMessage("Microsoft.Security", "CA2122:DoNotIndirectlyExposeMethodsWithLinkDemands", Justification = "By design")] private static void VerifyCertChain(List<X509Certificate2> certs) { var chain = new X509Chain(); foreach (var cert in certs) { diff --git a/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs b/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs index ccfb1b8..a4fdf49 100644 --- a/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs +++ b/src/DotNetOpenAuth/OpenId/Messages/AssociateDiffieHellmanResponse.cs @@ -53,7 +53,7 @@ namespace DotNetOpenAuth.OpenId.Messages { /// </remarks> protected override Association CreateAssociationAtRelyingParty(AssociateRequest request) { var diffieHellmanRequest = request as AssociateDiffieHellmanRequest; - ErrorUtilities.VerifyArgument(diffieHellmanRequest != null, "request"); + ErrorUtilities.VerifyArgument(diffieHellmanRequest != null, OpenIdStrings.DiffieHellmanAssociationRequired); HashAlgorithm hasher = DiffieHellmanUtilities.Lookup(Protocol, this.SessionType); byte[] associationSecret = DiffieHellmanUtilities.SHAHashXorSecret(hasher, diffieHellmanRequest.Algorithm, this.DiffieHellmanServerPublic, this.EncodedMacKey); @@ -86,14 +86,14 @@ namespace DotNetOpenAuth.OpenId.Messages { // that will be transmitted to the Relying Party. The RP will perform an inverse operation // using its part of a DH secret in order to decrypt the shared secret we just invented // above when we created the association. - DiffieHellman dh = new DiffieHellmanManaged( + using (DiffieHellman dh = new DiffieHellmanManaged( diffieHellmanRequest.DiffieHellmanModulus ?? AssociateDiffieHellmanRequest.DefaultMod, diffieHellmanRequest.DiffieHellmanGen ?? AssociateDiffieHellmanRequest.DefaultGen, - AssociateDiffieHellmanRequest.DefaultX); - HashAlgorithm hasher = DiffieHellmanUtilities.Lookup(this.Protocol, this.SessionType); - this.DiffieHellmanServerPublic = DiffieHellmanUtilities.EnsurePositive(dh.CreateKeyExchange()); - this.EncodedMacKey = DiffieHellmanUtilities.SHAHashXorSecret(hasher, dh, diffieHellmanRequest.DiffieHellmanConsumerPublic, association.SecretKey); - + AssociateDiffieHellmanRequest.DefaultX)) { + HashAlgorithm hasher = DiffieHellmanUtilities.Lookup(this.Protocol, this.SessionType); + this.DiffieHellmanServerPublic = DiffieHellmanUtilities.EnsurePositive(dh.CreateKeyExchange()); + this.EncodedMacKey = DiffieHellmanUtilities.SHAHashXorSecret(hasher, dh, diffieHellmanRequest.DiffieHellmanConsumerPublic, association.SecretKey); + } return association; } } diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs index 43283ac..f45af93 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs +++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version:4.0.30319.1 +// Runtime Version:4.0.30319.225 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -250,6 +250,15 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Looks up a localized string similar to The associate request instance must be a Diffie-Hellman instance.. + /// </summary> + internal static string DiffieHellmanAssociationRequired { + get { + return ResourceManager.GetString("DiffieHellmanAssociationRequired", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to The following properties must be set before the Diffie-Hellman algorithm can generate a public key: {0}. /// </summary> internal static string DiffieHellmanRequiredPropertiesNotSet { @@ -349,6 +358,15 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Looks up a localized string similar to Invalid XmlDSig signature on XRDS document.. + /// </summary> + internal static string InvalidDSig { + get { + return ResourceManager.GetString("InvalidDSig", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to Cannot decode Key-Value Form because a line was found without a '{0}' character. (line {1}: '{2}'). /// </summary> internal static string InvalidKeyValueFormCharacterMissing { @@ -425,6 +443,15 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Looks up a localized string similar to X.509 signing certificate issued to {0}, but a certificate for {1} was expected.. + /// </summary> + internal static string MisdirectedSigningCertificate { + get { + return ResourceManager.GetString("MisdirectedSigningCertificate", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to Missing {0} element.. /// </summary> internal static string MissingElement { @@ -524,11 +551,20 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> - /// Looks up a localized string similar to An positive OpenID assertion was received from OP endpoint {0} that is not on this relying party's whitelist.. + /// Looks up a localized string similar to OpenID popup window or iframe did not recognize an OpenID response in the request.. /// </summary> - internal static string PositiveAssertionFromNonWhitelistedProvider { + internal static string PopupRedirectMissingResponse { get { - return ResourceManager.GetString("PositiveAssertionFromNonWhitelistedProvider", resourceCulture); + return ResourceManager.GetString("PopupRedirectMissingResponse", resourceCulture); + } + } + + /// <summary> + /// Looks up a localized string similar to An positive OpenID assertion was received from OP endpoint {0} and was rejected based on this site's security settings.. + /// </summary> + internal static string PositiveAssertionFromNonQualifiedProvider { + get { + return ResourceManager.GetString("PositiveAssertionFromNonQualifiedProvider", resourceCulture); } } @@ -722,6 +758,15 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Looks up a localized string similar to Unrecognized or missing canonicalization method.. + /// </summary> + internal static string UnsupportedCanonicalizationMethod { + get { + return ResourceManager.GetString("UnsupportedCanonicalizationMethod", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to This feature is unavailable due to an unrecognized channel configuration.. /// </summary> internal static string UnsupportedChannelConfiguration { @@ -731,6 +776,15 @@ namespace DotNetOpenAuth.OpenId { } /// <summary> + /// Looks up a localized string similar to Unrecognized or missing signature method.. + /// </summary> + internal static string UnsupportedSignatureMethod { + get { + return ResourceManager.GetString("UnsupportedSignatureMethod", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to The openid.user_setup_url parameter is required when sending negative assertion messages in response to immediate mode requests.. /// </summary> internal static string UserSetupUrlRequiredInImmediateNegativeResponse { diff --git a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx index fab03a9..b700d76 100644 --- a/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx +++ b/src/DotNetOpenAuth/OpenId/OpenIdStrings.resx @@ -337,8 +337,8 @@ Discovered endpoint info: <data name="BadExtension" xml:space="preserve"> <value>The {0} extension failed to deserialize and will be skipped. {1}</value> </data> - <data name="PositiveAssertionFromNonWhitelistedProvider" xml:space="preserve"> - <value>An positive OpenID assertion was received from OP endpoint {0} that is not on this relying party's whitelist.</value> + <data name="PositiveAssertionFromNonQualifiedProvider" xml:space="preserve"> + <value>An positive OpenID assertion was received from OP endpoint {0} and was rejected based on this site's security settings.</value> </data> <data name="HeadTagMustIncludeRunatServer" xml:space="preserve"> <value>The HTML head tag must include runat="server".</value> @@ -355,4 +355,22 @@ Discovered endpoint info: <data name="MissingElement" xml:space="preserve"> <value>Missing {0} element.</value> </data> + <data name="DiffieHellmanAssociationRequired" xml:space="preserve"> + <value>The associate request instance must be a Diffie-Hellman instance.</value> + </data> + <data name="InvalidDSig" xml:space="preserve"> + <value>Invalid XmlDSig signature on XRDS document.</value> + </data> + <data name="MisdirectedSigningCertificate" xml:space="preserve"> + <value>X.509 signing certificate issued to {0}, but a certificate for {1} was expected.</value> + </data> + <data name="PopupRedirectMissingResponse" xml:space="preserve"> + <value>OpenID popup window or iframe did not recognize an OpenID response in the request.</value> + </data> + <data name="UnsupportedCanonicalizationMethod" xml:space="preserve"> + <value>Unrecognized or missing canonicalization method.</value> + </data> + <data name="UnsupportedSignatureMethod" xml:space="preserve"> + <value>Unrecognized or missing signature method.</value> + </data> </root>
\ No newline at end of file diff --git a/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs b/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs index ad73269..c5e6bba 100644 --- a/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs +++ b/src/DotNetOpenAuth/OpenId/Provider/AnonymousRequest.cs @@ -27,7 +27,7 @@ namespace DotNetOpenAuth.OpenId.Provider { /// </summary> /// <param name="provider">The provider that received the request.</param> /// <param name="request">The incoming authentication request message.</param> - [SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Code contracts require it.")] + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Requires<System.ArgumentException>(System.Boolean,System.String,System.String)", Justification = "Code contracts"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "AuthenticationRequest", Justification = "Type name"), SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "Code contracts require it.")] internal AnonymousRequest(OpenIdProvider provider, SignedResponseRequest request) : base(provider, request) { Contract.Requires<ArgumentNullException>(provider != null); diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs index 967ef60..3a17263 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/AuthenticationRequest.cs @@ -501,14 +501,10 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { Contract.Requires<ArgumentNullException>(endpoints != null); Contract.Requires<ArgumentNullException>(relyingParty != null); - // Construct the endpoints filters based on criteria given by the host web site. - EndpointSelector versionFilter = ep => ep.Version >= Protocol.Lookup(relyingParty.SecuritySettings.MinimumRequiredOpenIdVersion).Version; - EndpointSelector hostingSiteFilter = relyingParty.EndpointFilter ?? (ep => true); - bool anyFilteredOut = false; var filteredEndpoints = new List<IdentifierDiscoveryResult>(); foreach (var endpoint in endpoints) { - if (versionFilter(endpoint) && hostingSiteFilter(endpoint)) { + if (relyingParty.FilterEndpoint(endpoint)) { filteredEndpoints.Add(endpoint); } else { anyFilteredOut = true; diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs index d80bf6a..8be097f 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdAjaxTextBox.cs @@ -721,11 +721,16 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } var css = new HtmlLink(); - css.Href = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), EmbeddedStylesheetResourceName); - css.Attributes["rel"] = "stylesheet"; - css.Attributes["type"] = "text/css"; - ErrorUtilities.VerifyHost(this.Page.Header != null, OpenIdStrings.HeadTagMustIncludeRunatServer); - this.Page.Header.Controls.AddAt(0, css); // insert at top so host page can override + try { + css.Href = this.Page.ClientScript.GetWebResourceUrl(this.GetType(), EmbeddedStylesheetResourceName); + css.Attributes["rel"] = "stylesheet"; + css.Attributes["type"] = "text/css"; + ErrorUtilities.VerifyHost(this.Page.Header != null, OpenIdStrings.HeadTagMustIncludeRunatServer); + this.Page.Header.Controls.AddAt(0, css); // insert at top so host page can override + } catch { + css.Dispose(); + throw; + } this.PrepareClientJavascript(); diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdButton.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdButton.cs index dbf6944..6243917 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdButton.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdButton.cs @@ -141,6 +141,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// Sends server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object, which writes the content to be rendered on the client. /// </summary> /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param> + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.HtmlTextWriter.WriteEncodedText(System.String)", Justification = "Not localizable")] protected override void Render(HtmlTextWriter writer) { if (string.IsNullOrEmpty(this.Identifier)) { writer.WriteEncodedText(string.Format(CultureInfo.CurrentCulture, "[{0}]", OpenIdStrings.NoIdentifierSet)); diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs index 3f2b196..456b6bb 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdLogin.cs @@ -316,7 +316,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// Gets or sets the text to display if the user attempts to login /// without providing an Identifier. /// </summary> - [Bindable(true)] + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "br", Justification = "HTML"), Bindable(true)] [Category("Appearance")] [DefaultValue(RequiredTextDefault)] [Localizable(true)] @@ -336,7 +336,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <summary> /// Gets or sets the text to display if the user provides an invalid form for an Identifier. /// </summary> - [SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Property grid only supports primitive types.")] + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "br", Justification = "HTML"), SuppressMessage("Microsoft.Design", "CA1056:UriPropertiesShouldNotBeStrings", Justification = "Property grid only supports primitive types.")] [Bindable(true)] [Category("Appearance")] [DefaultValue(UriFormatTextDefault)] @@ -687,150 +687,156 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <summary> /// Initializes the child controls. /// </summary> + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.WebControl.set_ToolTip(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.Label.set_Text(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.HyperLink.set_Text(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.CheckBox.set_Text(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.Button.set_Text(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.BaseValidator.set_ErrorMessage(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "br", Justification = "HTML"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "OpenID", Justification = "It is correct"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "MyOpenID", Justification = "Correct spelling"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "myopenid", Justification = "URL")] protected void InitializeControls() { this.panel = new Panel(); Table table = new Table(); - TableRow row1, row2, row3; - TableCell cell; - table.Rows.Add(row1 = new TableRow()); - table.Rows.Add(row2 = new TableRow()); - table.Rows.Add(row3 = new TableRow()); - - // top row, left cell - cell = new TableCell(); try { - this.label = new HtmlGenericControl("label"); - this.label.InnerText = LabelTextDefault; - cell.Controls.Add(this.label); - row1.Cells.Add(cell); - } catch { - cell.Dispose(); - throw; - } + TableRow row1, row2, row3; + TableCell cell; + table.Rows.Add(row1 = new TableRow()); + table.Rows.Add(row2 = new TableRow()); + table.Rows.Add(row3 = new TableRow()); + + // top row, left cell + cell = new TableCell(); + try { + this.label = new HtmlGenericControl("label"); + this.label.InnerText = LabelTextDefault; + cell.Controls.Add(this.label); + row1.Cells.Add(cell); + } catch { + cell.Dispose(); + throw; + } - // top row, middle cell - cell = new TableCell(); - try { - cell.Controls.Add(new InPlaceControl(this)); - row1.Cells.Add(cell); - } catch { - cell.Dispose(); - throw; - } + // top row, middle cell + cell = new TableCell(); + try { + cell.Controls.Add(new InPlaceControl(this)); + row1.Cells.Add(cell); + } catch { + cell.Dispose(); + throw; + } - // top row, right cell - cell = new TableCell(); - try { - this.loginButton = new Button(); - this.loginButton.ID = this.ID + "_loginButton"; - this.loginButton.Text = ButtonTextDefault; - this.loginButton.ToolTip = ButtonToolTipDefault; - this.loginButton.Click += this.LoginButton_Click; - this.loginButton.ValidationGroup = ValidationGroupDefault; + // top row, right cell + cell = new TableCell(); + try { + this.loginButton = new Button(); + this.loginButton.ID = this.ID + "_loginButton"; + this.loginButton.Text = ButtonTextDefault; + this.loginButton.ToolTip = ButtonToolTipDefault; + this.loginButton.Click += this.LoginButton_Click; + this.loginButton.ValidationGroup = ValidationGroupDefault; #if !Mono - this.panel.DefaultButton = this.loginButton.ID; + this.panel.DefaultButton = this.loginButton.ID; #endif - cell.Controls.Add(this.loginButton); - row1.Cells.Add(cell); - } catch { - cell.Dispose(); - throw; - } + cell.Controls.Add(this.loginButton); + row1.Cells.Add(cell); + } catch { + cell.Dispose(); + throw; + } - // middle row, left cell - row2.Cells.Add(new TableCell()); + // middle row, left cell + row2.Cells.Add(new TableCell()); + + // middle row, middle cell + cell = new TableCell(); + try { + cell.Style[HtmlTextWriterStyle.Color] = "gray"; + cell.Style[HtmlTextWriterStyle.FontSize] = "smaller"; + this.requiredValidator = new RequiredFieldValidator(); + this.requiredValidator.ErrorMessage = RequiredTextDefault + RequiredTextSuffix; + this.requiredValidator.Text = RequiredTextDefault + RequiredTextSuffix; + this.requiredValidator.Display = ValidatorDisplay.Dynamic; + this.requiredValidator.ValidationGroup = ValidationGroupDefault; + cell.Controls.Add(this.requiredValidator); + this.identifierFormatValidator = new CustomValidator(); + this.identifierFormatValidator.ErrorMessage = UriFormatTextDefault + RequiredTextSuffix; + this.identifierFormatValidator.Text = UriFormatTextDefault + RequiredTextSuffix; + this.identifierFormatValidator.ServerValidate += this.IdentifierFormatValidator_ServerValidate; + this.identifierFormatValidator.Enabled = UriValidatorEnabledDefault; + this.identifierFormatValidator.Display = ValidatorDisplay.Dynamic; + this.identifierFormatValidator.ValidationGroup = ValidationGroupDefault; + cell.Controls.Add(this.identifierFormatValidator); + this.errorLabel = new Label(); + this.errorLabel.EnableViewState = false; + this.errorLabel.ForeColor = System.Drawing.Color.Red; + this.errorLabel.Style[HtmlTextWriterStyle.Display] = "block"; // puts it on its own line + this.errorLabel.Visible = false; + cell.Controls.Add(this.errorLabel); + this.examplePrefixLabel = new Label(); + this.examplePrefixLabel.Text = ExamplePrefixDefault; + cell.Controls.Add(this.examplePrefixLabel); + cell.Controls.Add(new LiteralControl(" ")); + this.exampleUrlLabel = new Label(); + this.exampleUrlLabel.Font.Bold = true; + this.exampleUrlLabel.Text = ExampleUrlDefault; + cell.Controls.Add(this.exampleUrlLabel); + row2.Cells.Add(cell); + } catch { + cell.Dispose(); + throw; + } - // middle row, middle cell - cell = new TableCell(); - try { - cell.Style[HtmlTextWriterStyle.Color] = "gray"; - cell.Style[HtmlTextWriterStyle.FontSize] = "smaller"; - this.requiredValidator = new RequiredFieldValidator(); - this.requiredValidator.ErrorMessage = RequiredTextDefault + RequiredTextSuffix; - this.requiredValidator.Text = RequiredTextDefault + RequiredTextSuffix; - this.requiredValidator.Display = ValidatorDisplay.Dynamic; - this.requiredValidator.ValidationGroup = ValidationGroupDefault; - cell.Controls.Add(this.requiredValidator); - this.identifierFormatValidator = new CustomValidator(); - this.identifierFormatValidator.ErrorMessage = UriFormatTextDefault + RequiredTextSuffix; - this.identifierFormatValidator.Text = UriFormatTextDefault + RequiredTextSuffix; - this.identifierFormatValidator.ServerValidate += this.IdentifierFormatValidator_ServerValidate; - this.identifierFormatValidator.Enabled = UriValidatorEnabledDefault; - this.identifierFormatValidator.Display = ValidatorDisplay.Dynamic; - this.identifierFormatValidator.ValidationGroup = ValidationGroupDefault; - cell.Controls.Add(this.identifierFormatValidator); - this.errorLabel = new Label(); - this.errorLabel.EnableViewState = false; - this.errorLabel.ForeColor = System.Drawing.Color.Red; - this.errorLabel.Style[HtmlTextWriterStyle.Display] = "block"; // puts it on its own line - this.errorLabel.Visible = false; - cell.Controls.Add(this.errorLabel); - this.examplePrefixLabel = new Label(); - this.examplePrefixLabel.Text = ExamplePrefixDefault; - cell.Controls.Add(this.examplePrefixLabel); - cell.Controls.Add(new LiteralControl(" ")); - this.exampleUrlLabel = new Label(); - this.exampleUrlLabel.Font.Bold = true; - this.exampleUrlLabel.Text = ExampleUrlDefault; - cell.Controls.Add(this.exampleUrlLabel); - row2.Cells.Add(cell); - } catch { - cell.Dispose(); - throw; - } + // middle row, right cell + cell = new TableCell(); + try { + cell.Style[HtmlTextWriterStyle.Color] = "gray"; + cell.Style[HtmlTextWriterStyle.FontSize] = "smaller"; + cell.Style[HtmlTextWriterStyle.TextAlign] = "center"; + this.registerLink = new HyperLink(); + this.registerLink.Text = RegisterTextDefault; + this.registerLink.ToolTip = RegisterToolTipDefault; + this.registerLink.NavigateUrl = RegisterUrlDefault; + this.registerLink.Visible = RegisterVisibleDefault; + cell.Controls.Add(this.registerLink); + row2.Cells.Add(cell); + } catch { + cell.Dispose(); + throw; + } - // middle row, right cell - cell = new TableCell(); - try { - cell.Style[HtmlTextWriterStyle.Color] = "gray"; - cell.Style[HtmlTextWriterStyle.FontSize] = "smaller"; - cell.Style[HtmlTextWriterStyle.TextAlign] = "center"; - this.registerLink = new HyperLink(); - this.registerLink.Text = RegisterTextDefault; - this.registerLink.ToolTip = RegisterToolTipDefault; - this.registerLink.NavigateUrl = RegisterUrlDefault; - this.registerLink.Visible = RegisterVisibleDefault; - cell.Controls.Add(this.registerLink); - row2.Cells.Add(cell); - } catch { - cell.Dispose(); - throw; - } + // bottom row, left cell + cell = new TableCell(); + row3.Cells.Add(cell); - // bottom row, left cell - cell = new TableCell(); - row3.Cells.Add(cell); + // bottom row, middle cell + cell = new TableCell(); + try { + this.rememberMeCheckBox = new CheckBox(); + this.rememberMeCheckBox.Text = RememberMeTextDefault; + this.rememberMeCheckBox.Checked = this.UsePersistentCookie != LogOnPersistence.Session; + this.rememberMeCheckBox.Visible = RememberMeVisibleDefault; + this.rememberMeCheckBox.CheckedChanged += this.RememberMeCheckBox_CheckedChanged; + cell.Controls.Add(this.rememberMeCheckBox); + row3.Cells.Add(cell); + } catch { + cell.Dispose(); + throw; + } - // bottom row, middle cell - cell = new TableCell(); - try { - this.rememberMeCheckBox = new CheckBox(); - this.rememberMeCheckBox.Text = RememberMeTextDefault; - this.rememberMeCheckBox.Checked = this.UsePersistentCookie != LogOnPersistence.Session; - this.rememberMeCheckBox.Visible = RememberMeVisibleDefault; - this.rememberMeCheckBox.CheckedChanged += this.RememberMeCheckBox_CheckedChanged; - cell.Controls.Add(this.rememberMeCheckBox); - row3.Cells.Add(cell); - } catch { - cell.Dispose(); - throw; - } + // bottom row, right cell + cell = new TableCell(); + try { + row3.Cells.Add(cell); + } catch { + cell.Dispose(); + throw; + } - // bottom row, right cell - cell = new TableCell(); - try { - row3.Cells.Add(cell); + // this sets all the controls' tab indexes + this.TabIndex = TabIndexDefault; + + this.panel.Controls.Add(table); } catch { - cell.Dispose(); + table.Dispose(); throw; } - // this sets all the controls' tab indexes - this.TabIndex = TabIndexDefault; - - this.panel.Controls.Add(table); - this.idselectorJavascript = new Literal(); this.panel.Controls.Add(this.idselectorJavascript); } @@ -849,6 +855,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// Renders the child controls. /// </summary> /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the rendered content.</param> + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Web.UI.WebControls.Literal.set_Text(System.String)", Justification = "By design"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "idselector", Justification = "HTML"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "charset", Justification = "html"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "src", Justification = "html"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "openidselector", Justification = "html"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "idselectorinputid", Justification = "html")] protected override void RenderChildren(HtmlTextWriter writer) { if (!this.DesignMode) { this.label.Attributes["for"] = this.ClientID; diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs index a5fdf9b..57c1f05 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingParty.cs @@ -39,6 +39,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <summary> /// Provides the programmatic facilities to act as an OpenID relying party. /// </summary> + [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Unavoidable")] [ContractVerification(true)] public class OpenIdRelyingParty : IDisposable { /// <summary> @@ -108,6 +109,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// </summary> /// <param name="associationStore">The association store. If null, the relying party will always operate in "dumb mode".</param> /// <param name="nonceStore">The nonce store to use. If null, the relying party will always operate in "dumb mode".</param> + [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling", Justification = "Unavoidable")] private OpenIdRelyingParty(IAssociationStore<Uri> associationStore, INonceStore nonceStore) { // If we are a smart-mode RP (supporting associations), then we MUST also be // capable of storing nonces to prevent replay attacks. @@ -542,15 +544,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { NegativeAssertionResponse negativeAssertion; IndirectSignedResponse positiveExtensionOnly; if ((positiveAssertion = message as PositiveAssertionResponse) != null) { - if (this.EndpointFilter != null) { - // We need to make sure that this assertion is coming from an endpoint - // that the host deems acceptable. - var providerEndpoint = new SimpleXrdsProviderEndpoint(positiveAssertion); - ErrorUtilities.VerifyProtocol( - this.EndpointFilter(providerEndpoint), - OpenIdStrings.PositiveAssertionFromNonWhitelistedProvider, - providerEndpoint.Uri); - } + // We need to make sure that this assertion is coming from an endpoint + // that the host deems acceptable. + var providerEndpoint = new SimpleXrdsProviderEndpoint(positiveAssertion); + ErrorUtilities.VerifyProtocol( + this.FilterEndpoint(providerEndpoint), + OpenIdStrings.PositiveAssertionFromNonQualifiedProvider, + providerEndpoint.Uri); var response = new PositiveAuthenticationResponse(positiveAssertion, this); foreach (var behavior in this.Behaviors) { @@ -660,8 +660,13 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// </remarks> internal static OpenIdRelyingParty CreateNonVerifying() { OpenIdRelyingParty rp = new OpenIdRelyingParty(); - rp.Channel = OpenIdChannel.CreateNonVerifyingChannel(); - return rp; + try { + rp.Channel = OpenIdChannel.CreateNonVerifyingChannel(); + return rp; + } catch { + rp.Dispose(); + throw; + } } /// <summary> @@ -672,13 +677,14 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <returns> /// The HTTP response to send to this HTTP request. /// </returns> + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "OpenID", Justification = "real word"), SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "iframe", Justification = "Code contracts")] internal OutgoingWebResponse ProcessResponseFromPopup(HttpRequestInfo request, Action<AuthenticationStatus> callback) { Contract.Requires<ArgumentNullException>(request != null); Contract.Ensures(Contract.Result<OutgoingWebResponse>() != null); string extensionsJson = null; var authResponse = this.NonVerifyingRelyingParty.GetResponse(); - ErrorUtilities.VerifyProtocol(authResponse != null, "OpenID popup window or iframe did not recognize an OpenID response in the request."); + ErrorUtilities.VerifyProtocol(authResponse != null, OpenIdStrings.PopupRedirectMissingResponse); // Give the caller a chance to notify the hosting page and fill up the clientScriptExtensions collection. if (callback != null) { @@ -761,6 +767,38 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { } /// <summary> + /// Checks whether a given OP Endpoint is permitted by the host relying party. + /// </summary> + /// <param name="endpoint">The OP endpoint.</param> + /// <returns><c>true</c> if the OP Endpoint is allowed; <c>false</c> otherwise.</returns> + protected internal bool FilterEndpoint(IProviderEndpoint endpoint) { + if (this.SecuritySettings.RejectAssertionsFromUntrustedProviders) { + if (!this.SecuritySettings.TrustedProviderEndpoints.Contains(endpoint.Uri)) { + Logger.OpenId.InfoFormat("Filtering out OP endpoint {0} because it is not on the exclusive trusted provider whitelist.", endpoint.Uri.AbsoluteUri); + return false; + } + } + + if (endpoint.Version < Protocol.Lookup(this.SecuritySettings.MinimumRequiredOpenIdVersion).Version) { + Logger.OpenId.InfoFormat( + "Filtering out OP endpoint {0} because it implements OpenID {1} but this relying party requires OpenID {2} or later.", + endpoint.Uri.AbsoluteUri, + endpoint.Version, + Protocol.Lookup(this.SecuritySettings.MinimumRequiredOpenIdVersion).Version); + return false; + } + + if (this.EndpointFilter != null) { + if (!this.EndpointFilter(endpoint)) { + Logger.OpenId.InfoFormat("Filtering out OP endpoint {0} because the host rejected it.", endpoint.Uri.AbsoluteUri); + return false; + } + } + + return true; + } + + /// <summary> /// Releases unmanaged and - optionally - managed resources /// </summary> /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs index 62f6554..7cda8e0 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/OpenIdRelyingPartyControlBase.cs @@ -546,7 +546,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// <summary> /// Enables a server control to perform final clean up before it is released from memory. /// </summary> - [SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Base class doesn't implement virtual Dispose(bool), so we must call its Dispose() method.")] + [SuppressMessage("Microsoft.Usage", "CA2202:Do not dispose objects multiple times", Justification = "Unavoidable because base class does not expose a protected virtual Dispose(bool) method."), SuppressMessage("Microsoft.Design", "CA1063:ImplementIDisposableCorrectly", Justification = "Base class doesn't implement virtual Dispose(bool), so we must call its Dispose() method.")] public sealed override void Dispose() { this.Dispose(true); base.Dispose(); @@ -809,6 +809,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { /// Configures the relying party. /// </summary> /// <param name="relyingParty">The relying party.</param> + [SuppressMessage("Microsoft.Maintainability", "CA1500:VariableNamesShouldNotMatchFieldNames", MessageId = "relyingParty", Justification = "This makes it possible for overrides to see the value before it is set on a field.")] protected virtual void ConfigureRelyingParty(OpenIdRelyingParty relyingParty) { Contract.Requires<ArgumentNullException>(relyingParty != null); diff --git a/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs b/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs index a7686c5..fc6d4c7 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingParty/RelyingPartySecuritySettings.cs @@ -8,6 +8,8 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { using System; using System.Collections.Generic; using System.Collections.ObjectModel; + using System.Diagnostics.CodeAnalysis; + using System.Diagnostics.Contracts; using System.Linq; using DotNetOpenAuth.Messaging; @@ -28,6 +30,7 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { this.PrivateSecretMaximumAge = TimeSpan.FromDays(7); this.ProtectDownlevelReplayAttacks = ProtectDownlevelReplayAttacksDefault; this.AllowApproximateIdentifierDiscovery = true; + this.TrustedProviderEndpoints = new HashSet<Uri>(); } /// <summary> @@ -143,6 +146,19 @@ namespace DotNetOpenAuth.OpenId.RelyingParty { public bool AllowApproximateIdentifierDiscovery { get; set; } /// <summary> + /// Gets the set of trusted OpenID Provider Endpoint URIs. + /// </summary> + public HashSet<Uri> TrustedProviderEndpoints { get; private set; } + + /// <summary> + /// Gets or sets a value indicating whether any login attempt coming from an OpenID Provider Endpoint that is not on this + /// whitelist of trusted OP Endpoints will be rejected. If the trusted providers list is empty and this value + /// is true, all assertions are rejected. + /// </summary> + /// <value>Default is <c>false</c>.</value> + public bool RejectAssertionsFromUntrustedProviders { get; set; } + + /// <summary> /// Gets or sets a value indicating whether special measures are taken to /// protect users from replay attacks when those users' identities are hosted /// by OpenID 1.x Providers. diff --git a/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs b/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs index 279ca30..7926e8f 100644 --- a/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs +++ b/src/DotNetOpenAuth/OpenId/RelyingPartyDescription.cs @@ -7,6 +7,7 @@ namespace DotNetOpenAuth.OpenId { using System; using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.Diagnostics.Contracts; using System.Linq; using System.Text; @@ -50,6 +51,7 @@ namespace DotNetOpenAuth.OpenId { /// </summary> /// <param name="supportedServiceTypeUris">The supported service type URIs.</param> /// <returns>The best OpenID protocol version to use when communicating with this Provider.</returns> + [SuppressMessage("Microsoft.Naming", "CA2204:Literals should be spelled correctly", MessageId = "OpenID", Justification = "Spelling correct")] private static Protocol GetProtocolFromServices(string[] supportedServiceTypeUris) { Protocol protocol = Protocol.FindBestVersion(p => p.RPReturnToTypeURI, supportedServiceTypeUris); if (protocol == null) { diff --git a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs index ffd8d13..74fe658 100644 --- a/src/DotNetOpenAuth/OpenId/UriIdentifier.cs +++ b/src/DotNetOpenAuth/OpenId/UriIdentifier.cs @@ -480,7 +480,7 @@ namespace DotNetOpenAuth.OpenId { Contract.Requires<InternalErrorException>(schemeSubstitution); Contract.Ensures(!string.IsNullOrEmpty(Contract.Result<string>())); - int delimiterIndex = normal.IndexOf(Uri.SchemeDelimiter); + int delimiterIndex = normal.IndexOf(Uri.SchemeDelimiter, StringComparison.Ordinal); string normalScheme = delimiterIndex < 0 ? normal : normal.Substring(0, delimiterIndex); string nonCompressingScheme; if (string.Equals(normalScheme, Uri.UriSchemeHttp, StringComparison.OrdinalIgnoreCase) || diff --git a/src/DotNetOpenAuth/Xrds/XrdsDocument.cs b/src/DotNetOpenAuth/Xrds/XrdsDocument.cs index e2c2d72..040c994 100644 --- a/src/DotNetOpenAuth/Xrds/XrdsDocument.cs +++ b/src/DotNetOpenAuth/Xrds/XrdsDocument.cs @@ -6,6 +6,7 @@ namespace DotNetOpenAuth.Xrds { using System.Collections.Generic; + using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Xml; @@ -51,6 +52,7 @@ namespace DotNetOpenAuth.Xrds { /// Initializes a new instance of the <see cref="XrdsDocument"/> class. /// </summary> /// <param name="xml">The text that is the XRDS document.</param> + [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope", Justification = "Fixing would decrease readability, and not likely avoid any finalizer on a StringReader anyway.")] public XrdsDocument(string xml) : this(new XPathDocument(new StringReader(xml)).CreateNavigator()) { } diff --git a/src/DotNetOpenAuth/XrdsPublisher.cs b/src/DotNetOpenAuth/XrdsPublisher.cs index 83d82ff..03c32c1 100644 --- a/src/DotNetOpenAuth/XrdsPublisher.cs +++ b/src/DotNetOpenAuth/XrdsPublisher.cs @@ -208,7 +208,7 @@ namespace DotNetOpenAuth { /// Renders the HTTP Header and/or HTML HEAD tags. /// </summary> /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the server control content.</param> - [SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Uri(Uri, string) accepts second arguments that Uri(Uri, new Uri(string)) does not that we must support.")] + [SuppressMessage("Microsoft.Globalization", "CA1303:Do not pass literals as localized parameters", MessageId = "System.Diagnostics.Contracts.__ContractsRuntime.Assume(System.Boolean,System.String,System.String)", Justification = "Code contracts"), SuppressMessage("Microsoft.Usage", "CA2234:PassSystemUriObjectsInsteadOfStrings", Justification = "Uri(Uri, string) accepts second arguments that Uri(Uri, new Uri(string)) does not that we must support.")] protected override void Render(HtmlTextWriter writer) { Contract.Assume(writer != null, "Missing contract."); if (this.Enabled && this.Visible && !string.IsNullOrEmpty(this.XrdsUrl)) { |