public void TestGetDigest()
        {
            Request request = new Request();
            
            List<CustomProperty> props = new List<CustomProperty>();

            props.Add(new CustomProperty("Subject", "This is a subject"));
            
            RoutingEntity sourceRouting = new RoutingEntity();

            RoutingItem item = new RoutingItem();
            item.Content = "*****@*****.**";
            
            sourceRouting.Items = new RoutingItem[] {item};
            request.Source = sourceRouting;
            request.Properties = props.ToArray();

            string digest1 = new RequestDigestProvider().GetDigest(request);
            //change the request, get a different digest value.

            request.Source.Items[0].Content = "*****@*****.**";
            string digest2 = new RequestDigestProvider().GetDigest(request);
            Assert.AreNotEqual(digest1,digest2);

            request.Properties[0].Value = "Change the subject";
            string digest3 = new RequestDigestProvider().GetDigest(request);
            Assert.AreNotEqual(digest1,digest2);
            Assert.AreNotEqual(digest2, digest3);

            //Empty subject is OK
            request.Properties[0].Value = string.Empty;

            string digest4 = new RequestDigestProvider().GetDigest(request);
            Assert.AreNotEqual(digest1,digest4);
        }
        public void GetDigestRoutingItemIsCaseInsensitive()
        {
            Request request = new Request();

            List<CustomProperty> props = new List<CustomProperty>();

            props.Add(new CustomProperty("Subject", "This is a subject"));

            RoutingEntity sourceRouting = new RoutingEntity();

            RoutingItem item = new RoutingItem();
            item.Content = "*****@*****.**";
            sourceRouting.Items = new RoutingItem[] { item };
            request.Source = sourceRouting;
            request.Properties = props.ToArray();

            string digest1 = new RequestDigestProvider().GetDigest(request);

            request.Source.Items[0].Content = request.Source.Items[0].Content.ToUpperInvariant();

            string digest2 = new RequestDigestProvider().GetDigest(request);

            Assert.AreEqual(digest1,digest2);
        }
        public void GetDigestMissingSource()
        {
            Request request = new Request();

            List<CustomProperty> props = new List<CustomProperty>();

            props.Add(new CustomProperty("Subject", "This is a subject"));
            request.Properties = props.ToArray();

            request.Source = null; //Invalid, this should cause the throw

            try
            {
                string digest = new RequestDigestProvider().GetDigest(request);
            }
            catch (ArgumentException)
            {
                Assert.IsTrue(true, "Expecting method to throw this ArgumentException");
                return;
            }

            Assert.Fail("Should have thrown the ArgumentException");
        }
        public void GetDigestMissingSubjectProperty()
        {
            Request request = new Request();

            request.Properties = new CustomProperty[0];//Invalid, this should cause the throw

            RoutingEntity sourceRouting = new RoutingEntity();
            sourceRouting.RoutingType = "Source";

            RoutingItem item = new RoutingItem();
            item.Content = "*****@*****.**";
            sourceRouting.Items = new RoutingItem[] { item };
            request.Source = sourceRouting;

            try
            {
                string digest = new RequestDigestProvider().GetDigest(request);
            }
            catch (ArgumentException)
            {
                Assert.IsTrue(true, "Expecting method to throw this ArgumentException");
                return;
            }

            Assert.Fail("Should have thrown the ArgumentException");
        }
        public void GetDigestEmptyRoutingItem()
        {
            Request request = new Request();

            List<CustomProperty> props = new List<CustomProperty>();

            props.Add(new CustomProperty("Subject", "This is a subject"));
            request.Properties = props.ToArray();

            RoutingEntity sourceRouting = new RoutingEntity();

            RoutingItem item = new RoutingItem();
            item.Content = string.Empty;  //Invalid, this should cause the throw
            sourceRouting.Items = new RoutingItem[] { item };
            request.Source = sourceRouting;
            request.Properties = props.ToArray();

            try
            {
                string digest = new RequestDigestProvider().GetDigest(request);
            }
            catch (ArgumentException)
            {
                Assert.IsTrue(true, "Expecting method to throw this ArgumentException");
                return;
            }

            Assert.Fail("Should have thrown the ArgumentException");
        }
예제 #6
0
		/// <summary>
		/// This method checks a certain property is present in the FileHeaders property, and that the value matches
		/// a hash of some request-specific properties.
		/// </summary>
		/// <param name="request"></param>
		/// <returns></returns>
		/// <remarks>
		/// Only expect this to be true for messages that were processed by Protect on the client, and then picked up at another 
		/// egress point such as the MTA or Network monitor.  
		/// Only messages processed by protect client will have the prerequisite fileheader property.
		///</remarks>
		private static bool VerifyRequest(Request request)
		{
			try
			{
				if (request == null || request.Properties == null)
				{
					return false;
				}
				CustomProperty fileHeaderProperty = Array.Find(request.Properties,
					cp => cp.Name.Equals("FileHeader", StringComparison.InvariantCultureIgnoreCase));
				if (fileHeaderProperty == null || string.IsNullOrEmpty(fileHeaderProperty.Value))
				{
					return false;
				}

				HeaderParser parser = new HeaderParser(fileHeaderProperty.Value);
				string actualValue = parser.GetHeaderValue(RequestDigestProvider.XHEADER_MESSAGE_PROTECTED);
				if (string.IsNullOrEmpty(actualValue))
				{
					return false;
				}
				actualValue = actualValue.Trim();

				string expectedHashValue = new RequestDigestProvider().GetDigest(request);
				if (!actualValue.Equals(expectedHashValue, StringComparison.InvariantCultureIgnoreCase))
				{
					Logger.LogInfo("A request failed hash validation.  It will be processed by all policies. FileHeader contents: " + fileHeaderProperty.Value);
					return false;
				}

				Logger.LogInfo("Request passed hash validation, therefore it was sent via a Protect-compatible email client.");
				return true;
			}
			catch (Exception e)
			{
				//Some requests passed in here will currently pass unexpected arguments, namely the NetworkMonitor.
				//NetMon code is currently passing an unexpected number of routing items. 

				//In all cases where unexpected arguments are passed or any other problem is encountered, 
				//treat this as failure to verify the message, therefore returning false.
				Logger.LogError("A request failed hash validation due to an exception.  It will be processed by all policies.");
				Logger.LogError(e);
				return false;
			}
		}