summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2008-09-13 09:55:52 -0700
committerAndrew <andrewarnott@gmail.com>2008-09-13 09:55:52 -0700
commit61650a6ec207c94cb92e27227dac75606c3e7e00 (patch)
tree94211306924328968711f101bc1234a417fc62ea /src
parentae2258f38effe0eca177d3610a9a113288f6365b (diff)
downloadDotNetOpenAuth-61650a6ec207c94cb92e27227dac75606c3e7e00.zip
DotNetOpenAuth-61650a6ec207c94cb92e27227dac75606c3e7e00.tar.gz
DotNetOpenAuth-61650a6ec207c94cb92e27227dac75606c3e7e00.tar.bz2
Added a few ProtocolException-derived exception types.
Diffstat (limited to 'src')
-rw-r--r--src/DotNetOAuth.Test/Messaging/ChannelTests.cs6
-rw-r--r--src/DotNetOAuth/DotNetOAuth.csproj3
-rw-r--r--src/DotNetOAuth/Messaging/Channel.cs9
-rw-r--r--src/DotNetOAuth/Messaging/ExpiredMessageException.cs36
-rw-r--r--src/DotNetOAuth/Messaging/InvalidSignatureException.cs34
-rw-r--r--src/DotNetOAuth/Messaging/ProtocolException.cs29
-rw-r--r--src/DotNetOAuth/Messaging/ReplayedMessageException.cs34
7 files changed, 141 insertions, 10 deletions
diff --git a/src/DotNetOAuth.Test/Messaging/ChannelTests.cs b/src/DotNetOAuth.Test/Messaging/ChannelTests.cs
index 4627b87..ca80dba 100644
--- a/src/DotNetOAuth.Test/Messaging/ChannelTests.cs
+++ b/src/DotNetOAuth.Test/Messaging/ChannelTests.cs
@@ -271,7 +271,7 @@ namespace DotNetOAuth.Test.Messaging {
this.ParameterizedReceiveTest("GET");
}
- [TestMethod, ExpectedException(typeof(ProtocolException))]
+ [TestMethod, ExpectedException(typeof(InvalidSignatureException))]
public void ReceivedInvalidSignature() {
this.channel = new TestSigningChannel(false, false);
this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, true);
@@ -284,7 +284,7 @@ namespace DotNetOAuth.Test.Messaging {
this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false);
}
- [TestMethod, ExpectedException(typeof(ProtocolException))]
+ [TestMethod, ExpectedException(typeof(ExpiredMessageException))]
public void VerifyBadTimestampIsRejected() {
// Create a channel that supports and recognizes signed messages.
this.channel = new TestSigningChannel(true, false);
@@ -297,7 +297,7 @@ namespace DotNetOAuth.Test.Messaging {
this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false);
}
- [TestMethod, ExpectedException(typeof(ProtocolException))]
+ [TestMethod, ExpectedException(typeof(ReplayedMessageException))]
public void ReceivedReplayProtectedMessageTwice() {
this.channel = new TestReplayProtectedChannel();
this.ParameterizedReceiveProtectedTest(DateTime.UtcNow, false);
diff --git a/src/DotNetOAuth/DotNetOAuth.csproj b/src/DotNetOAuth/DotNetOAuth.csproj
index 41587db..fb41be1 100644
--- a/src/DotNetOAuth/DotNetOAuth.csproj
+++ b/src/DotNetOAuth/DotNetOAuth.csproj
@@ -68,7 +68,10 @@
<ItemGroup>
<Compile Include="Consumer.cs" />
<Compile Include="IWebRequestHandler.cs" />
+ <Compile Include="Messaging\ReplayedMessageException.cs" />
+ <Compile Include="Messaging\ExpiredMessageException.cs" />
<Compile Include="Messaging\DataContractMemberComparer.cs" />
+ <Compile Include="Messaging\InvalidSignatureException.cs" />
<Compile Include="Messaging\IReplayProtectedProtocolMessage.cs" />
<Compile Include="Messaging\IExpiringProtocolMessage.cs" />
<Compile Include="Messaging\DictionaryXmlReader.cs" />
diff --git a/src/DotNetOAuth/Messaging/Channel.cs b/src/DotNetOAuth/Messaging/Channel.cs
index f26a9eb..4d644c9 100644
--- a/src/DotNetOAuth/Messaging/Channel.cs
+++ b/src/DotNetOAuth/Messaging/Channel.cs
@@ -503,7 +503,7 @@ namespace DotNetOAuth.Messaging {
if (!this.IsSignatureValid(signedMessage)) {
// TODO: add inResponseTo and remoteReceiver where applicable
- throw new ProtocolException(MessagingStrings.SignatureInvalid);
+ throw new InvalidSignatureException(signedMessage);
}
}
@@ -519,10 +519,7 @@ namespace DotNetOAuth.Messaging {
// but just in case a given message failed to guarantee that, we do it here.
DateTime expirationDate = expiringMessage.UtcCreationDate.ToUniversalTime() + this.MaximumMessageAge;
if (expirationDate < DateTime.UtcNow) {
- throw new ProtocolException(string.Format(
- MessagingStrings.ExpiredMessage,
- expirationDate,
- DateTime.UtcNow));
+ throw new ExpiredMessageException(expirationDate, expiringMessage);
}
}
@@ -535,7 +532,7 @@ namespace DotNetOAuth.Messaging {
Debug.Assert(message != null, "message == null");
if (this.IsMessageReplayed(message)) {
- throw new ProtocolException(MessagingStrings.ReplayAttackDetected);
+ throw new ReplayedMessageException(message);
}
}
}
diff --git a/src/DotNetOAuth/Messaging/ExpiredMessageException.cs b/src/DotNetOAuth/Messaging/ExpiredMessageException.cs
new file mode 100644
index 0000000..3d4ded3
--- /dev/null
+++ b/src/DotNetOAuth/Messaging/ExpiredMessageException.cs
@@ -0,0 +1,36 @@
+//-----------------------------------------------------------------------
+// <copyright file="ExpiredMessageException.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.Messaging {
+ using System;
+
+ /// <summary>
+ /// An exception thrown when a message is received that exceeds the maximum message age limit.
+ /// </summary>
+ [Serializable]
+ internal class ExpiredMessageException : ProtocolException {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExpiredMessageException"/> class.
+ /// </summary>
+ /// <param name="utcExpirationDate">The date the message expired.</param>
+ /// <param name="faultedMessage">The expired message.</param>
+ public ExpiredMessageException(DateTime utcExpirationDate, IExpiringProtocolMessage faultedMessage)
+ : base(string.Format(MessagingStrings.ExpiredMessage, utcExpirationDate.ToUniversalTime(), DateTime.UtcNow), faultedMessage) {
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ExpiredMessageException"/> class.
+ /// </summary>
+ /// <param name="info">The <see cref="System.Runtime.Serialization.SerializationInfo"/>
+ /// that holds the serialized object data about the exception being thrown.</param>
+ /// <param name="context">The System.Runtime.Serialization.StreamingContext
+ /// that contains contextual information about the source or destination.</param>
+ protected ExpiredMessageException(
+ System.Runtime.Serialization.SerializationInfo info,
+ System.Runtime.Serialization.StreamingContext context)
+ : base(info, context) { }
+ }
+}
diff --git a/src/DotNetOAuth/Messaging/InvalidSignatureException.cs b/src/DotNetOAuth/Messaging/InvalidSignatureException.cs
new file mode 100644
index 0000000..1b66a3d
--- /dev/null
+++ b/src/DotNetOAuth/Messaging/InvalidSignatureException.cs
@@ -0,0 +1,34 @@
+//-----------------------------------------------------------------------
+// <copyright file="InvalidSignatureException.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.Messaging {
+ using System;
+
+ /// <summary>
+ /// An exception thrown when a signed message does not pass signature validation.
+ /// </summary>
+ [Serializable]
+ internal class InvalidSignatureException : ProtocolException {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="InvalidSignatureException"/> class.
+ /// </summary>
+ /// <param name="faultedMessage">The message with the invalid signature.</param>
+ public InvalidSignatureException(ISignedProtocolMessage faultedMessage)
+ : base(MessagingStrings.SignatureInvalid, faultedMessage) { }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="InvalidSignatureException"/> class.
+ /// </summary>
+ /// <param name="info">The <see cref="System.Runtime.Serialization.SerializationInfo"/>
+ /// that holds the serialized object data about the exception being thrown.</param>
+ /// <param name="context">The System.Runtime.Serialization.StreamingContext
+ /// that contains contextual information about the source or destination.</param>
+ protected InvalidSignatureException(
+ System.Runtime.Serialization.SerializationInfo info,
+ System.Runtime.Serialization.StreamingContext context)
+ : base(info, context) { }
+ }
+}
diff --git a/src/DotNetOAuth/Messaging/ProtocolException.cs b/src/DotNetOAuth/Messaging/ProtocolException.cs
index 6101073..d7c3675 100644
--- a/src/DotNetOAuth/Messaging/ProtocolException.cs
+++ b/src/DotNetOAuth/Messaging/ProtocolException.cs
@@ -45,6 +45,20 @@ namespace DotNetOAuth.Messaging {
/// such that it can be sent as a protocol message response to a remote caller.
/// </summary>
/// <param name="message">The human-readable exception message.</param>
+ /// <param name="faultedMessage">The message that was the cause of the exception. May not be null.</param>
+ internal ProtocolException(string message, IProtocolMessage faultedMessage) : base(message) {
+ if (faultedMessage == null) {
+ throw new ArgumentNullException("faultedMessage");
+ }
+
+ this.FaultedMessage = faultedMessage;
+ }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ProtocolException"/> class
+ /// such that it can be sent as a protocol message response to a remote caller.
+ /// </summary>
+ /// <param name="message">The human-readable exception message.</param>
/// <param name="inResponseTo">
/// If <paramref name="message"/> is a response to an incoming message, this is the incoming message.
/// This is useful for error scenarios in deciding just how to send the response message.
@@ -61,6 +75,7 @@ namespace DotNetOAuth.Messaging {
throw new ArgumentNullException("inResponseTo");
}
this.inResponseTo = inResponseTo;
+ this.FaultedMessage = inResponseTo;
if (remoteIndirectReceiver == null && inResponseTo.Transport != MessageTransport.Direct) {
// throw an exception, with ourselves as the inner exception (as fully initialized as we can be).
@@ -100,7 +115,7 @@ namespace DotNetOAuth.Messaging {
#endregion
- #region IProtocolMessage Members
+ #region IProtocolMessage Properties
/// <summary>
/// Gets the version of the protocol this message is prepared to implement.
@@ -126,6 +141,18 @@ namespace DotNetOAuth.Messaging {
}
}
+ #endregion
+
+ /// <summary>
+ /// Gets the message that caused the exception.
+ /// </summary>
+ internal IProtocolMessage FaultedMessage {
+ get;
+ private set;
+ }
+
+ #region IProtocolMessage Methods
+
/// <summary>
/// See <see cref="IProtocolMessage.EnsureValidMessage"/>.
/// </summary>
diff --git a/src/DotNetOAuth/Messaging/ReplayedMessageException.cs b/src/DotNetOAuth/Messaging/ReplayedMessageException.cs
new file mode 100644
index 0000000..1df0a4b
--- /dev/null
+++ b/src/DotNetOAuth/Messaging/ReplayedMessageException.cs
@@ -0,0 +1,34 @@
+//-----------------------------------------------------------------------
+// <copyright file="ReplayedMessageException.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOAuth.Messaging {
+ using System;
+
+ /// <summary>
+ /// An exception thrown when a message is received for the second time, signalling a possible
+ /// replay attack.
+ /// </summary>
+ [Serializable]
+ internal class ReplayedMessageException : ProtocolException {
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ReplayedMessageException"/> class.
+ /// </summary>
+ /// <param name="faultedMessage">The replayed message.</param>
+ public ReplayedMessageException(IReplayProtectedProtocolMessage faultedMessage) : base(MessagingStrings.ReplayAttackDetected, faultedMessage) { }
+
+ /// <summary>
+ /// Initializes a new instance of the <see cref="ReplayedMessageException"/> class.
+ /// </summary>
+ /// <param name="info">The <see cref="System.Runtime.Serialization.SerializationInfo"/>
+ /// that holds the serialized object data about the exception being thrown.</param>
+ /// <param name="context">The System.Runtime.Serialization.StreamingContext
+ /// that contains contextual information about the source or destination.</param>
+ protected ReplayedMessageException(
+ System.Runtime.Serialization.SerializationInfo info,
+ System.Runtime.Serialization.StreamingContext context)
+ : base(info, context) { }
+ }
+}