aec08d49c876bac9913899defa0d20b0bf9ab206
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel.Configuration / ConfigUtil.cs
1 //
2 // ConfigUtil.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.Configuration;
30 using System.Collections.Generic;
31 using System.Security.Cryptography.X509Certificates;
32 using System.ServiceModel.Channels;
33 using System.ServiceModel.Configuration;
34 using System.ServiceModel.Description;
35 using System.ServiceModel.Dispatcher;
36 using System.Web.Configuration;
37
38 namespace System.ServiceModel.Configuration
39 {
40         internal static class ConfigUtil
41         {
42                 static object GetSection (string name)
43                 {
44                         if (ServiceHostingEnvironment.InAspNet)
45                                 return WebConfigurationManager.GetSection (name);
46                         else
47                                 return ConfigurationManager.GetSection (name);
48                 }
49
50                 public static BindingsSection BindingsSection {
51                         get {
52                                 return (BindingsSection) GetSection ("system.serviceModel/bindings");
53                         }
54                 }
55
56                 public static ClientSection ClientSection {
57                         get { return (ClientSection) GetSection ("system.serviceModel/client"); }
58                 }
59
60                 public static ServicesSection ServicesSection {
61                         get { return (ServicesSection) GetSection ("system.serviceModel/services"); }
62                 }
63
64                 public static BehaviorsSection BehaviorsSection {
65                         get { return (BehaviorsSection) GetSection ("system.serviceModel/behaviors"); }
66                 }
67
68                 public static ExtensionsSection ExtensionsSection {
69                         get { return (ExtensionsSection) GetSection ("system.serviceModel/extensions"); }
70                 }
71
72 #if NET_4_0
73                 public static ProtocolMappingSection ProtocolMappingSection {
74                         get {
75                                 return (ProtocolMappingSection) GetSection ("system.serviceModel/protocolMapping");
76                         }
77                 }
78
79                 public static StandardEndpointsSection StandardEndpointsSection {
80                         get {
81                                 return (StandardEndpointsSection) GetSection ("system.serviceModel/standardEndpoints");
82                         }
83                 }
84 #endif
85
86                 public static Binding CreateBinding (string binding, string bindingConfiguration)
87                 {
88                         BindingCollectionElement section = ConfigUtil.BindingsSection [binding];
89                         if (section == null)
90                                 throw new ArgumentException (String.Format ("binding section for {0} was not found.", binding));
91
92                         Binding b = section.GetDefault ();
93
94                         foreach (IBindingConfigurationElement el in section.ConfiguredBindings)
95                                 if (el.Name == bindingConfiguration)
96                                         el.ApplyConfiguration (b);
97
98                         return b;
99                 }
100
101 #if NET_4_0
102                 public static Binding GetBindingByProtocolMapping (Uri address)
103                 {
104                         ProtocolMappingElement el = ConfigUtil.ProtocolMappingSection.ProtocolMappingCollection [address.Scheme];
105                         if (el == null)
106                                 return null;
107                         return ConfigUtil.CreateBinding (el.Binding, el.BindingConfiguration);
108                 }
109
110                 public static ServiceEndpoint ConfigureStandardEndpoint (ContractDescription cd, ChannelEndpointElement element)
111                 {
112                         string kind = element.Kind;
113                         string endpointConfiguration = element.EndpointConfiguration;
114
115                         EndpointCollectionElement section = ConfigUtil.StandardEndpointsSection [kind];
116                         if (section == null)
117                                 throw new ArgumentException (String.Format ("standard endpoint section for '{0}' was not found.", kind));
118
119                         StandardEndpointElement e = section.GetDefaultStandardEndpointElement ();
120
121                         ServiceEndpoint inst = e.CreateServiceEndpoint (cd);
122
123                         foreach (StandardEndpointElement el in section.ConfiguredEndpoints) {
124                                 if (el.Name == endpointConfiguration) {
125                                         el.InitializeAndValidate (element);
126                                         el.ApplyConfiguration (inst, element);
127                                         break;
128                                 }
129                         }
130                         
131                         return inst;
132                 }
133
134                 public static Type GetTypeFromConfigString (string name)
135                 {
136                         Type type = Type.GetType (name);
137                         if (type != null)
138                                 return type;
139                         foreach (var ass in AppDomain.CurrentDomain.GetAssemblies ())
140                                 if ((type = ass.GetType (name)) != null)
141                                         return type;
142                         return null;
143                 }
144
145                 public static ServiceEndpoint ConfigureStandardEndpoint (ContractDescription cd, ServiceEndpointElement element)
146                 {
147                         string kind = element.Kind;
148                         string endpointConfiguration = element.EndpointConfiguration;
149
150                         EndpointCollectionElement section = ConfigUtil.StandardEndpointsSection [kind];
151                         if (section == null)
152                                 throw new ArgumentException (String.Format ("standard endpoint section for '{0}' was not found.", kind));
153
154                         StandardEndpointElement e = section.GetDefaultStandardEndpointElement ();
155
156                         ServiceEndpoint inst = e.CreateServiceEndpoint (cd);
157
158                         foreach (StandardEndpointElement el in section.ConfiguredEndpoints) {
159                                 if (el.Name == endpointConfiguration) {
160                                         el.InitializeAndValidate (element);
161                                         el.ApplyConfiguration (inst, element);
162                                         break;
163                                 }
164                         }
165                         
166                         return inst;
167                 }
168 #endif
169
170                 public static KeyedByTypeCollection<IEndpointBehavior>  CreateEndpointBehaviors (string bindingConfiguration)
171                 {
172                         var ec = BehaviorsSection.EndpointBehaviors [bindingConfiguration];
173                         if (ec == null)
174                                 return null;
175                         var c = new KeyedByTypeCollection<IEndpointBehavior> ();
176                         foreach (var bxe in ec)
177                                 c.Add ((IEndpointBehavior) bxe.CreateBehavior ());
178                         return c;
179                 }
180
181                 public static EndpointAddress CreateInstance (this EndpointAddressElementBase el)
182                 {
183                         return new EndpointAddress (el.Address, el.Identity.CreateInstance (), el.Headers.Headers);
184                 }
185
186                 public static void CopyFrom (this ChannelEndpointElement to, ChannelEndpointElement from)
187                 {
188                         to.Address = from.Address;
189                         to.BehaviorConfiguration = from.BehaviorConfiguration;
190                         to.Binding = from.Binding;
191                         to.BindingConfiguration = from.BindingConfiguration;
192                         to.Contract = from.Contract;
193                         if (from.Headers != null)
194                                 to.Headers.Headers = from.Headers.Headers;
195                         if (from.Identity != null)
196                                 to.Identity.InitializeFrom (from.Identity.CreateInstance ());
197                         to.Name = from.Name;
198                 }
199
200                 public static EndpointAddress CreateEndpointAddress (this ChannelEndpointElement el)
201                 {
202                         return new EndpointAddress (el.Address, el.Identity != null ? el.Identity.CreateInstance () : null, el.Headers.Headers);
203                 }
204
205                 public static EndpointAddress CreateEndpointAddress (this ServiceEndpointElement el)
206                 {
207                         return new EndpointAddress (el.Address, el.Identity != null ? el.Identity.CreateInstance () : null, el.Headers.Headers);
208                 }
209
210                 public static EndpointIdentity CreateInstance (this IdentityElement el)
211                 {
212                         if (el.Certificate != null)
213                                 return new X509CertificateEndpointIdentity (el.Certificate.CreateInstance ());
214                         else if (el.CertificateReference != null)
215                                 return new X509CertificateEndpointIdentity (el.CertificateReference.CreateInstance ());
216                         else if (el.Dns != null)
217                                 return new DnsEndpointIdentity (el.Dns.Value);
218                         else if (el.Rsa != null)
219                                 return new RsaEndpointIdentity (el.Rsa.Value);
220                         else if (el.ServicePrincipalName != null)
221                                 return new SpnEndpointIdentity (el.ServicePrincipalName.Value);
222                         else if (el.UserPrincipalName != null)
223                                 return new UpnEndpointIdentity (el.UserPrincipalName.Value);
224                         else
225                                 return null;
226                 }
227
228                 public static X509Certificate2 CreateCertificateFrom (StoreLocation storeLocation, StoreName storeName, X509FindType findType, Object findValue)
229                 {
230                         var store = new X509Store (storeName, storeLocation);
231                         store.Open (OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
232                         try {
233                                 foreach (var c in store.Certificates.Find (findType, findValue, false))
234                                         return c;
235                                 throw new InvalidOperationException (String.Format ("Specified X509 certificate with find type {0} and find value {1} was not found in X509 store {2} location {3}", findType, findValue, storeName, storeLocation));
236                         } finally {
237                                 store.Close ();
238                         }
239                 }
240
241                 public static X509Certificate2 CreateInstance (this CertificateElement el)
242                 {
243                         return new X509Certificate2 (Convert.FromBase64String (el.EncodedValue));
244                 }
245                 
246                 public static X509Certificate2 CreateInstance (this CertificateReferenceElement el)
247                 {
248                         return CreateCertificateFrom (el.StoreLocation, el.StoreName, el.X509FindType, el.FindValue);
249                 }
250
251                 public static X509Certificate2 CreateInstance (this X509ClientCertificateCredentialsElement el)
252                 {
253                         return CreateCertificateFrom (el.StoreLocation, el.StoreName, el.X509FindType, el.FindValue);
254                 }
255                 
256                 public static X509Certificate2 CreateInstance (this X509ScopedServiceCertificateElement el)
257                 {
258                         return CreateCertificateFrom (el.StoreLocation, el.StoreName, el.X509FindType, el.FindValue);
259                 }
260
261                 public static X509Certificate2 CreateInstance (this X509DefaultServiceCertificateElement el)
262                 {
263                         return CreateCertificateFrom (el.StoreLocation, el.StoreName, el.X509FindType, el.FindValue);
264                 }
265         }
266 }