Merge pull request #1804 from esdrubal/processmodule
[mono.git] / mcs / class / System.ServiceModel / Test / System.ServiceModel.Security / SecurityMessagePropertyTest.cs
1 //
2 // SecurityMessagePropertyTest.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2006 Novell, Inc.  http://www.novell.com
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28 using System;
29 using System.Collections.ObjectModel;
30 using System.Net;
31 using System.Net.Security;
32 using System.Security.Principal;
33 using System.Security.Cryptography.X509Certificates;
34 using System.ServiceModel;
35 using System.ServiceModel.Channels;
36 using System.ServiceModel.Description;
37 using System.ServiceModel.Security;
38 using System.ServiceModel.Security.Tokens;
39 using System.Security.Cryptography.Xml;
40 using System.Threading;
41 using NUnit.Framework;
42
43 using MonoTests.System.ServiceModel.Channels;
44
45 using MonoTests.Helpers;
46
47 namespace MonoTests.System.ServiceModel.Security
48 {
49         [TestFixture]
50         public class SecurityMessagePropertyTest
51         {
52                 static X509Certificate2 cert = new X509Certificate2 ("Test/Resources/test.pfx", "mono");
53                 static X509Certificate2 cert2 = new X509Certificate2 ("Test/Resources/test2.pfx", "mono");
54
55                 [ServiceContract]
56                 public interface ICalc
57                 {
58                         [OperationContract]
59                         int Sum (int a, int b);
60
61                         [OperationContract (AsyncPattern = true)]
62                         IAsyncResult BeginSum (int a, int b, AsyncCallback cb, object state);
63
64                         int EndSum (IAsyncResult result);
65                 }
66
67                 public class CalcProxy : ClientBase<ICalc>, ICalc
68                 {
69                         public CalcProxy (Binding binding, EndpointAddress address)
70                                 : base (binding, address)
71                         {
72                         }
73
74                         public int Sum (int a, int b)
75                         {
76                                 return Channel.Sum (a, b);
77                         }
78
79                         public IAsyncResult BeginSum (int a, int b, AsyncCallback cb, object state)
80                         {
81                                 return Channel.BeginSum (a, b, cb, state);
82                         }
83
84                         public int EndSum (IAsyncResult result)
85                         {
86                                 return Channel.EndSum (result);
87                         }
88                 }
89
90                 public class CalcService : ICalc
91                 {
92                         public int Sum (int a, int b)
93                         {
94                                 return a + b;
95                         }
96
97                         public IAsyncResult BeginSum (int a, int b, AsyncCallback cb, object state)
98                         {
99                                 return new CalcAsyncResult (a, b, cb, state);
100                         }
101
102                         public int EndSum (IAsyncResult result)
103                         {
104                                 CalcAsyncResult c = (CalcAsyncResult) result;
105                                 return c.A + c.B;
106                         }
107                 }
108
109                 class CalcAsyncResult : IAsyncResult
110                 {
111                         public int A, B;
112                         AsyncCallback callback;
113                         object state;
114
115                         public CalcAsyncResult (int a, int b, AsyncCallback cb, object state)
116                         {
117                                 A = a;
118                                 B = b;
119                                 callback = cb;
120                                 this.state = state;
121                         }
122
123                         public object AsyncState {
124                                 get { return state; }
125                         }
126
127                         public WaitHandle AsyncWaitHandle {
128                                 get { return null; }
129                         }
130
131                         public bool CompletedSynchronously {
132                                 get { return true; }
133                         }
134
135                         public bool IsCompleted {
136                                 get { return true; }
137                         }
138                 }
139
140                 [Test]
141                 public void GetOrCreateNonSecureMessage ()
142                 {
143                         Message m = Message.CreateMessage (MessageVersion.Default, "urn:myaction");
144                         SecurityMessageProperty p =
145                                 SecurityMessageProperty.GetOrCreate (m);
146                         Assert.IsNull (p.InitiatorToken, "#1");
147                         Assert.IsNull (p.RecipientToken, "#2");
148                         Assert.IsNull (p.ProtectionToken, "#3");
149                         Assert.IsNull (p.TransportToken, "#4");
150                         Assert.IsNull (p.ExternalAuthorizationPolicies, "#5");
151 //                      Assert.AreEqual (0, p.ExternalAuthorizationPolicies.Count, "#5");
152                         Assert.IsFalse (p.HasIncomingSupportingTokens, "#6");
153                         Assert.IsNotNull (p.IncomingSupportingTokens, "#6-2");
154                         Assert.AreEqual ("_", p.SenderIdPrefix, "#6-3");
155                         ServiceSecurityContext ssc = p.ServiceSecurityContext;
156                         Assert.IsNotNull (ssc, "#7");
157
158                         // not sure if it is worthy of testing though ...
159                         GenericIdentity identity = ssc.PrimaryIdentity as GenericIdentity;
160                         Assert.IsNotNull (identity, "#8-1");
161                         Assert.AreEqual ("", identity.Name, "#8-2");
162                         Assert.AreEqual ("", identity.AuthenticationType, "#8-3");
163
164                         Assert.AreEqual (0, ssc.AuthorizationPolicies.Count, "#9");
165                         Assert.IsTrue (ssc.IsAnonymous, "#10");
166                 }
167
168                 [Test]
169                 [Ignore ("This hangs on .NET")]
170                 // not sure how "good" this test is ... if it fails at
171                 // service side, it just results in timeout error.
172                 // The assertion makes sure that it passes all the tests, but
173                 // in case it failed, there is almost no hint ...
174                 public void GetOrCreateSecureMessage ()
175                 {
176                         bool passed = false;
177                         ServiceHost host = new ServiceHost (typeof (CalcService));
178                         InterceptorRequestContextHandler handler = delegate (MessageBuffer src) {
179                                 Message msg = src.CreateMessage ();
180                                 GetOrCreateSecureMessageAtService (msg);
181                                 passed = true;
182                         };
183
184                         try {
185                                 SymmetricSecurityBindingElement clisbe =
186                                         new SymmetricSecurityBindingElement ();
187                                 clisbe.ProtectionTokenParameters =
188                                         new X509SecurityTokenParameters (X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.Never);
189                                 BindingElement transport = new HttpTransportBindingElement ();
190                                 BindingElement sintercept = new InterceptorBindingElement (handler);
191                                 CustomBinding b_res = new CustomBinding (clisbe,
192                                         sintercept,
193                                         transport);
194                                 b_res.ReceiveTimeout = b_res.SendTimeout = TimeSpan.FromSeconds (5);
195                                 host.AddServiceEndpoint (typeof (ICalc), b_res, "http://localhost:" + NetworkHelpers.FindFreePort ());
196
197                                 ServiceCredentials cred = new ServiceCredentials ();
198                                 cred.ServiceCertificate.Certificate = cert;
199                                 cred.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
200                                 host.Description.Behaviors.Add (cred);
201
202                                 host.Open ();
203
204                                 ProcessClient ();
205
206                         } finally {
207                                 if (host.State == CommunicationState.Opened)
208                                         host.Close ();
209                         }
210                         if (!passed)
211                                 Assert.Fail ("Didn't pass the interceptor.");
212                 }
213
214                 void ProcessClient ()
215                 {
216                         SymmetricSecurityBindingElement svcsbe =
217                                 new SymmetricSecurityBindingElement ();
218                         svcsbe.ProtectionTokenParameters =
219                                 new X509SecurityTokenParameters (X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.Never);
220
221                         BindingElement cintercept = new InterceptorBindingElement (null);
222                         CustomBinding b_req = new CustomBinding (svcsbe,
223                                 cintercept,
224                                 new HttpTransportBindingElement ());
225
226                         b_req.ReceiveTimeout = b_req.SendTimeout = TimeSpan.FromSeconds (5);
227                         EndpointAddress remaddr = new EndpointAddress (
228                                 new Uri ("http://localhost:" + NetworkHelpers.FindFreePort ()),
229                                 new X509CertificateEndpointIdentity (cert));
230                         CalcProxy proxy = new CalcProxy (b_req, remaddr);
231                         proxy.ClientCredentials.ClientCertificate.Certificate = cert2;
232
233                         proxy.Sum (1, 2);
234                         proxy.Close ();
235                 }
236
237                 static void GetOrCreateSecureMessageAtClient (Message msg)
238                 {
239                         foreach (object o in msg.Properties)
240                                 if (o is SecurityMessageProperty)
241                                         Assert.Fail ("The input msg should not contain SecurityMessageProperty yet.");
242                         SecurityMessageProperty p = SecurityMessageProperty.GetOrCreate (msg);
243
244                         Assert.AreEqual (null, p.InitiatorToken, "#1");
245                         Assert.AreEqual (null, p.RecipientToken, "#2");
246                         Assert.IsNull (p.ProtectionToken, "#3");
247                         Assert.IsNull (p.TransportToken, "#4");
248                         Assert.IsNull (p.ExternalAuthorizationPolicies, "#5");
249 //                      Assert.AreEqual (0, p.ExternalAuthorizationPolicies.Count, "#5");
250                         Assert.IsFalse (p.HasIncomingSupportingTokens, "#6");
251                         Assert.IsNotNull (p.IncomingSupportingTokens, "#6-2");
252                         Assert.AreEqual ("_", p.SenderIdPrefix, "#6-3");
253                         ServiceSecurityContext ssc = p.ServiceSecurityContext;
254                         Assert.IsNotNull (ssc, "#7");
255
256                         // not sure if it is worthy of testing though ...
257                         GenericIdentity identity = ssc.PrimaryIdentity as GenericIdentity;
258                         Assert.IsNotNull (identity, "#8-1");
259                         Assert.AreEqual ("", identity.Name, "#8-2");
260                         Assert.AreEqual ("", identity.AuthenticationType, "#8-3");
261
262                         Assert.AreEqual (0, ssc.AuthorizationPolicies.Count, "#9");
263                         Assert.IsTrue (ssc.IsAnonymous, "#10");
264                 }
265
266                 static void GetOrCreateSecureMessageAtService (Message msg)
267                 {
268                         Assert.IsNull (msg.Properties.Security, "#0");
269                         foreach (object o in msg.Properties)
270                                 if (o is SecurityMessageProperty)
271                                         Assert.Fail ("The input msg should not contain SecurityMessageProperty yet.");
272                         SecurityMessageProperty p = SecurityMessageProperty.GetOrCreate (msg);
273                         Assert.IsNotNull (msg.Properties.Security, "#0-2");
274
275                         Assert.AreEqual (null, p.InitiatorToken, "#1");
276                         Assert.AreEqual (null, p.RecipientToken, "#2");
277                         Assert.IsNull (p.ProtectionToken, "#3");
278                         Assert.IsNull (p.TransportToken, "#4");
279                         Assert.IsNull (p.ExternalAuthorizationPolicies, "#5");
280 //                      Assert.AreEqual (0, p.ExternalAuthorizationPolicies.Count, "#5");
281                         Assert.IsFalse (p.HasIncomingSupportingTokens, "#6");
282                         Assert.IsNotNull (p.IncomingSupportingTokens, "#6-2");
283                         Assert.AreEqual ("_", p.SenderIdPrefix, "#6-3");
284                         ServiceSecurityContext ssc = p.ServiceSecurityContext;
285                         Assert.IsNotNull (ssc, "#7");
286
287                         // not sure if it is worthy of testing though ...
288                         GenericIdentity identity = ssc.PrimaryIdentity as GenericIdentity;
289                         Assert.IsNotNull (identity, "#8-1");
290                         Assert.AreEqual ("", identity.Name, "#8-2");
291                         Assert.AreEqual ("", identity.AuthenticationType, "#8-3");
292
293                         Assert.AreEqual (0, ssc.AuthorizationPolicies.Count, "#9");
294                         Assert.IsTrue (ssc.IsAnonymous, "#10");
295                 }
296         }
297 }