2009-12-03 Marek Safar <marek.safar@gmail.com>
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Channels / SecurityBindingElement.cs
1 //
2 // SecurityBindingElement.cs
3 //
4 // Author:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //
7 // Copyright (C) 2005-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.Collections.Generic;
29 using System.Collections.ObjectModel;
30 using System.ServiceModel.Description;
31 using System.ServiceModel.Channels;
32 using System.ServiceModel.Security;
33 #if !NET_2_1
34 using System.IdentityModel.Selectors;
35 using System.IdentityModel.Tokens;
36 using System.ServiceModel.Security.Tokens;
37 #endif
38
39 namespace System.ServiceModel.Channels
40 {
41         public abstract class SecurityBindingElement : BindingElement
42         {
43                 internal SecurityBindingElement ()
44                 {
45 #if !NET_2_1
46                         DefaultAlgorithmSuite = SecurityAlgorithmSuite.Default;
47                         MessageSecurityVersion = MessageSecurityVersion.Default;
48                         KeyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy;
49                         endpoint = new SupportingTokenParameters ();
50                         operation = new Dictionary<string,SupportingTokenParameters> ();
51                         opt_endpoint = new SupportingTokenParameters ();
52                         opt_operation = new Dictionary<string,SupportingTokenParameters> ();
53                         service_settings = new LocalServiceSecuritySettings ();
54 #endif
55                         IncludeTimestamp = true;
56                         LocalClientSettings = new LocalClientSecuritySettings ();
57                 }
58
59                 internal SecurityBindingElement (SecurityBindingElement other)
60                 {
61 #if !NET_2_1
62                         alg_suite = other.alg_suite;
63                         key_entropy_mode = other.key_entropy_mode;
64                         security_header_layout = other.security_header_layout;
65                         msg_security_version = other.msg_security_version;
66                         endpoint = other.endpoint.Clone ();
67                         opt_endpoint = other.opt_endpoint.Clone ();
68                         operation = new Dictionary<string,SupportingTokenParameters> ();
69                         foreach (KeyValuePair<string,SupportingTokenParameters> p in other.operation)
70                                 operation.Add (p.Key, p.Value.Clone ());
71                         opt_operation = new Dictionary<string,SupportingTokenParameters> ();
72                         foreach (KeyValuePair<string,SupportingTokenParameters> p in other.opt_operation)
73                                 opt_operation.Add (p.Key, p.Value.Clone ());
74                         service_settings = other.service_settings.Clone ();
75 #endif
76                         IncludeTimestamp = other.IncludeTimestamp;
77                         LocalClientSettings = other.LocalClientSettings.Clone ();
78                 }
79
80 #if !NET_2_1
81                 SecurityAlgorithmSuite alg_suite;
82                 SecurityKeyEntropyMode key_entropy_mode;
83                 SecurityHeaderLayout security_header_layout;
84                 MessageSecurityVersion msg_security_version;
85                 SupportingTokenParameters endpoint, opt_endpoint;
86                 IDictionary<string,SupportingTokenParameters> operation, opt_operation;
87                 LocalServiceSecuritySettings service_settings;
88 #endif
89
90                 public bool IncludeTimestamp { get; set; }
91
92                 public LocalClientSecuritySettings LocalClientSettings { get; private set; }
93
94 #if !NET_2_1
95                 public SecurityAlgorithmSuite DefaultAlgorithmSuite {
96                         get { return alg_suite; }
97                         set { alg_suite = value; }
98                 }
99
100                 public SecurityKeyEntropyMode KeyEntropyMode {
101                         get { return key_entropy_mode; }
102                         set { key_entropy_mode = value; }
103                 }
104
105                 public LocalServiceSecuritySettings LocalServiceSettings {
106                         get { return service_settings; }
107                 }
108
109                 public SecurityHeaderLayout SecurityHeaderLayout {
110                         get { return security_header_layout; }
111                         set { security_header_layout = value; }
112                 }
113
114                 public MessageSecurityVersion MessageSecurityVersion {
115                         get { return msg_security_version; }
116                         set { msg_security_version = value; }
117                 }
118
119                 public SupportingTokenParameters EndpointSupportingTokenParameters {
120                         get { return endpoint; }
121                 }
122
123                 public IDictionary<string,SupportingTokenParameters> OperationSupportingTokenParameters {
124                         get { return operation; }
125                 }
126
127                 public SupportingTokenParameters OptionalEndpointSupportingTokenParameters {
128                         get { return opt_endpoint; }
129                 }
130
131                 public IDictionary<string,SupportingTokenParameters> OptionalOperationSupportingTokenParameters {
132                         get { return opt_operation; }
133                 }
134 #endif
135
136                 [MonoTODO ("It supports only IRequestSessionChannel")]
137                 public override bool CanBuildChannelFactory<TChannel> (BindingContext context)
138                 {
139                         return context.CanBuildInnerChannelFactory<TChannel> ();
140                 }
141
142                 public override IChannelFactory<TChannel> BuildChannelFactory<TChannel> (
143                         BindingContext context)
144                 {
145                         return BuildChannelFactoryCore<TChannel> (context);
146                 }
147
148                 protected abstract IChannelFactory<TChannel>
149                         BuildChannelFactoryCore<TChannel> (BindingContext context);
150
151 #if !NET_2_1
152                 [MonoTODO ("It probably supports only IReplySessionChannel")]
153                 public override bool CanBuildChannelListener<TChannel> (BindingContext context)
154                 {
155                         return context.CanBuildInnerChannelListener<TChannel> ();
156                 }
157
158                 public override IChannelListener<TChannel> BuildChannelListener<TChannel> (
159                         BindingContext context)
160                 {
161                         return BuildChannelListenerCore<TChannel> (context);
162                 }
163
164                 protected abstract IChannelListener<TChannel> 
165                         BuildChannelListenerCore<TChannel> (BindingContext context)
166                         where TChannel : class, IChannel;
167
168                 public virtual void SetKeyDerivation (bool requireDerivedKeys)
169                 {
170                         endpoint.SetKeyDerivation (requireDerivedKeys);
171                         opt_endpoint.SetKeyDerivation (requireDerivedKeys);
172                         foreach (SupportingTokenParameters p in operation.Values)
173                                 p.SetKeyDerivation (requireDerivedKeys);
174                         foreach (SupportingTokenParameters p in opt_operation.Values)
175                                 p.SetKeyDerivation (requireDerivedKeys);
176                 }
177
178                 [MonoTODO]
179                 public override string ToString ()
180                 {
181                         return base.ToString ();
182                 }
183 #else
184                 [MonoTODO]
185                 public override T GetProperty<T> (BindingContext context)
186                 {
187                         return null;
188                 }
189 #endif
190
191                 #region Factory methods
192 #if !NET_2_1
193                 public static SymmetricSecurityBindingElement 
194                         CreateAnonymousForCertificateBindingElement ()
195                 {
196                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
197                         be.RequireSignatureConfirmation = true;
198                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (true);
199                         return be;
200                 }
201
202                 public static TransportSecurityBindingElement 
203                         CreateCertificateOverTransportBindingElement ()
204                 {
205                         return CreateCertificateOverTransportBindingElement (MessageSecurityVersion.Default);
206                 }
207
208                 [MonoTODO]
209                 public static TransportSecurityBindingElement 
210                         CreateCertificateOverTransportBindingElement (MessageSecurityVersion version)
211                 {
212                         var be = new TransportSecurityBindingElement () { MessageSecurityVersion = version };
213                         be.EndpointSupportingTokenParameters.SignedEncrypted.Add (new X509SecurityTokenParameters ());
214                         return be;
215                 }
216
217                 [MonoTODO]
218                 public static AsymmetricSecurityBindingElement 
219                         CreateCertificateSignatureBindingElement  ()
220                 {
221                         throw new NotImplementedException ();
222                 }
223
224                 [MonoTODO]
225                 public static SymmetricSecurityBindingElement 
226                         CreateIssuedTokenBindingElement  (
227                         IssuedSecurityTokenParameters issuedTokenParameters)
228                 {
229                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
230                         be.ProtectionTokenParameters = issuedTokenParameters;
231                         return be;
232                 }
233
234                 public static SymmetricSecurityBindingElement
235                         CreateIssuedTokenForCertificateBindingElement (
236                         IssuedSecurityTokenParameters issuedTokenParameters)
237                 {
238                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
239                         be.RequireSignatureConfirmation = true;
240                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (true);
241                         be.EndpointSupportingTokenParameters.Endorsing.Add (
242                                 issuedTokenParameters);
243                         return be;
244                 }
245
246                 [MonoTODO]
247                 public static SymmetricSecurityBindingElement 
248                         CreateIssuedTokenForSslBindingElement (
249                         IssuedSecurityTokenParameters issuedTokenParameters)
250                 {
251                         return CreateIssuedTokenForSslBindingElement (
252                                 issuedTokenParameters, false);
253                 }
254
255                 [MonoTODO]
256                 public static SymmetricSecurityBindingElement 
257                         CreateIssuedTokenForSslBindingElement (
258                         IssuedSecurityTokenParameters issuedTokenParameters,
259                         bool requireCancellation)
260                 {
261                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
262                         be.RequireSignatureConfirmation = true;
263                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
264                         be.EndpointSupportingTokenParameters.Endorsing.Add (
265                                 issuedTokenParameters);
266                         return be;
267                 }
268
269                 [MonoTODO]
270                 public static TransportSecurityBindingElement 
271                         CreateIssuedTokenOverTransportBindingElement (
272                         IssuedSecurityTokenParameters issuedTokenParameters)
273                 {
274                         throw new NotImplementedException ();
275                 }
276
277                 [MonoTODO]
278                 public static SymmetricSecurityBindingElement CreateKerberosBindingElement ()
279                 {
280                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
281                         be.DefaultAlgorithmSuite = SecurityAlgorithmSuite.Basic128;
282                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
283                         be.ProtectionTokenParameters.InclusionMode =
284                                 SecurityTokenInclusionMode.Once;
285                         return be;
286                 }
287
288                 [MonoTODO]
289                 public static TransportSecurityBindingElement 
290                         CreateKerberosOverTransportBindingElement ()
291                 {
292                         throw new NotImplementedException ();
293                 }
294
295                 [MonoTODO]
296                 public static SecurityBindingElement 
297                         CreateMutualCertificateBindingElement ()
298                 {
299                         throw new NotImplementedException ();
300                 }
301
302                 [MonoTODO]
303                 public static SecurityBindingElement 
304                         CreateMutualCertificateBindingElement (MessageSecurityVersion version)
305                 {
306                         throw new NotImplementedException ();
307                 }
308
309                 [MonoTODO]
310                 public static SecurityBindingElement 
311                         CreateMutualCertificateBindingElement (
312                         MessageSecurityVersion version,
313                         bool allowSerializedSigningTokenOnReply)
314                 {
315                         throw new NotImplementedException ();
316                 }
317
318                 [MonoTODO]
319                 public static AsymmetricSecurityBindingElement 
320                         CreateMutualCertificateDuplexBindingElement ()
321                 {
322                         throw new NotImplementedException ();
323                 }
324
325                 [MonoTODO]
326                 public static AsymmetricSecurityBindingElement 
327                         CreateMutualCertificateDuplexBindingElement (
328                         MessageSecurityVersion version)
329                 {
330                         throw new NotImplementedException ();
331                 }
332
333                 public static SecurityBindingElement 
334                         CreateSecureConversationBindingElement (SecurityBindingElement binding)
335                 {
336                         return CreateSecureConversationBindingElement (binding, false);
337                 }
338
339                 public static SecurityBindingElement 
340                         CreateSecureConversationBindingElement (
341                         SecurityBindingElement binding, bool requireCancellation)
342                 {
343                         return CreateSecureConversationBindingElement (binding, requireCancellation, null);
344                 }
345
346                 [MonoTODO]
347                 public static SecurityBindingElement 
348                         CreateSecureConversationBindingElement (
349                         SecurityBindingElement binding, bool requireCancellation,
350                         ChannelProtectionRequirements protectionRequirements)
351                 {
352                         SymmetricSecurityBindingElement be =
353                                 new SymmetricSecurityBindingElement ();
354                         be.ProtectionTokenParameters =
355                                 new SecureConversationSecurityTokenParameters (
356                                         binding, requireCancellation, protectionRequirements);
357                         return be;
358                 }
359
360                 [MonoTODO]
361                 public static SymmetricSecurityBindingElement 
362                         CreateSslNegotiationBindingElement (bool requireClientCertificate)
363                 {
364                         return CreateSslNegotiationBindingElement (
365                                 requireClientCertificate, false);
366                 }
367
368                 [MonoTODO]
369                 public static SymmetricSecurityBindingElement 
370                         CreateSslNegotiationBindingElement (
371                         bool requireClientCertificate,
372                         bool requireCancellation)
373                 {
374                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
375                         be.ProtectionTokenParameters = new SslSecurityTokenParameters (requireClientCertificate, requireCancellation);
376                         return be;
377                 }
378
379                 [MonoTODO]
380                 public static SymmetricSecurityBindingElement 
381                         CreateSspiNegotiationBindingElement ()
382                 {
383                         return CreateSspiNegotiationBindingElement (true);
384                 }
385
386                 [MonoTODO]
387                 public static SymmetricSecurityBindingElement 
388                         CreateSspiNegotiationBindingElement (bool requireCancellation)
389                 {
390                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
391                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
392                         return be;
393                 }
394
395                 public static TransportSecurityBindingElement 
396                         CreateSspiNegotiationOverTransportBindingElement ()
397                 {
398                         return CreateSspiNegotiationOverTransportBindingElement (false);
399                 }
400
401                 [MonoTODO]
402                 public static TransportSecurityBindingElement 
403                         CreateSspiNegotiationOverTransportBindingElement (bool requireCancellation)
404                 {
405                         throw new NotImplementedException ();
406                 }
407
408                 static X509SecurityTokenParameters CreateProtectionTokenParameters (bool cert)
409                 {
410                         X509SecurityTokenParameters p =
411                                 new X509SecurityTokenParameters ();
412                         p.X509ReferenceStyle = X509KeyIdentifierClauseType.Thumbprint;
413                         if (cert)
414                                 p.InclusionMode = SecurityTokenInclusionMode.Never;
415                         return p;
416                 }
417
418                 [MonoTODO]
419                 public static SymmetricSecurityBindingElement 
420                         CreateUserNameForCertificateBindingElement ()
421                 {
422                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
423                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (true);
424                         UserNameSecurityTokenParameters utp =
425                                 new UserNameSecurityTokenParameters ();
426                         be.EndpointSupportingTokenParameters.SignedEncrypted.Add (utp);
427                         return be;
428                 }
429
430                 [MonoTODO]
431                 public static SymmetricSecurityBindingElement 
432                         CreateUserNameForSslBindingElement ()
433                 {
434                         return CreateUserNameForSslBindingElement (false);
435                 }
436
437                 [MonoTODO]
438                 public static SymmetricSecurityBindingElement 
439                         CreateUserNameForSslBindingElement (bool requireCancellation)
440                 {
441                         SymmetricSecurityBindingElement be = new SymmetricSecurityBindingElement ();
442                         be.ProtectionTokenParameters = CreateProtectionTokenParameters (false);
443                         UserNameSecurityTokenParameters utp =
444                                 new UserNameSecurityTokenParameters ();
445                         be.EndpointSupportingTokenParameters.SignedEncrypted.Add (utp);
446                         return be;
447                 }
448 #endif
449
450                 [MonoTODO]
451                 public static TransportSecurityBindingElement 
452                         CreateUserNameOverTransportBindingElement ()
453                 {
454                         var be = new TransportSecurityBindingElement ();
455 #if !NET_2_1 // FIXME: there should be whatever else to do for 2.1 instead.
456                         be.EndpointSupportingTokenParameters.SignedEncrypted.Add (new UserNameSecurityTokenParameters ());
457 #endif
458                         return be;
459                 }
460                 #endregion
461
462 #if !NET_2_1
463                 // It seems almost internal, hardcoded like this (I tried
464                 // custom parameters that sets IssuedTokenSecurityTokenParameters
465                 // like below ones, but that didn't trigger this method).
466                 protected static void SetIssuerBindingContextIfRequired (
467                         SecurityTokenParameters parameters,
468                         BindingContext issuerBindingContext)
469                 {
470                         if (parameters is IssuedSecurityTokenParameters ||
471                             parameters is SecureConversationSecurityTokenParameters ||
472                             parameters is SslSecurityTokenParameters ||
473                             parameters is SspiSecurityTokenParameters) {
474                                 parameters.IssuerBindingContext = issuerBindingContext;
475                         }
476                 }
477 #endif
478         }
479 }