diff options
Diffstat (limited to 'src/DotNetOpenAuth.Core/Messaging')
6 files changed, 74 insertions, 9 deletions
diff --git a/src/DotNetOpenAuth.Core/Messaging/DataBagFormatterBase.cs b/src/DotNetOpenAuth.Core/Messaging/DataBagFormatterBase.cs index 69ee8dc..2452502 100644 --- a/src/DotNetOpenAuth.Core/Messaging/DataBagFormatterBase.cs +++ b/src/DotNetOpenAuth.Core/Messaging/DataBagFormatterBase.cs @@ -217,8 +217,8 @@ namespace DotNetOpenAuth.Messaging { if (this.signed) { using (var dataStream = new MemoryStream(data)) { var dataReader = new BinaryReader(dataStream); - signature = dataReader.ReadBuffer(); - data = dataReader.ReadBuffer(); + signature = dataReader.ReadBuffer(1024); + data = dataReader.ReadBuffer(8 * 1024); } // Verify that the verification code was issued by message authorization server. diff --git a/src/DotNetOpenAuth.Core/Messaging/MessagePartAttribute.cs b/src/DotNetOpenAuth.Core/Messaging/MessagePartAttribute.cs index 6fd95ee..8ef9b7e 100644 --- a/src/DotNetOpenAuth.Core/Messaging/MessagePartAttribute.cs +++ b/src/DotNetOpenAuth.Core/Messaging/MessagePartAttribute.cs @@ -101,6 +101,15 @@ namespace DotNetOpenAuth.Messaging { } /// <summary> + /// Gets or sets a value indicating whether the value contained by this property contains + /// sensitive information that should generally not be logged. + /// </summary> + /// <value> + /// <c>true</c> if this instance is security sensitive; otherwise, <c>false</c>. + /// </value> + public bool IsSecuritySensitive { get; set; } + + /// <summary> /// Gets or sets the minimum version of the protocol this attribute applies to /// and overrides any attributes with lower values for this property. /// </summary> diff --git a/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.Designer.cs b/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.Designer.cs index 2fe273f..4f89589 100644 --- a/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.Designer.cs +++ b/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. -// Runtime Version:4.0.30319.239 +// Runtime Version:4.0.30319.18010 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -106,6 +106,15 @@ namespace DotNetOpenAuth.Messaging { } /// <summary> + /// Looks up a localized string similar to Decoding failed due to data corruption.. + /// </summary> + internal static string DataCorruptionDetected { + get { + return ResourceManager.GetString("DataCorruptionDetected", resourceCulture); + } + } + + /// <summary> /// Looks up a localized string similar to An instance of type {0} was expected, but received unexpected derived type {1}.. /// </summary> internal static string DerivedTypeNotExpected { diff --git a/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.resx b/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.resx index fbdb63d..15ca046 100644 --- a/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.resx +++ b/src/DotNetOpenAuth.Core/Messaging/MessagingStrings.resx @@ -112,10 +112,10 @@ <value>2.0</value> </resheader> <resheader name="reader"> - <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name="writer"> - <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> + <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <data name="ArgumentPropertyMissing" xml:space="preserve"> <value>Argument's {0}.{1} property is required but is empty or null.</value> @@ -333,4 +333,7 @@ <data name="UnexpectedBufferLength" xml:space="preserve"> <value>Unexpected buffer length.</value> </data> + <data name="DataCorruptionDetected" xml:space="preserve"> + <value>Decoding failed due to data corruption.</value> + </data> </root>
\ No newline at end of file diff --git a/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs b/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs index 5390da5..7aa4469 100644 --- a/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs +++ b/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs @@ -15,6 +15,9 @@ namespace DotNetOpenAuth.Messaging { using System.IO.Compression; using System.Linq; using System.Net; +#if CLR4 + using System.Net.Http; +#endif using System.Net.Mime; using System.Runtime.Serialization.Json; using System.Security; @@ -161,6 +164,29 @@ namespace DotNetOpenAuth.Messaging { return new OutgoingWebResponseActionResult(response); } +#if CLR4 + /// <summary> + /// Transforms an OutgoingWebResponse to a Web API-friendly HttpResponseMessage. + /// </summary> + /// <param name="outgoingResponse">The response to send to the user agent.</param> + /// <returns>The <see cref="HttpResponseMessage"/> instance to be returned by the Web API method.</returns> + public static HttpResponseMessage AsHttpResponseMessage(this OutgoingWebResponse outgoingResponse) { + HttpResponseMessage response = new HttpResponseMessage(outgoingResponse.Status); + if (outgoingResponse.ResponseStream != null) { + response.Content = new StreamContent(outgoingResponse.ResponseStream); + } + + var responseHeaders = outgoingResponse.Headers; + foreach (var header in responseHeaders.AllKeys) { + if (!response.Headers.TryAddWithoutValidation(header, responseHeaders[header])) { + response.Content.Headers.TryAddWithoutValidation(header, responseHeaders[header]); + } + } + + return response; + } +#endif + /// <summary> /// Gets the original request URL, as seen from the browser before any URL rewrites on the server if any. /// Cookieless session directory (if applicable) is also included. @@ -797,7 +823,7 @@ namespace DotNetOpenAuth.Messaging { using (var encryptedStream = new MemoryStream(buffer)) { var encryptedStreamReader = new BinaryReader(encryptedStream); - byte[] encryptedPrequel = encryptedStreamReader.ReadBytes(encryptedStreamReader.ReadInt32()); + byte[] encryptedPrequel = encryptedStreamReader.ReadBuffer(4096); byte[] prequel = crypto.Decrypt(encryptedPrequel, false); using (var symmetricCrypto = new RijndaelManaged()) { @@ -989,7 +1015,7 @@ namespace DotNetOpenAuth.Messaging { missingPaddingCharacters = 0; break; default: - throw ErrorUtilities.ThrowInternal("No more than two padding characters should be present for base64."); + throw new ProtocolException(MessagingStrings.DataCorruptionDetected, new ArgumentException("No more than two padding characters should be present for base64.")); } var builder = new StringBuilder(base64WebSafe, base64WebSafe.Length + missingPaddingCharacters); builder.Replace('-', '+').Replace('_', '/'); @@ -1659,10 +1685,17 @@ namespace DotNetOpenAuth.Messaging { /// Reads a buffer that is prefixed with its own length. /// </summary> /// <param name="reader">The binary reader positioned at the buffer length.</param> + /// <param name="maxBufferSize"> + /// The maximum size of the buffer that should be permitted. + /// Although the stream will indicate the size of the buffer, this mitigates data corruption + /// or DoS attacks causing the web server to allocate too much memory for a small data packet. + /// </param> /// <returns>The read buffer.</returns> - internal static byte[] ReadBuffer(this BinaryReader reader) { + internal static byte[] ReadBuffer(this BinaryReader reader, int maxBufferSize) { Requires.NotNull(reader, "reader"); + Requires.InRange(maxBufferSize > 0 && maxBufferSize < 1024 * 1024, "maxBufferSize"); int length = reader.ReadInt32(); + ErrorUtilities.VerifyProtocol(length <= maxBufferSize, MessagingStrings.DataCorruptionDetected); byte[] buffer = new byte[length]; ErrorUtilities.VerifyProtocol(reader.Read(buffer, 0, length) == length, MessagingStrings.UnexpectedBufferLength); return buffer; @@ -1894,7 +1927,8 @@ namespace DotNetOpenAuth.Messaging { // the public URL: if (serverVariables["HTTP_HOST"] != null) { ErrorUtilities.VerifySupported(request.Url.Scheme == Uri.UriSchemeHttps || request.Url.Scheme == Uri.UriSchemeHttp, "Only HTTP and HTTPS are supported protocols."); - string scheme = serverVariables["HTTP_X_FORWARDED_PROTO"] ?? request.Url.Scheme; + string scheme = serverVariables["HTTP_X_FORWARDED_PROTO"] ?? + (string.Equals(serverVariables["HTTP_FRONT_END_HTTPS"], "on", StringComparison.OrdinalIgnoreCase) ? Uri.UriSchemeHttps : request.Url.Scheme); Uri hostAndPort = new Uri(scheme + Uri.SchemeDelimiter + serverVariables["HTTP_HOST"]); UriBuilder publicRequestUri = new UriBuilder(request.Url); publicRequestUri.Scheme = scheme; diff --git a/src/DotNetOpenAuth.Core/Messaging/Reflection/MessagePart.cs b/src/DotNetOpenAuth.Core/Messaging/Reflection/MessagePart.cs index b2c4664..0f140d6 100644 --- a/src/DotNetOpenAuth.Core/Messaging/Reflection/MessagePart.cs +++ b/src/DotNetOpenAuth.Core/Messaging/Reflection/MessagePart.cs @@ -115,6 +115,7 @@ namespace DotNetOpenAuth.Messaging.Reflection { this.RequiredProtection = attribute.RequiredProtection; this.IsRequired = attribute.IsRequired; this.AllowEmpty = attribute.AllowEmpty; + this.IsSecuritySensitive = attribute.IsSecuritySensitive; this.memberDeclaredType = (this.field != null) ? this.field.FieldType : this.property.PropertyType; this.defaultMemberValue = DeriveDefaultValue(this.memberDeclaredType); @@ -189,6 +190,15 @@ namespace DotNetOpenAuth.Messaging.Reflection { internal bool IsConstantValueAvailableStatically { get; set; } /// <summary> + /// Gets or sets a value indicating whether the value contained by this property contains + /// sensitive information that should generally not be logged. + /// </summary> + /// <value> + /// <c>true</c> if this instance is security sensitive; otherwise, <c>false</c>. + /// </value> + internal bool IsSecuritySensitive { get; set; } + + /// <summary> /// Gets the static constant value for this message part without a message instance. /// </summary> internal string StaticConstantValue { |