//-----------------------------------------------------------------------
//
// Copyright (c) Outercurve Foundation. All rights reserved.
//
//-----------------------------------------------------------------------
namespace DotNetOpenAuth.Configuration {
using System;
using System.Configuration;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.Messaging.Bindings;
///
/// Represents the <messaging> element in the host's .config file.
///
public class MessagingElement : ConfigurationSection {
///
/// The name of the <webResourceUrlProvider> sub-element.
///
private const string WebResourceUrlProviderName = "webResourceUrlProvider";
///
/// The name of the <untrustedWebRequest> sub-element.
///
private const string UntrustedWebRequestElementName = "untrustedWebRequest";
///
/// The name of the attribute that stores the association's maximum lifetime.
///
private const string MaximumMessageLifetimeConfigName = "lifetime";
///
/// The name of the attribute that stores the maximum allowable clock skew.
///
private const string MaximumClockSkewConfigName = "clockSkew";
///
/// The name of the attribute that indicates whether to disable SSL requirements across the library.
///
private const string RelaxSslRequirementsConfigName = "relaxSslRequirements";
///
/// The name of the attribute that controls whether messaging rules are strictly followed.
///
private const string StrictConfigName = "strict";
///
/// The default value for the property.
///
///
/// 2KB, recommended by OpenID group
///
private const int DefaultMaximumIndirectMessageUrlLength = 2 * 1024;
///
/// The name of the attribute that controls the maximum length of a URL before it is converted
/// to a POST payload.
///
private const string MaximumIndirectMessageUrlLengthConfigName = "maximumIndirectMessageUrlLength";
///
/// Gets the name of the @privateSecretMaximumAge attribute.
///
private const string PrivateSecretMaximumAgeConfigName = "privateSecretMaximumAge";
///
/// The name of the <messaging> sub-element.
///
private const string MessagingElementName = DotNetOpenAuthSection.SectionName + "/messaging";
///
/// Gets the configuration section from the .config file.
///
public static MessagingElement Configuration {
get {
return (MessagingElement)ConfigurationManager.GetSection(MessagingElementName) ?? new MessagingElement();
}
}
///
/// Gets the actual maximum message lifetime that a program should allow.
///
/// The sum of the and
/// property values.
public TimeSpan MaximumMessageLifetime {
get { return this.MaximumMessageLifetimeNoSkew + this.MaximumClockSkew; }
}
///
/// Gets or sets the maximum lifetime of a private symmetric secret,
/// that may be used for signing or encryption.
///
/// The default value is 28 days (twice the age of the longest association).
[ConfigurationProperty(PrivateSecretMaximumAgeConfigName, DefaultValue = "28.00:00:00")]
public TimeSpan PrivateSecretMaximumAge {
get { return (TimeSpan)this[PrivateSecretMaximumAgeConfigName]; }
set { this[PrivateSecretMaximumAgeConfigName] = value; }
}
///
/// Gets or sets the time between a message's creation and its receipt
/// before it is considered expired.
///
///
/// The default value value is 3 minutes.
///
///
/// Smaller timespans mean lower tolerance for delays in message delivery.
/// Larger timespans mean more nonces must be stored to provide replay protection.
/// The maximum age a message implementing the
/// interface can be before
/// being discarded as too old.
/// This time limit should NOT take into account expected
/// time skew for servers across the Internet. Time skew is added to
/// this value and is controlled by the property.
///
[ConfigurationProperty(MaximumMessageLifetimeConfigName, DefaultValue = "00:03:00")]
internal TimeSpan MaximumMessageLifetimeNoSkew {
get { return (TimeSpan)this[MaximumMessageLifetimeConfigName]; }
set { this[MaximumMessageLifetimeConfigName] = value; }
}
///
/// Gets or sets the maximum clock skew.
///
/// The default value is 10 minutes.
///
/// Smaller timespans mean lower tolerance for
/// time variance due to server clocks not being synchronized.
/// Larger timespans mean greater chance for replay attacks and
/// larger nonce caches.
/// For example, if a server could conceivably have its
/// clock d = 5 minutes off UTC time, then any two servers could have
/// their clocks disagree by as much as 2*d = 10 minutes.
///
[ConfigurationProperty(MaximumClockSkewConfigName, DefaultValue = "00:10:00")]
internal TimeSpan MaximumClockSkew {
get { return (TimeSpan)this[MaximumClockSkewConfigName]; }
set { this[MaximumClockSkewConfigName] = value; }
}
///
/// Gets or sets a value indicating whether SSL requirements within the library are disabled/relaxed.
/// Use for TESTING ONLY.
///
[ConfigurationProperty(RelaxSslRequirementsConfigName, DefaultValue = false)]
internal bool RelaxSslRequirements {
get { return (bool)this[RelaxSslRequirementsConfigName]; }
set { this[RelaxSslRequirementsConfigName] = value; }
}
///
/// Gets or sets a value indicating whether messaging rules are strictly
/// adhered to.
///
/// true by default.
///
/// Strict will require that remote parties adhere strictly to the specifications,
/// even when a loose interpretation would not compromise security.
/// true is a good default because it shakes out interoperability bugs in remote services
/// so they can be identified and corrected. But some web sites want things to Just Work
/// more than they want to file bugs against others, so false is the setting for them.
///
[ConfigurationProperty(StrictConfigName, DefaultValue = true)]
internal bool Strict {
get { return (bool)this[StrictConfigName]; }
set { this[StrictConfigName] = value; }
}
///
/// Gets or sets the configuration for the UntrustedWebRequestHandler class.
///
/// The untrusted web request.
[ConfigurationProperty(UntrustedWebRequestElementName)]
internal UntrustedWebRequestElement UntrustedWebRequest {
get { return (UntrustedWebRequestElement)this[UntrustedWebRequestElementName] ?? new UntrustedWebRequestElement(); }
set { this[UntrustedWebRequestElementName] = value; }
}
///
/// 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.
///
/// The default value is 2048.
[ConfigurationProperty(MaximumIndirectMessageUrlLengthConfigName, DefaultValue = DefaultMaximumIndirectMessageUrlLength)]
[IntegerValidator(MinValue = 500, MaxValue = 4096)]
internal int MaximumIndirectMessageUrlLength {
get { return (int)this[MaximumIndirectMessageUrlLengthConfigName]; }
set { this[MaximumIndirectMessageUrlLengthConfigName] = value; }
}
///
/// Gets or sets the embedded resource retrieval provider.
///
///
/// The embedded resource retrieval provider.
///
[ConfigurationProperty(WebResourceUrlProviderName)]
internal TypeConfigurationElement EmbeddedResourceRetrievalProvider {
get { return (TypeConfigurationElement)this[WebResourceUrlProviderName] ?? new TypeConfigurationElement(); }
set { this[WebResourceUrlProviderName] = value; }
}
}
}