ef9715fb4b4fb00e0cc5ffb30c1fac359060ec25
[mono.git] / mcs / class / System.ServiceModel / System.ServiceModel / BasicHttpBinding_4_5.cs
1 //
2 // BasicHttpBinding_4_5.cs
3 //
4 // Authors:
5 //      Atsushi Enomoto <atsushi@ximian.com>
6 //      Martin Baulig <martin.baulig@xamarin.com>
7 //
8 // Copyright (C) 2005-2006 Novell, Inc.  http://www.novell.com
9 // Copyright 2011-2012 Xamarin Inc (http://www.xamarin.com).
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 using System;
31 using System.Collections.Generic;
32 using System.Net;
33 using System.Net.Security;
34 using System.ServiceModel.Channels;
35 using System.ServiceModel.Description;
36 using System.Text;
37 using System.Xml;
38 using System.ServiceModel.Configuration;
39
40 namespace System.ServiceModel
41 {
42         public class BasicHttpBinding : HttpBindingBase,
43                 IBindingRuntimePreferences
44         {
45                 WSMessageEncoding message_encoding = WSMessageEncoding.Text;
46                 BasicHttpSecurity security;
47
48                 public BasicHttpBinding ()
49                         : this (BasicHttpSecurityMode.None)
50                 {
51                 }
52                 
53 #if !NET_2_1 && !XAMMAC_4_5
54                 public BasicHttpBinding (string configurationName)
55                         : this ()
56                 {
57                         BindingsSection bindingsSection = ConfigUtil.BindingsSection;
58                         BasicHttpBindingElement el = 
59                                 bindingsSection.BasicHttpBinding.Bindings [configurationName];
60
61                         el.ApplyConfiguration (this);
62                 }
63 #endif
64
65                 public BasicHttpBinding (
66                         BasicHttpSecurityMode securityMode)
67                 {
68                         security = new BasicHttpSecurity (securityMode);
69                 }
70
71                 public WSMessageEncoding MessageEncoding {
72                         get { return message_encoding; }
73                         set { message_encoding = value; }
74                 }
75
76                 public override string Scheme {
77                         get {
78                                 switch (Security.Mode) {
79                                 case BasicHttpSecurityMode.Transport:
80                                 case BasicHttpSecurityMode.TransportWithMessageCredential:
81                                         return Uri.UriSchemeHttps;
82                                 default:
83                                         return Uri.UriSchemeHttp;
84                                 }
85                         }
86                 }
87
88                 public BasicHttpSecurity Security {
89                         get { return security; }
90                         set { security = value; }
91                 }
92
93                 public override BindingElementCollection
94                         CreateBindingElements ()
95                 {
96                         var list = new List<BindingElement> ();
97                         
98                         var security = CreateSecurityBindingElement ();
99                         if (security != null)
100                                 list.Add (security);
101
102                         list.Add (BuildMessageEncodingBindingElement ());
103                         list.Add (GetTransport ());
104
105                         return new BindingElementCollection (list.ToArray ());
106                 }
107                 
108                 SecurityBindingElement CreateSecurityBindingElement () 
109                 {
110                         SecurityBindingElement element;
111                         switch (Security.Mode) {
112                         case BasicHttpSecurityMode.Message:
113 #if NET_2_1 || XAMMAC_4_5
114                                 throw new NotImplementedException ();
115 #else
116                                 if (Security.Message.ClientCredentialType != BasicHttpMessageCredentialType.Certificate)
117                                         throw new InvalidOperationException ("When Message security is enabled in a BasicHttpBinding, the message security credential type must be BasicHttpMessageCredentialType.Certificate.");
118                                 element = SecurityBindingElement.CreateMutualCertificateBindingElement (
119                                     MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
120                                 break;
121 #endif
122
123                         case BasicHttpSecurityMode.TransportWithMessageCredential:
124 #if NET_2_1 || XAMMAC_4_5
125                                 throw new NotImplementedException ();
126 #else
127                                 if (Security.Message.ClientCredentialType != BasicHttpMessageCredentialType.Certificate)
128                                         // FIXME: pass proper security token parameters.
129                                         element = SecurityBindingElement.CreateCertificateOverTransportBindingElement ();
130                                 else
131                                         element = new AsymmetricSecurityBindingElement ();
132                                 break;
133 #endif
134                         default: 
135                                 return null;
136                         }
137                         
138 #if !NET_2_1 && !XAMMAC_4_5
139                         element.SetKeyDerivation (false);
140                         element.SecurityHeaderLayout = SecurityHeaderLayout.Lax;
141 #endif
142                         return element;
143                 }
144
145                 MessageEncodingBindingElement BuildMessageEncodingBindingElement ()
146                 {
147                         if (MessageEncoding == WSMessageEncoding.Text) {
148                                 TextMessageEncodingBindingElement tm = new TextMessageEncodingBindingElement (
149                                         MessageVersion.CreateVersion (EnvelopeVersion, AddressingVersion.None), TextEncoding);
150                                 ReaderQuotas.CopyTo (tm.ReaderQuotas);
151                                 return tm;
152                         } else {
153 #if NET_2_1 || XAMMAC_4_5
154                                 throw new NotImplementedException ();
155 #else
156                                 return new MtomMessageEncodingBindingElement (
157                                         MessageVersion.CreateVersion (EnvelopeVersion, AddressingVersion.None), TextEncoding);
158 #endif
159                         }
160                 }
161
162                 TransportBindingElement GetTransport ()
163                 {
164                         HttpTransportBindingElement h;
165                         switch (Security.Mode) {
166                         case BasicHttpSecurityMode.Transport:
167                         case BasicHttpSecurityMode.TransportWithMessageCredential:
168                                 h = new HttpsTransportBindingElement ();
169                                 break;
170                         default:
171                                 h = new HttpTransportBindingElement ();
172                                 break;
173                         }
174
175                         h.AllowCookies = AllowCookies;
176                         h.BypassProxyOnLocal = BypassProxyOnLocal;
177                         h.HostNameComparisonMode = HostNameComparisonMode;
178                         h.MaxBufferPoolSize = MaxBufferPoolSize;
179                         h.MaxBufferSize = MaxBufferSize;
180                         h.MaxReceivedMessageSize = MaxReceivedMessageSize;
181                         h.ProxyAddress = ProxyAddress;
182                         h.UseDefaultWebProxy = UseDefaultWebProxy;
183                         h.TransferMode = TransferMode;
184                         h.ExtendedProtectionPolicy = Security.Transport.ExtendedProtectionPolicy;
185
186                         switch (Security.Transport.ClientCredentialType) {
187                         case HttpClientCredentialType.Basic:
188                                 h.AuthenticationScheme = AuthenticationSchemes.Basic;
189                                 break;
190                         case HttpClientCredentialType.Ntlm:
191                                 h.AuthenticationScheme = AuthenticationSchemes.Ntlm;
192                                 break;
193                         case HttpClientCredentialType.Windows:
194                                 h.AuthenticationScheme = AuthenticationSchemes.Negotiate;
195                                 break;
196                         case HttpClientCredentialType.Digest:
197                                 h.AuthenticationScheme = AuthenticationSchemes.Digest;
198                                 break;
199                         case HttpClientCredentialType.Certificate:
200                                 switch (Security.Mode) {
201                                 case BasicHttpSecurityMode.Transport:
202                                         (h as HttpsTransportBindingElement).RequireClientCertificate = true;
203                                         break;
204                                 case BasicHttpSecurityMode.TransportCredentialOnly:
205                                         throw new InvalidOperationException ("Certificate-based client authentication is not supported by 'TransportCredentialOnly' mode.");
206                                 }
207                                 break;
208                         }
209
210                         return h;
211                 }
212         }
213 }