Selaa lähdekoodia

2009-12-03 Atsushi Enomoto <[email protected]>

	* HttpsTransportBindingElement.cs :
	  RequireClientCertificate is false by default.
	  Remove extra #if NET_2_1.
	* SecurityBindingElement.cs :
	  Implement some transport security factory methods.
	* TransportSecurityBindingElement.cs :
	  It is not ISecurityCapabilities anymore.

	* BasicHttpBinding.cs : handle transport security properties.

	* BasicHttpBindingTest.cs : added transport security related tests.


svn path=/trunk/mcs/; revision=147532
Atsushi Eno 16 vuotta sitten
vanhempi
sitoutus
0532f0a556

+ 10 - 0
mcs/class/System.ServiceModel/System.ServiceModel.Channels/ChangeLog

@@ -1,3 +1,13 @@
+2009-12-03  Atsushi Enomoto  <[email protected]>
+
+	* HttpsTransportBindingElement.cs :
+	  RequireClientCertificate is false by default.
+	  Remove extra #if NET_2_1.
+	* SecurityBindingElement.cs :
+	  Implement some transport security factory methods.
+	* TransportSecurityBindingElement.cs :
+	  It is not ISecurityCapabilities anymore.
+
 2009-11-25  Atsushi Enomoto  <[email protected]>
 
 	* MessageHeaders.cs

+ 1 - 5
mcs/class/System.ServiceModel/System.ServiceModel.Channels/HttpsTransportBindingElement.cs

@@ -40,7 +40,7 @@ namespace System.ServiceModel.Channels
 		: HttpTransportBindingElement, ITransportTokenAssertionProvider,
 		IPolicyExportExtension, IWsdlExportExtension
 	{
-		bool req_cli_cert = true;
+		bool req_cli_cert = false;
 
 		public HttpsTransportBindingElement ()
 		{
@@ -50,11 +50,7 @@ namespace System.ServiceModel.Channels
 			HttpsTransportBindingElement other)
 			: base (other)
 		{
-#if NET_2_1
 			req_cli_cert = other.req_cli_cert;
-#else
-			throw new NotImplementedException ();
-#endif
 		}
 
 		public bool RequireClientCertificate {

+ 6 - 2
mcs/class/System.ServiceModel/System.ServiceModel.Channels/SecurityBindingElement.cs

@@ -209,7 +209,9 @@ namespace System.ServiceModel.Channels
 		public static TransportSecurityBindingElement 
 			CreateCertificateOverTransportBindingElement (MessageSecurityVersion version)
 		{
-			throw new NotImplementedException ();
+			var be = new TransportSecurityBindingElement () { MessageSecurityVersion = version };
+			be.EndpointSupportingTokenParameters.SignedEncrypted.Add (new X509SecurityTokenParameters ());
+			return be;
 		}
 
 		[MonoTODO]
@@ -449,7 +451,9 @@ namespace System.ServiceModel.Channels
 		public static TransportSecurityBindingElement 
 			CreateUserNameOverTransportBindingElement ()
 		{
-			throw new NotImplementedException ();
+			var be = new TransportSecurityBindingElement ();
+			be.EndpointSupportingTokenParameters.SignedEncrypted.Add (new UserNameSecurityTokenParameters ());
+			return be;
 		}
 		#endregion
 

+ 1 - 31
mcs/class/System.ServiceModel/System.ServiceModel.Channels/TransportSecurityBindingElement.cs

@@ -39,8 +39,7 @@ namespace System.ServiceModel.Channels
 #if NET_2_1
 		: SecurityBindingElement
 #else
-		: SecurityBindingElement,
-		  ISecurityCapabilities, IPolicyExportExtension
+		: SecurityBindingElement, IPolicyExportExtension
 #endif
 	{
 		public TransportSecurityBindingElement ()
@@ -51,10 +50,8 @@ namespace System.ServiceModel.Channels
 			TransportSecurityBindingElement other)
 			: base (other)
 		{
-			throw new NotImplementedException ();
 		}
 
-		[MonoTODO]
 		public override BindingElement Clone ()
 		{
 			return new TransportSecurityBindingElement (this);
@@ -83,32 +80,6 @@ namespace System.ServiceModel.Channels
 			throw new NotImplementedException ();
 		}
 
-		#region explicit interface implementations
-		[MonoTODO]
-		ProtectionLevel ISecurityCapabilities.SupportedRequestProtectionLevel {
-			get { throw new NotImplementedException (); }
-		}
-
-		[MonoTODO]
-		ProtectionLevel ISecurityCapabilities.SupportedResponseProtectionLevel {
-			get { throw new NotImplementedException (); }
-		}
-
-		[MonoTODO]
-		bool ISecurityCapabilities.SupportsClientAuthentication {
-			get { throw new NotImplementedException (); }
-		}
-
-		[MonoTODO]
-		bool ISecurityCapabilities.SupportsClientWindowsIdentity {
-			get { throw new NotImplementedException (); }
-		}
-
-		[MonoTODO]
-		bool ISecurityCapabilities.SupportsServerAuthentication {
-			get { throw new NotImplementedException (); }
-		}
-
 		[MonoTODO]
 		void IPolicyExportExtension.ExportPolicy (
 			MetadataExporter exporter,
@@ -116,7 +87,6 @@ namespace System.ServiceModel.Channels
 		{
 			throw new NotImplementedException ();
 		}
-		#endregion
 #endif
 	}
 }

+ 54 - 21
mcs/class/System.ServiceModel/System.ServiceModel/BasicHttpBinding.cs

@@ -27,6 +27,7 @@
 //
 using System;
 using System.Collections.Generic;
+using System.Net;
 using System.Net.Security;
 using System.ServiceModel.Channels;
 using System.ServiceModel.Description;
@@ -178,14 +179,17 @@ namespace System.ServiceModel
 			switch (Security.Mode) {
 #if !NET_2_1
 			case BasicHttpSecurityMode.Message:
-			case BasicHttpSecurityMode.TransportWithMessageCredential:
 				if (Security.Message.ClientCredentialType != BasicHttpMessageCredentialType.Certificate)
 					throw new InvalidOperationException ("When Message security is enabled in a BasicHttpBinding, the message security credential type must be BasicHttpMessageCredentialType.Certificate.");
-				return new BindingElementCollection (new BindingElement [] {
+				goto case BasicHttpSecurityMode.TransportWithMessageCredential;
+			case BasicHttpSecurityMode.TransportWithMessageCredential:
+				SecurityBindingElement sec;
+				if (Security.Message.ClientCredentialType != BasicHttpMessageCredentialType.Certificate)
 					// FIXME: pass proper security token parameters.
-					new AsymmetricSecurityBindingElement (),
-					BuildMessageEncodingBindingElement (),
-					GetTransport ()});
+					sec = SecurityBindingElement.CreateCertificateOverTransportBindingElement ();
+				else
+					sec = new AsymmetricSecurityBindingElement ();
+				return new BindingElementCollection (new BindingElement [] {sec, BuildMessageEncodingBindingElement (), GetTransport ()});
 #endif
 			default:
 				return new BindingElementCollection (new BindingElement [] {
@@ -216,30 +220,59 @@ namespace System.ServiceModel
 
 		TransportBindingElement GetTransport ()
 		{
-			HttpTransportBindingElement transportBindingElement;
+			HttpTransportBindingElement h;
 			switch (Security.Mode) {
 			case BasicHttpSecurityMode.Transport:
 			case BasicHttpSecurityMode.TransportWithMessageCredential:
-				transportBindingElement
-					= new HttpsTransportBindingElement ();
+				h = new HttpsTransportBindingElement ();
 				break;
 			default:
-				transportBindingElement
-					= new HttpTransportBindingElement ();
+				h = new HttpTransportBindingElement ();
 				break;
 			}
 
-			transportBindingElement.AllowCookies = AllowCookies;
-			transportBindingElement.BypassProxyOnLocal = BypassProxyOnLocal;
-			transportBindingElement.HostNameComparisonMode = HostNameComparisonMode;
-			transportBindingElement.MaxBufferPoolSize = MaxBufferPoolSize;
-			transportBindingElement.MaxBufferSize = MaxBufferSize;
-			transportBindingElement.MaxReceivedMessageSize = MaxReceivedMessageSize;
-			transportBindingElement.ProxyAddress = ProxyAddress;
-			transportBindingElement.UseDefaultWebProxy = UseDefaultWebProxy;
-			transportBindingElement.TransferMode = TransferMode;
-
-			return transportBindingElement;
+			h.AllowCookies = AllowCookies;
+			h.BypassProxyOnLocal = BypassProxyOnLocal;
+			h.HostNameComparisonMode = HostNameComparisonMode;
+			h.MaxBufferPoolSize = MaxBufferPoolSize;
+			h.MaxBufferSize = MaxBufferSize;
+			h.MaxReceivedMessageSize = MaxReceivedMessageSize;
+			h.ProxyAddress = ProxyAddress;
+			h.UseDefaultWebProxy = UseDefaultWebProxy;
+			h.TransferMode = TransferMode;
+
+#if !NET_2_1
+			switch (Security.Mode) {
+			case BasicHttpSecurityMode.Transport:
+				switch (Security.Transport.ClientCredentialType) {
+				case HttpClientCredentialType.Certificate:
+					var https = (HttpsTransportBindingElement) h;
+					https.RequireClientCertificate = true;
+					break;
+				}
+				break;
+			case BasicHttpSecurityMode.TransportCredentialOnly:
+				switch (Security.Transport.ClientCredentialType) {
+				case HttpClientCredentialType.Basic:
+					h.AuthenticationScheme = AuthenticationSchemes.Basic;
+					break;
+				case HttpClientCredentialType.Ntlm:
+					h.AuthenticationScheme = AuthenticationSchemes.Ntlm;
+					break;
+				case HttpClientCredentialType.Windows:
+					h.AuthenticationScheme = AuthenticationSchemes.Negotiate;
+					break;
+				case HttpClientCredentialType.Digest:
+					h.AuthenticationScheme = AuthenticationSchemes.Digest;
+					break;
+				case HttpClientCredentialType.Certificate:
+					throw new InvalidOperationException ("Certificate-based client authentication is not supported by 'TransportCredentialOnly' mode.");
+				}
+				break;
+			}
+#endif
+
+			return h;
 		}
 
 		// explicit interface implementations

+ 4 - 0
mcs/class/System.ServiceModel/System.ServiceModel/ChangeLog

@@ -1,3 +1,7 @@
+2009-12-03  Atsushi Enomoto  <[email protected]>
+
+	* BasicHttpBinding.cs : handle transport security properties.
+
 2009-12-02  Sebastien Pouliot  <[email protected]>
 
 	* CommunicationObjectAbortedException.cs, ServerTooBusyException.cs,

+ 66 - 0
mcs/class/System.ServiceModel/Test/System.ServiceModel/BasicHttpBindingTest.cs

@@ -27,6 +27,7 @@
 //
 using System;
 using System.Collections.ObjectModel;
+using System.Net;
 using System.Net.Security;
 using System.ServiceModel;
 using System.ServiceModel.Channels;
@@ -248,6 +249,71 @@ namespace MonoTests.System.ServiceModel
 			Assert.AreEqual (false, t.UseDefaultWebProxy, "#16");
 		}
 
+		[Test]
+		public void SecurityMode ()
+		{
+			// hmm, against my expectation, those modes does not give Http(s)TransportBindingElement property differences..
+			var modes = new HttpClientCredentialType [] {HttpClientCredentialType.None, HttpClientCredentialType.Basic, HttpClientCredentialType.Digest, HttpClientCredentialType.Ntlm, HttpClientCredentialType.Windows, HttpClientCredentialType.Certificate};
+			foreach (var m in modes) {
+				var b = new BasicHttpBinding ();
+				b.Security.Mode = BasicHttpSecurityMode.Transport;
+				b.Security.Transport.ClientCredentialType = m;
+				var bec = b.CreateBindingElements ();
+				Assert.AreEqual (2, bec.Count, "#1." + m);
+				Assert.IsTrue (bec [1] is HttpsTransportBindingElement, "#2." + m);
+				var tbe = (HttpsTransportBindingElement) bec [1];
+				if (m == HttpClientCredentialType.Certificate)
+					Assert.IsTrue (tbe.RequireClientCertificate, "#3." + m);
+				else
+					Assert.IsFalse (tbe.RequireClientCertificate, "#3." + m);
+			}
+		}
+
+		[Test]
+		public void SecurityMode2 ()
+		{
+			var modes = new HttpClientCredentialType [] {HttpClientCredentialType.None, HttpClientCredentialType.Basic, HttpClientCredentialType.Digest, HttpClientCredentialType.Ntlm, HttpClientCredentialType.Windows, HttpClientCredentialType.Certificate};
+			foreach (var m in modes) {
+				var b = new BasicHttpBinding ();
+				b.Security.Mode = BasicHttpSecurityMode.TransportWithMessageCredential; // gives WS-Security message security.
+				b.Security.Transport.ClientCredentialType = m;
+				var bec = b.CreateBindingElements ();
+				Assert.AreEqual (3, bec.Count, "#1." + m);
+				Assert.IsTrue (bec [0] is TransportSecurityBindingElement, "#2." + m);
+				Assert.IsTrue (bec [2] is HttpsTransportBindingElement, "#3." + m);
+				var tbe = (HttpsTransportBindingElement) bec [2];
+				Assert.IsFalse (tbe.RequireClientCertificate, "#4." + m);
+			}
+		}
+
+		[Test]
+		public void SecurityMode3 ()
+		{
+			var modes = new HttpClientCredentialType [] {HttpClientCredentialType.None, HttpClientCredentialType.Basic, HttpClientCredentialType.Digest, HttpClientCredentialType.Ntlm, HttpClientCredentialType.Windows};
+			var auths = new AuthenticationSchemes [] { AuthenticationSchemes.Anonymous, AuthenticationSchemes.Basic, AuthenticationSchemes.Digest, AuthenticationSchemes.Ntlm, AuthenticationSchemes.Negotiate }; // specifically, none->anonymous, and windows->negotiate
+			for (int i = 0; i < modes.Length; i++) {
+				var m = modes [i];
+				var b = new BasicHttpBinding ();
+				b.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; // gives WS-Security message security.
+				b.Security.Transport.ClientCredentialType = m;
+				var bec = b.CreateBindingElements ();
+				Assert.AreEqual (2, bec.Count, "#1." + m);
+				Assert.IsTrue (bec [1] is HttpTransportBindingElement, "#2." + m);
+				var tbe = (HttpTransportBindingElement) bec [1];
+				Assert.AreEqual (auths [i], tbe.AuthenticationScheme, "#3." + m);
+			}
+		}
+
+		[Test]
+		[ExpectedException (typeof (InvalidOperationException))]
+		public void SecurityMode4 ()
+		{
+			var b = new BasicHttpBinding ();
+			b.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly; // gives WS-Security message security.
+			b.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
+			var bec = b.CreateBindingElements ();
+		}
+
 		private BasicHttpBinding CreateBindingFromConfig ()
 		{
 			ServiceModelSectionGroup config = (ServiceModelSectionGroup) ConfigurationManager.OpenExeConfiguration ("Test/config/basicHttpBinding").GetSectionGroup ("system.serviceModel");

+ 4 - 0
mcs/class/System.ServiceModel/Test/System.ServiceModel/ChangeLog

@@ -1,3 +1,7 @@
+2009-12-03  Atsushi Enomoto  <[email protected]>
+
+	* BasicHttpBindingTest.cs : added transport security related tests.
+
 2009-12-02  Atsushi Enomoto  <[email protected]>
 
 	* NetTcpBindingTest.cs :