summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs')
-rw-r--r--src/DotNetOpenAuth.Core/Messaging/MessagingUtilities.cs42
1 files changed, 38 insertions, 4 deletions
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;