summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenId
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenId')
-rw-r--r--src/DotNetOpenId/DiffieHellmanUtil.cs5
-rw-r--r--src/DotNetOpenId/Extensions/AttributeExchange/FetchResponse.cs4
-rw-r--r--src/DotNetOpenId/HmacShaAssociation.cs7
-rw-r--r--src/DotNetOpenId/Loggers/Log4NetLogger.cs6
-rw-r--r--src/DotNetOpenId/RelyingParty/Token.cs8
-rw-r--r--src/DotNetOpenId/UntrustedWebRequest.cs10
-rw-r--r--src/DotNetOpenId/UntrustedWebResponse.cs23
-rw-r--r--src/DotNetOpenId/UriIdentifier.cs21
-rw-r--r--src/DotNetOpenId/Yadis/Yadis.cs2
9 files changed, 58 insertions, 28 deletions
diff --git a/src/DotNetOpenId/DiffieHellmanUtil.cs b/src/DotNetOpenId/DiffieHellmanUtil.cs
index ac3bcff..492f757 100644
--- a/src/DotNetOpenId/DiffieHellmanUtil.cs
+++ b/src/DotNetOpenId/DiffieHellmanUtil.cs
@@ -1,5 +1,6 @@
using System;
using System.Globalization;
+using System.Collections.Generic;
using System.Security.Cryptography;
using Org.Mentalis.Security.Cryptography;
@@ -17,12 +18,12 @@ namespace DotNetOpenId {
internal readonly HashAlgorithm Algorithm;
}
- static DHSha[] DiffieHellmanSessionTypes = {
+ static DHSha[] DiffieHellmanSessionTypes = new List<DHSha> {
new DHSha(new SHA512Managed(), protocol => protocol.Args.SessionType.DH_SHA512),
new DHSha(new SHA384Managed(), protocol => protocol.Args.SessionType.DH_SHA384),
new DHSha(new SHA256Managed(), protocol => protocol.Args.SessionType.DH_SHA256),
new DHSha(new SHA1Managed(), protocol => protocol.Args.SessionType.DH_SHA1),
- };
+ }.ToArray();
public static HashAlgorithm Lookup(Protocol protocol, string name) {
foreach (DHSha dhsha in DiffieHellmanSessionTypes) {
diff --git a/src/DotNetOpenId/Extensions/AttributeExchange/FetchResponse.cs b/src/DotNetOpenId/Extensions/AttributeExchange/FetchResponse.cs
index 3878d2c..1d58851 100644
--- a/src/DotNetOpenId/Extensions/AttributeExchange/FetchResponse.cs
+++ b/src/DotNetOpenId/Extensions/AttributeExchange/FetchResponse.cs
@@ -116,8 +116,8 @@ namespace DotNetOpenId.Extensions.AttributeExchange {
bool countSent = false;
string countString;
if (fields.TryGetValue("count." + alias, out countString)) {
- if (!int.TryParse(countString, out count) || count <= 0) {
- Logger.ErrorFormat("Failed to parse count.{0} value to a positive integer.", alias);
+ if (!int.TryParse(countString, out count) || count < 0) {
+ Logger.ErrorFormat("Failed to parse count.{0} value to a non-negative integer.", alias);
continue;
}
countSent = true;
diff --git a/src/DotNetOpenId/HmacShaAssociation.cs b/src/DotNetOpenId/HmacShaAssociation.cs
index a754aca..dd66900 100644
--- a/src/DotNetOpenId/HmacShaAssociation.cs
+++ b/src/DotNetOpenId/HmacShaAssociation.cs
@@ -1,5 +1,6 @@
using System;
using System.Diagnostics;
+using System.Collections.Generic;
using System.Security.Cryptography;
namespace DotNetOpenId {
@@ -14,7 +15,7 @@ namespace DotNetOpenId {
/// </summary>
internal int SecretLength { get { return BaseHashAlgorithm.HashSize / 8; } }
}
- static HmacSha[] HmacShaAssociationTypes = {
+ static HmacSha[] HmacShaAssociationTypes = new List<HmacSha> {
new HmacSha {
CreateHasher = secretKey => new HMACSHA512(secretKey),
GetAssociationType = protocol => protocol.Args.SignatureAlgorithm.HMAC_SHA512,
@@ -35,7 +36,7 @@ namespace DotNetOpenId {
GetAssociationType = protocol => protocol.Args.SignatureAlgorithm.HMAC_SHA1,
BaseHashAlgorithm = new SHA1Managed(),
},
- };
+ }.ToArray();
public static HmacShaAssociation Create(Protocol protocol, string associationType,
string handle, byte[] secret, TimeSpan totalLifeLength) {
@@ -142,4 +143,4 @@ namespace DotNetOpenId {
return typeIdentity.CreateHasher(SecretKey);
}
}
-} \ No newline at end of file
+}
diff --git a/src/DotNetOpenId/Loggers/Log4NetLogger.cs b/src/DotNetOpenId/Loggers/Log4NetLogger.cs
index 36ca3f2..6d9a120 100644
--- a/src/DotNetOpenId/Loggers/Log4NetLogger.cs
+++ b/src/DotNetOpenId/Loggers/Log4NetLogger.cs
@@ -33,7 +33,11 @@ namespace DotNetOpenId.Loggers {
/// Creates the log4net.LogManager. Call ONLY once log4net.dll is known to be present.
/// </summary>
static ILog createLogger() {
- return new Log4NetLogger(log4net.LogManager.GetLogger("DotNetOpenId"));
+ try {
+ return new Log4NetLogger(log4net.LogManager.GetLogger("DotNetOpenId"));
+ } catch (FileLoadException) { // wrong log4net.dll version
+ return null;
+ }
}
#region ILog Members
diff --git a/src/DotNetOpenId/RelyingParty/Token.cs b/src/DotNetOpenId/RelyingParty/Token.cs
index c546cb1..68a4e76 100644
--- a/src/DotNetOpenId/RelyingParty/Token.cs
+++ b/src/DotNetOpenId/RelyingParty/Token.cs
@@ -79,7 +79,13 @@ namespace DotNetOpenId.RelyingParty {
/// by discovery (slow but secure).
/// </remarks>
public static Token Deserialize(string token, INonceStore store) {
- byte[] tok = Convert.FromBase64String(token);
+ byte[] tok;
+ try {
+ tok = Convert.FromBase64String(token);
+ } catch (FormatException ex) {
+ throw new OpenIdException(string.Format(CultureInfo.CurrentCulture,
+ Strings.ExpectedBase64OpenIdQueryParameter, token), null, ex);
+ }
if (tok.Length < 1) throw new OpenIdException(Strings.InvalidSignature);
bool signaturePresent = tok[0] == 1;
bool signatureVerified = false;
diff --git a/src/DotNetOpenId/UntrustedWebRequest.cs b/src/DotNetOpenId/UntrustedWebRequest.cs
index 6a997a4..4ba07af 100644
--- a/src/DotNetOpenId/UntrustedWebRequest.cs
+++ b/src/DotNetOpenId/UntrustedWebRequest.cs
@@ -224,11 +224,11 @@ namespace DotNetOpenId {
}
}
- static UntrustedWebResponse getResponse(Uri requestUri, HttpWebResponse resp) {
+ static UntrustedWebResponse getResponse(Uri requestUri, Uri finalRequestUri, HttpWebResponse resp) {
byte[] data;
int length;
readData(resp, out data, out length);
- return new UntrustedWebResponse(requestUri, resp, new MemoryStream(data, 0, length));
+ return new UntrustedWebResponse(requestUri, finalRequestUri, resp, new MemoryStream(data, 0, length));
}
internal static UntrustedWebResponse Request(Uri uri) {
@@ -283,6 +283,8 @@ namespace DotNetOpenId {
// If SSL is required throughout, we cannot allow auto redirects because
// it may include a pass through an unprotected HTTP request.
// We have to follow redirects manually, and our caller will be responsible for that.
+ // It also allows us to ignore HttpWebResponse.FinalUri since that can be affected by
+ // the Content-Location header and open security holes.
request.AllowAutoRedirect = false;
request.ReadWriteTimeout = (int)ReadWriteTimeout.TotalMilliseconds;
request.Timeout = (int)Timeout.TotalMilliseconds;
@@ -316,7 +318,7 @@ namespace DotNetOpenId {
}
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) {
- return getResponse(originalRequestUri, response);
+ return getResponse(originalRequestUri, request.RequestUri, response);
}
} catch (WebException e) {
using (HttpWebResponse response = (HttpWebResponse)e.Response) {
@@ -326,7 +328,7 @@ namespace DotNetOpenId {
return RequestInternal(uri, body, acceptTypes, requireSsl, true, originalRequestUri, cachePolicy);
}
}
- return getResponse(originalRequestUri, response);
+ return getResponse(originalRequestUri, request.RequestUri, response);
} else {
throw new OpenIdException(string.Format(CultureInfo.CurrentCulture,
Strings.WebRequestFailed, originalRequestUri), e);
diff --git a/src/DotNetOpenId/UntrustedWebResponse.cs b/src/DotNetOpenId/UntrustedWebResponse.cs
index 5214114..0834125 100644
--- a/src/DotNetOpenId/UntrustedWebResponse.cs
+++ b/src/DotNetOpenId/UntrustedWebResponse.cs
@@ -21,18 +21,24 @@ namespace DotNetOpenId {
public Uri RequestUri { get; private set; }
public Uri FinalUri { get; private set; }
- public UntrustedWebResponse(Uri requestUri, HttpWebResponse response, Stream responseStream) {
+ public UntrustedWebResponse(Uri requestUri, Uri finalRequestUri, HttpWebResponse response, Stream responseStream) {
if (requestUri == null) throw new ArgumentNullException("requestUri");
+ if (finalRequestUri == null) throw new ArgumentNullException("finalRequestUri");
if (response == null) throw new ArgumentNullException("response");
if (responseStream == null) throw new ArgumentNullException("responseStream");
this.RequestUri = requestUri;
this.ResponseStream = responseStream;
StatusCode = response.StatusCode;
- if (!string.IsNullOrEmpty(response.ContentType))
- ContentType = new ContentType(response.ContentType);
+ if (!string.IsNullOrEmpty(response.ContentType)) {
+ try {
+ ContentType = new ContentType(response.ContentType);
+ } catch (FormatException) {
+ Logger.ErrorFormat("HTTP response to {0} included an invalid Content-Type header value: {1}", response.ResponseUri.AbsoluteUri, response.ContentType);
+ }
+ }
ContentEncoding = string.IsNullOrEmpty(response.ContentEncoding) ? DefaultContentEncoding : response.ContentEncoding;
Headers = response.Headers;
- FinalUri = response.ResponseUri;
+ FinalUri = finalRequestUri;
}
/// <summary>
@@ -45,8 +51,13 @@ namespace DotNetOpenId {
RequestUri = requestUri;
ResponseStream = responseStream;
StatusCode = statusCode;
- if (!string.IsNullOrEmpty(contentType))
- ContentType = new ContentType(contentType);
+ if (!string.IsNullOrEmpty(contentType)) {
+ try {
+ ContentType = new ContentType(contentType);
+ } catch (FormatException) {
+ Logger.ErrorFormat("HTTP response to {0} included an invalid Content-Type header value: {1}", responseUri.AbsoluteUri, contentType);
+ }
+ }
ContentEncoding = string.IsNullOrEmpty(contentEncoding) ? DefaultContentEncoding : contentEncoding;
Headers = headers;
FinalUri = responseUri;
diff --git a/src/DotNetOpenId/UriIdentifier.cs b/src/DotNetOpenId/UriIdentifier.cs
index 9b1d3e9..821b7db 100644
--- a/src/DotNetOpenId/UriIdentifier.cs
+++ b/src/DotNetOpenId/UriIdentifier.cs
@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Web.UI.HtmlControls;
+using System.Xml;
using DotNetOpenId.RelyingParty;
using DotNetOpenId.Yadis;
@@ -155,7 +156,7 @@ namespace DotNetOpenId {
// rel attributes are supposed to be interpreted with case INsensitivity,
// and is a space-delimited list of values. (http://www.htmlhelp.com/reference/html40/values.html#linktypes)
- var serverLinkTag = Util.FirstOrDefault(linkTags, tag => Regex.IsMatch(tag.Attributes["rel"], @"\b" + Regex.Escape(protocol.HtmlDiscoveryProviderKey) + @"\b", RegexOptions.IgnoreCase));
+ var serverLinkTag = Util.FirstOrDefault(linkTags, tag => tag.Attributes["rel"] != null && Regex.IsMatch(tag.Attributes["rel"], @"\b" + Regex.Escape(protocol.HtmlDiscoveryProviderKey) + @"\b", RegexOptions.IgnoreCase));
if (serverLinkTag == null) {
continue;
}
@@ -164,7 +165,7 @@ namespace DotNetOpenId {
if (Uri.TryCreate(serverLinkTag.Href, UriKind.Absolute, out providerEndpoint)) {
// See if a LocalId tag of the discovered version exists
Identifier providerLocalIdentifier = null;
- var delegateLinkTag = Util.FirstOrDefault(linkTags, tag => Regex.IsMatch(tag.Attributes["rel"], @"\b" + Regex.Escape(protocol.HtmlDiscoveryLocalIdKey) + @"\b", RegexOptions.IgnoreCase));
+ var delegateLinkTag = Util.FirstOrDefault(linkTags, tag => tag.Attributes["rel"] != null && Regex.IsMatch(tag.Attributes["rel"], @"\b" + Regex.Escape(protocol.HtmlDiscoveryLocalIdKey) + @"\b", RegexOptions.IgnoreCase));
if (delegateLinkTag != null) {
if (Identifier.IsValid(delegateLinkTag.Href)) {
providerLocalIdentifier = delegateLinkTag.Href;
@@ -188,13 +189,17 @@ namespace DotNetOpenId {
DiscoveryResult yadisResult = Yadis.Yadis.Discover(this, IsDiscoverySecureEndToEnd);
if (yadisResult != null) {
if (yadisResult.IsXrds) {
- XrdsDocument xrds = new XrdsDocument(yadisResult.ResponseText);
- var xrdsEndpoints = xrds.CreateServiceEndpoints(yadisResult.NormalizedUri);
- // Filter out insecure endpoints if high security is required.
- if (IsDiscoverySecureEndToEnd) {
- xrdsEndpoints = Util.Where(xrdsEndpoints, se => se.IsSecure);
+ try {
+ XrdsDocument xrds = new XrdsDocument(yadisResult.ResponseText);
+ var xrdsEndpoints = xrds.CreateServiceEndpoints(yadisResult.NormalizedUri);
+ // Filter out insecure endpoints if high security is required.
+ if (IsDiscoverySecureEndToEnd) {
+ xrdsEndpoints = Util.Where(xrdsEndpoints, se => se.IsSecure);
+ }
+ endpoints.AddRange(xrdsEndpoints);
+ } catch (XmlException ex) {
+ Logger.Error("Error while parsing the XRDS document. Falling back to HTML discovery.", ex);
}
- endpoints.AddRange(xrdsEndpoints);
}
// Failing YADIS discovery of an XRDS document, we try HTML discovery.
if (endpoints.Count == 0) {
diff --git a/src/DotNetOpenId/Yadis/Yadis.cs b/src/DotNetOpenId/Yadis/Yadis.cs
index c617123..01edf67 100644
--- a/src/DotNetOpenId/Yadis/Yadis.cs
+++ b/src/DotNetOpenId/Yadis/Yadis.cs
@@ -55,7 +55,7 @@ namespace DotNetOpenId.Yadis {
Logger.DebugFormat("{0} found in HTTP header. Preparing to pull XRDS from {1}", HeaderName, url);
}
}
- if (url == null && response.ContentType.MediaType == ContentTypes.Html) {
+ if (url == null && (response.ContentType.MediaType == ContentTypes.Html || response.ContentType.MediaType == ContentTypes.XHtml)) {
url = FindYadisDocumentLocationInHtmlMetaTags(response.ReadResponseString());
if (url != null) {
Logger.DebugFormat("{0} found in HTML Http-Equiv tag. Preparing to pull XRDS from {1}", HeaderName, url);