Merge branch 'master' of github.com:mono/mono
[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 namespace MonoTests.System.ServiceModel.Security
46 {
47         [TestFixture]
48         public class SecurityMessagePropertyTest
49         {
50                 static X509Certificate2 cert = new X509Certificate2 ("Test/Resources/test.pfx", "mono");
51                 static X509Certificate2 cert2 = new X509Certificate2 ("Test/Resources/test2.pfx", "mono");
52
53                 [ServiceContract]
54                 public interface ICalc
55                 {
56                         [OperationContract]
57                         int Sum (int a, int b);
58
59                         [OperationContract (AsyncPattern = true)]
60                         IAsyncResult BeginSum (int a, int b, AsyncCallback cb, object state);
61
62                         int EndSum (IAsyncResult result);
63                 }
64
65                 public class CalcProxy : ClientBase<ICalc>, ICalc
66                 {
67                         public CalcProxy (Binding binding, EndpointAddress address)
68                                 : base (binding, address)
69                         {
70                         }
71
72                         public int Sum (int a, int b)
73                         {
74                                 return Channel.Sum (a, b);
75                         }
76
77                         public IAsyncResult BeginSum (int a, int b, AsyncCallback cb, object state)
78                         {
79                                 return Channel.BeginSum (a, b, cb, state);
80                         }
81
82                         public int EndSum (IAsyncResult result)
83                         {
84                                 return Channel.EndSum (result);
85                         }
86                 }
87
88                 public class CalcService : ICalc
89                 {
90                         public int Sum (int a, int b)
91                         {
92                                 return a + b;
93                         }
94
95                         public IAsyncResult BeginSum (int a, int b, AsyncCallback cb, object state)
96                         {
97                                 return new CalcAsyncResult (a, b, cb, state);
98                         }
99
100                         public int EndSum (IAsyncResult result)
101                         {
102                                 CalcAsyncResult c = (CalcAsyncResult) result;
103                                 return c.A + c.B;
104                         }
105                 }
106
107                 class CalcAsyncResult : IAsyncResult
108                 {
109                         public int A, B;
110                         AsyncCallback callback;
111                         object state;
112
113                         public CalcAsyncResult (int a, int b, AsyncCallback cb, object state)
114                         {
115                                 A = a;
116                                 B = b;
117                                 callback = cb;
118                                 this.state = state;
119                         }
120
121                         public object AsyncState {
122                                 get { return state; }
123                         }
124
125                         public WaitHandle AsyncWaitHandle {
126                                 get { return null; }
127                         }
128
129                         public bool CompletedSynchronously {
130                                 get { return true; }
131                         }
132
133                         public bool IsCompleted {
134                                 get { return true; }
135                         }
136                 }
137
138                 [Test]
139                 public void GetOrCreateNonSecureMessage ()
140                 {
141                         Message m = Message.CreateMessage (MessageVersion.Default, "urn:myaction");
142                         SecurityMessageProperty p =
143                                 SecurityMessageProperty.GetOrCreate (m);
144                         Assert.IsNull (p.InitiatorToken, "#1");
145                         Assert.IsNull (p.RecipientToken, "#2");
146                         Assert.IsNull (p.ProtectionToken, "#3");
147                         Assert.IsNull (p.TransportToken, "#4");
148                         Assert.IsNull (p.ExternalAuthorizationPolicies, "#5");
149 //                      Assert.AreEqual (0, p.ExternalAuthorizationPolicies.Count, "#5");
150                         Assert.IsFalse (p.HasIncomingSupportingTokens, "#6");
151                         Assert.IsNotNull (p.IncomingSupportingTokens, "#6-2");
152                         Assert.AreEqual ("_", p.SenderIdPrefix, "#6-3");
153                         ServiceSecurityContext ssc = p.ServiceSecurityContext;
154                         Assert.IsNotNull (ssc, "#7");
155
156                         // not sure if it is worthy of testing though ...
157                         GenericIdentity identity = ssc.PrimaryIdentity as GenericIdentity;
158                         Assert.IsNotNull (identity, "#8-1");
159                         Assert.AreEqual ("", identity.Name, "#8-2");
160                         Assert.AreEqual ("", identity.AuthenticationType, "#8-3");
161
162                         Assert.AreEqual (0, ssc.AuthorizationPolicies.Count, "#9");
163                         Assert.IsTrue (ssc.IsAnonymous, "#10");
164                 }
165
166                 [Test]
167                 [Category ("NotWorking")]
168                 // not sure how "good" this test is ... if it fails at
169                 // service side, it just results in timeout error.
170                 // The assertion makes sure that it passes all the tests, but
171                 // in case it failed, there is almost no hint ...
172                 public void GetOrCreateSecureMessage ()
173                 {
174                         bool passed = false;
175                         ServiceHost host = new ServiceHost (typeof (CalcService));
176                         InterceptorRequestContextHandler handler = delegate (MessageBuffer src) {
177                                 Message msg = src.CreateMessage ();
178                                 GetOrCreateSecureMessageAtService (msg);
179                                 passed = true;
180                         };
181
182                         try {
183                                 SymmetricSecurityBindingElement clisbe =
184                                         new SymmetricSecurityBindingElement ();
185                                 clisbe.ProtectionTokenParameters =
186                                         new X509SecurityTokenParameters (X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.Never);
187                                 BindingElement transport = new HttpTransportBindingElement ();
188                                 BindingElement sintercept = new InterceptorBindingElement (handler);
189                                 CustomBinding b_res = new CustomBinding (clisbe,
190                                         sintercept,
191                                         transport);
192                                 b_res.ReceiveTimeout = b_res.SendTimeout = TimeSpan.FromSeconds (5);
193                                 host.AddServiceEndpoint (typeof (ICalc), b_res, "http://localhost:37564");
194
195                                 ServiceCredentials cred = new ServiceCredentials ();
196                                 cred.ServiceCertificate.Certificate = cert;
197                                 cred.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
198                                 host.Description.Behaviors.Add (cred);
199
200                                 host.Open ();
201
202                                 ProcessClient ();
203
204                         } finally {
205                                 if (host.State == CommunicationState.Opened)
206                                         host.Close ();
207                         }
208                         if (!passed)
209                                 Assert.Fail ("Didn't pass the interceptor.");
210                 }
211
212                 void ProcessClient ()
213                 {
214                         SymmetricSecurityBindingElement svcsbe =
215                                 new SymmetricSecurityBindingElement ();
216                         svcsbe.ProtectionTokenParameters =
217                                 new X509SecurityTokenParameters (X509KeyIdentifierClauseType.Thumbprint, SecurityTokenInclusionMode.Never);
218
219                         BindingElement cintercept = new InterceptorBindingElement (null);
220                         CustomBinding b_req = new CustomBinding (svcsbe,
221                                 cintercept,
222                                 new HttpTransportBindingElement ());
223
224                         b_req.ReceiveTimeout = b_req.SendTimeout = TimeSpan.FromSeconds (5);
225                         EndpointAddress remaddr = new EndpointAddress (
226                                 new Uri ("http://localhost:37564"),
227                                 new X509CertificateEndpointIdentity (cert));
228                         CalcProxy proxy = new CalcProxy (b_req, remaddr);
229                         proxy.ClientCredentials.ClientCertificate.Certificate = cert2;
230
231                         proxy.Sum (1, 2);
232                         proxy.Close ();
233                 }
234
235                 static void GetOrCreateSecureMessageAtClient (Message msg)
236                 {
237                         foreach (object o in msg.Properties)
238                                 if (o is SecurityMessageProperty)
239                                         Assert.Fail ("The input msg should not contain SecurityMessageProperty yet.");
240                         SecurityMessageProperty p = SecurityMessageProperty.GetOrCreate (msg);
241
242                         Assert.AreEqual (null, p.InitiatorToken, "#1");
243                         Assert.AreEqual (null, p.RecipientToken, "#2");
244                         Assert.IsNull (p.ProtectionToken, "#3");
245                         Assert.IsNull (p.TransportToken, "#4");
246                         Assert.IsNull (p.ExternalAuthorizationPolicies, "#5");
247 //                      Assert.AreEqual (0, p.ExternalAuthorizationPolicies.Count, "#5");
248                         Assert.IsFalse (p.HasIncomingSupportingTokens, "#6");
249                         Assert.IsNotNull (p.IncomingSupportingTokens, "#6-2");
250                         Assert.AreEqual ("_", p.SenderIdPrefix, "#6-3");
251                         ServiceSecurityContext ssc = p.ServiceSecurityContext;
252                         Assert.IsNotNull (ssc, "#7");
253
254                         // not sure if it is worthy of testing though ...
255                         GenericIdentity identity = ssc.PrimaryIdentity as GenericIdentity;
256                         Assert.IsNotNull (identity, "#8-1");
257                         Assert.AreEqual ("", identity.Name, "#8-2");
258                         Assert.AreEqual ("", identity.AuthenticationType, "#8-3");
259
260                         Assert.AreEqual (0, ssc.AuthorizationPolicies.Count, "#9");
261                         Assert.IsTrue (ssc.IsAnonymous, "#10");
262                 }
263
264                 static void GetOrCreateSecureMessageAtService (Message msg)
265                 {
266                         Assert.IsNull (msg.Properties.Security, "#0");
267                         foreach (object o in msg.Properties)
268                                 if (o is SecurityMessageProperty)
269                                         Assert.Fail ("The input msg should not contain SecurityMessageProperty yet.");
270                         SecurityMessageProperty p = SecurityMessageProperty.GetOrCreate (msg);
271                         Assert.IsNotNull (msg.Properties.Security, "#0-2");
272
273                         Assert.AreEqual (null, p.InitiatorToken, "#1");
274                         Assert.AreEqual (null, p.RecipientToken, "#2");
275                         Assert.IsNull (p.ProtectionToken, "#3");
276                         Assert.IsNull (p.TransportToken, "#4");
277                         Assert.IsNull (p.ExternalAuthorizationPolicies, "#5");
278 //                      Assert.AreEqual (0, p.ExternalAuthorizationPolicies.Count, "#5");
279                         Assert.IsFalse (p.HasIncomingSupportingTokens, "#6");
280                         Assert.IsNotNull (p.IncomingSupportingTokens, "#6-2");
281                         Assert.AreEqual ("_", p.SenderIdPrefix, "#6-3");
282                         ServiceSecurityContext ssc = p.ServiceSecurityContext;
283                         Assert.IsNotNull (ssc, "#7");
284
285                         // not sure if it is worthy of testing though ...
286                         GenericIdentity identity = ssc.PrimaryIdentity as GenericIdentity;
287                         Assert.IsNotNull (identity, "#8-1");
288                         Assert.AreEqual ("", identity.Name, "#8-2");
289                         Assert.AreEqual ("", identity.AuthenticationType, "#8-3");
290
291                         Assert.AreEqual (0, ssc.AuthorizationPolicies.Count, "#9");
292                         Assert.IsTrue (ssc.IsAnonymous, "#10");
293                 }
294         }
295 }