1 //------------------------------------------------------------------------------
2 // <copyright file="DefaultProxySection.cs" company="Microsoft Corporation">
3 // Copyright (c) Microsoft Corporation. All rights reserved.
5 //------------------------------------------------------------------------------
7 namespace System.Net.Configuration
9 using System.Collections.Generic;
10 using System.Configuration;
11 using System.Globalization;
13 using System.Reflection;
14 using System.Threading;
15 using System.Security;
16 using System.Security.Permissions;
17 using System.Security.Principal;
18 using System.ComponentModel;
21 public sealed class DefaultProxySection : ConfigurationSection
23 public DefaultProxySection()
25 this.properties.Add(this.bypasslist);
26 this.properties.Add(this.module);
27 this.properties.Add(this.proxy);
28 this.properties.Add(this.enabled);
29 this.properties.Add(this.useDefaultCredentials);
32 protected override void PostDeserialize()
34 // Perf optimization. If the configuration is coming from machine.config
35 // It is safe and we don't need to check for permissions.
36 if (EvaluationContext.IsMachineLevel)
40 ExceptionHelper.WebPermissionUnrestricted.Demand();
41 } catch (Exception exception) {
42 throw new ConfigurationErrorsException(
43 SR.GetString(SR.net_config_section_permission,
44 ConfigurationStrings.DefaultProxySectionName),
49 [ConfigurationProperty(ConfigurationStrings.BypassList)]
50 public BypassElementCollection BypassList
52 get { return (BypassElementCollection)this[this.bypasslist]; }
55 [ConfigurationProperty(ConfigurationStrings.Module)]
56 public ModuleElement Module
58 get { return (ModuleElement)this[this.module]; }
61 protected override ConfigurationPropertyCollection Properties
63 get { return this.properties; }
66 [ConfigurationProperty(ConfigurationStrings.Proxy)]
67 public ProxyElement Proxy
69 get { return (ProxyElement)this[this.proxy]; }
72 [ConfigurationProperty(ConfigurationStrings.Enabled, DefaultValue = true)]
75 get { return (bool) this[this.enabled]; }
76 set { this[this.enabled] = value; }
79 [ConfigurationProperty(ConfigurationStrings.UseDefaultCredentials, DefaultValue = false)]
80 public bool UseDefaultCredentials
82 get { return (bool) this[this.useDefaultCredentials]; }
83 set { this[this.useDefaultCredentials] = value; }
86 ConfigurationPropertyCollection properties = new ConfigurationPropertyCollection();
88 readonly ConfigurationProperty bypasslist =
89 new ConfigurationProperty(ConfigurationStrings.BypassList,
90 typeof(BypassElementCollection),
92 ConfigurationPropertyOptions.None);
94 readonly ConfigurationProperty module =
95 new ConfigurationProperty(ConfigurationStrings.Module,
96 typeof(ModuleElement),
98 ConfigurationPropertyOptions.None);
100 readonly ConfigurationProperty proxy =
101 new ConfigurationProperty(ConfigurationStrings.Proxy,
102 typeof(ProxyElement),
104 ConfigurationPropertyOptions.None);
106 readonly ConfigurationProperty enabled =
107 new ConfigurationProperty(ConfigurationStrings.Enabled,
110 ConfigurationPropertyOptions.None);
112 readonly ConfigurationProperty useDefaultCredentials =
113 new ConfigurationProperty(ConfigurationStrings.UseDefaultCredentials,
116 ConfigurationPropertyOptions.None);
119 // This allows us to prevent parent settings (machine.config) from propegating to higher config (app.config), unless
120 // the higher config doesn't contain the section at all. That is, overriding defaultProxy is all-or-nothing.
121 // Template from Microsoft.
122 protected override void Reset(ConfigurationElement parentElement)
124 // Ignore the parentElement parameter by changing it to the default settings
125 DefaultProxySection defaultElement = new DefaultProxySection();
127 // Initialize the parentElement to the right set of defaults (not needed now,
128 // but this will avoid errors in the future if SetDefaults is ever overridden in this class.
129 // ConfigurationElement::InitializeDefault is a no-op, so you aren
\92t hurting perf by anything
131 defaultElement.InitializeDefault();
133 // Finally, pass it to the base class to do the
\93right things
\94
134 base.Reset(defaultElement);
138 internal sealed class DefaultProxySectionInternal
141 [SecurityPermission(SecurityAction.Assert, Flags=SecurityPermissionFlag.ControlPrincipal)]
142 internal DefaultProxySectionInternal(DefaultProxySection section)
144 // If enabled is false, skip everything.
145 if (!section.Enabled)
150 // If nothing else is set, use the system default.
151 if (section.Proxy.AutoDetect == ProxyElement.AutoDetectValues.Unspecified &&
152 section.Proxy.ScriptLocation == null &&
153 String.IsNullOrEmpty(section.Module.Type) &&
154 section.Proxy.UseSystemDefault != ProxyElement.UseSystemDefaultValues.True &&
155 section.Proxy.ProxyAddress == null &&
156 section.Proxy.BypassOnLocal == ProxyElement.BypassOnLocalValues.Unspecified &&
157 section.BypassList.Count == 0)
159 // Old-style indication to turn off the proxy.
160 if (section.Proxy.UseSystemDefault == ProxyElement.UseSystemDefaultValues.False)
162 this.webProxy = new EmptyWebProxy();
164 // Intentionally ignoring UseDefaultCredentials in this case.
168 // Suspend impersonation.
170 new SecurityPermission(SecurityPermissionFlag.ControlPrincipal | SecurityPermissionFlag.UnmanagedCode).Assert();
172 using(WindowsIdentity.Impersonate(IntPtr.Zero))
173 #endif // !FEATURE_PAL
175 CodeAccessPermission.RevertAssert();
176 this.webProxy = new WebRequest.WebProxyWrapper(new WebProxy(true));
184 // First, check out if we are using a different module type
185 if (!String.IsNullOrEmpty(section.Module.Type))
187 Type theType = Type.GetType(section.Module.Type, true, true);
189 if ((theType.Attributes & TypeAttributes.VisibilityMask) != TypeAttributes.Public)
190 throw new ConfigurationErrorsException(SR.GetString(SR.net_config_proxy_module_not_public));
192 // verify that its of the proper type of IWebProxy
193 if (!typeof(IWebProxy).IsAssignableFrom(theType))
195 throw new InvalidCastException(SR.GetString(SR.net_invalid_cast,
199 this.webProxy = (IWebProxy)Activator.CreateInstance(
201 BindingFlags.CreateInstance
202 | BindingFlags.Instance
203 | BindingFlags.NonPublic
204 | BindingFlags.Public,
206 new object[0], // no arguments
207 CultureInfo.InvariantCulture
210 else if (section.Proxy.UseSystemDefault == ProxyElement.UseSystemDefaultValues.True &&
211 section.Proxy.AutoDetect == ProxyElement.AutoDetectValues.Unspecified &&
212 section.Proxy.ScriptLocation == null)
214 // Suspend impersonation. This setting is deprecated but required for Everett compat.
216 new SecurityPermission(SecurityPermissionFlag.ControlPrincipal | SecurityPermissionFlag.UnmanagedCode).Assert();
218 using(WindowsIdentity.Impersonate(IntPtr.Zero))
219 #endif // !FEATURE_PAL
221 CodeAccessPermission.RevertAssert();
222 this.webProxy = new WebProxy(false);
230 this.webProxy = new WebProxy();
233 WebProxy tempProxy = this.webProxy as WebProxy;
235 if (tempProxy != null)
237 if (section.Proxy.AutoDetect != ProxyElement.AutoDetectValues.Unspecified)
239 tempProxy.AutoDetect = section.Proxy.AutoDetect == ProxyElement.AutoDetectValues.True;
241 if (section.Proxy.ScriptLocation != null)
243 tempProxy.ScriptLocation = section.Proxy.ScriptLocation;
245 if (section.Proxy.BypassOnLocal != ProxyElement.BypassOnLocalValues.Unspecified)
247 tempProxy.BypassProxyOnLocal = section.Proxy.BypassOnLocal == ProxyElement.BypassOnLocalValues.True;
249 if (section.Proxy.ProxyAddress != null)
251 tempProxy.Address = section.Proxy.ProxyAddress;
253 int bypassListSize = section.BypassList.Count;
254 if (bypassListSize > 0)
256 string[] bypassList = new string[section.BypassList.Count];
257 for (int index = 0; index < bypassListSize; ++index)
259 bypassList[index] = section.BypassList[index].Address;
261 tempProxy.BypassList = bypassList;
264 // Wrap it if type not explicitly specified in Module.
265 if (section.Module.Type == null)
267 this.webProxy = new WebRequest.WebProxyWrapper(tempProxy);
272 // Now apply UseDefaultCredentials if there's a proxy.
273 if (this.webProxy != null && section.UseDefaultCredentials)
275 this.webProxy.Credentials = SystemNetworkCredential.defaultCredential;
280 static IWebProxy GetDefaultProxy_UsingOldMonoCode()
282 #if CONFIGURATION_DEP
283 DefaultProxySection sec = ConfigurationManager.GetSection ("system.net/defaultProxy") as DefaultProxySection;
287 return GetSystemWebProxy ();
289 ProxyElement pe = sec.Proxy;
291 if ((pe.UseSystemDefault != ProxyElement.UseSystemDefaultValues.False) && (pe.ProxyAddress == null)) {
292 IWebProxy proxy = GetSystemWebProxy ();
294 if (!(proxy is WebProxy))
297 p = (WebProxy) proxy;
301 if (pe.ProxyAddress != null)
302 p.Address = pe.ProxyAddress;
304 if (pe.BypassOnLocal != ProxyElement.BypassOnLocalValues.Unspecified)
305 p.BypassProxyOnLocal = (pe.BypassOnLocal == ProxyElement.BypassOnLocalValues.True);
307 foreach(BypassElement elem in sec.BypassList)
308 p.BypassArrayList.Add(elem.Address);
312 return GetSystemWebProxy ();
316 static IWebProxy GetSystemWebProxy()
318 return System.Net.WebProxy.CreateDefaultProxy ();
323 internal static object ClassSyncObject
327 if (classSyncObject == null)
329 object o = new object();
330 Interlocked.CompareExchange(ref classSyncObject, o, null);
332 return classSyncObject;
336 static internal DefaultProxySectionInternal GetSection()
338 lock (DefaultProxySectionInternal.ClassSyncObject)
341 var res = new DefaultProxySectionInternal();
342 res.webProxy = GetDefaultProxy_UsingOldMonoCode ();
345 DefaultProxySection section = PrivilegedConfigurationManager.GetSection(ConfigurationStrings.DefaultProxySectionPath) as DefaultProxySection;
351 return new DefaultProxySectionInternal(section);
353 catch (Exception exception)
355 if (NclUtilities.IsFatal(exception)) throw;
357 throw new ConfigurationErrorsException(SR.GetString(SR.net_config_proxy), exception);
363 internal IWebProxy WebProxy
365 get { return this.webProxy; }
368 private IWebProxy webProxy;
369 private static object classSyncObject;