blob: 74b1ea644a1971daf2ca20a54e98ee1944fa3b5d [file] [log] [blame]
[email protected]a9944f02009-12-10 10:37:271// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/proxy/proxy_config_service_mac.h"
6
7#include <CoreFoundation/CoreFoundation.h>
8#include <SystemConfiguration/SystemConfiguration.h>
9
10#include "base/logging.h"
11#include "base/mac_util.h"
12#include "base/scoped_cftyperef.h"
13#include "base/sys_string_conversions.h"
14#include "net/base/net_errors.h"
15#include "net/proxy/proxy_config.h"
16#include "net/proxy/proxy_info.h"
17#include "net/proxy/proxy_server.h"
18
19namespace {
20
21// Utility function to pull out a boolean value from a dictionary and return it,
22// returning a default value if the key is not present.
23bool GetBoolFromDictionary(CFDictionaryRef dict,
24 CFStringRef key,
25 bool default_value) {
26 CFNumberRef number = (CFNumberRef)mac_util::GetValueFromDictionary(
27 dict, key, CFNumberGetTypeID());
28 if (!number)
29 return default_value;
30
31 int int_value;
32 if (CFNumberGetValue(number, kCFNumberIntType, &int_value))
33 return int_value;
34 else
35 return default_value;
36}
37
38} // namespace
39
40namespace net {
41
42int ProxyConfigServiceMac::GetProxyConfig(ProxyConfig* config) {
43 scoped_cftyperef<CFDictionaryRef> config_dict(
44 SCDynamicStoreCopyProxies(NULL));
45 DCHECK(config_dict);
46
47 // auto-detect
48
49 // There appears to be no UI for this configuration option, and we're not sure
50 // if Apple's proxy code even takes it into account. But the constant is in
51 // the header file so we'll use it.
52 config->auto_detect =
53 GetBoolFromDictionary(config_dict.get(),
54 kSCPropNetProxiesProxyAutoDiscoveryEnable,
55 false);
56
57 // PAC file
58
59 if (GetBoolFromDictionary(config_dict.get(),
60 kSCPropNetProxiesProxyAutoConfigEnable,
61 false)) {
62 CFStringRef pac_url_ref = (CFStringRef)mac_util::GetValueFromDictionary(
63 config_dict.get(),
64 kSCPropNetProxiesProxyAutoConfigURLString,
65 CFStringGetTypeID());
66 if (pac_url_ref)
67 config->pac_url = GURL(base::SysCFStringRefToUTF8(pac_url_ref));
68 }
69
70 // proxies (for now ftp, http, https, and SOCKS)
71
72 if (GetBoolFromDictionary(config_dict.get(),
73 kSCPropNetProxiesFTPEnable,
74 false)) {
75 ProxyServer proxy_server =
76 ProxyServer::FromDictionary(ProxyServer::SCHEME_HTTP,
77 config_dict.get(),
78 kSCPropNetProxiesFTPProxy,
79 kSCPropNetProxiesFTPPort);
80 if (proxy_server.is_valid()) {
81 config->proxy_rules.type = ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
82 config->proxy_rules.proxy_for_ftp = proxy_server;
83 }
84 }
85 if (GetBoolFromDictionary(config_dict.get(),
86 kSCPropNetProxiesHTTPEnable,
87 false)) {
88 ProxyServer proxy_server =
89 ProxyServer::FromDictionary(ProxyServer::SCHEME_HTTP,
90 config_dict.get(),
91 kSCPropNetProxiesHTTPProxy,
92 kSCPropNetProxiesHTTPPort);
93 if (proxy_server.is_valid()) {
94 config->proxy_rules.type = ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
95 config->proxy_rules.proxy_for_http = proxy_server;
96 }
97 }
98 if (GetBoolFromDictionary(config_dict.get(),
99 kSCPropNetProxiesHTTPSEnable,
100 false)) {
101 ProxyServer proxy_server =
102 ProxyServer::FromDictionary(ProxyServer::SCHEME_HTTP,
103 config_dict.get(),
104 kSCPropNetProxiesHTTPSProxy,
105 kSCPropNetProxiesHTTPSPort);
106 if (proxy_server.is_valid()) {
107 config->proxy_rules.type = ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
108 config->proxy_rules.proxy_for_https = proxy_server;
109 }
110 }
111 if (GetBoolFromDictionary(config_dict.get(),
112 kSCPropNetProxiesSOCKSEnable,
113 false)) {
114 ProxyServer proxy_server =
115 ProxyServer::FromDictionary(ProxyServer::SCHEME_SOCKS5,
116 config_dict.get(),
117 kSCPropNetProxiesSOCKSProxy,
118 kSCPropNetProxiesSOCKSPort);
119 if (proxy_server.is_valid()) {
120 config->proxy_rules.type = ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;
121 config->proxy_rules.socks_proxy = proxy_server;
122 }
123 }
124
125 // proxy bypass list
126
127 CFArrayRef bypass_array_ref =
128 (CFArrayRef)mac_util::GetValueFromDictionary(
129 config_dict.get(),
130 kSCPropNetProxiesExceptionsList,
131 CFArrayGetTypeID());
132 if (bypass_array_ref) {
133 CFIndex bypass_array_count = CFArrayGetCount(bypass_array_ref);
134 for (CFIndex i = 0; i < bypass_array_count; ++i) {
135 CFStringRef bypass_item_ref =
136 (CFStringRef)CFArrayGetValueAtIndex(bypass_array_ref, i);
137 if (CFGetTypeID(bypass_item_ref) != CFStringGetTypeID()) {
138 LOG(WARNING) << "Expected value for item " << i
139 << " in the kSCPropNetProxiesExceptionsList"
140 " to be a CFStringRef but it was not";
141
142 } else {
[email protected]7541206c2010-02-19 20:24:06143 config->bypass_rules.AddRuleFromString(
[email protected]a9944f02009-12-10 10:37:27144 base::SysCFStringRefToUTF8(bypass_item_ref));
145 }
146 }
147 }
148
149 // proxy bypass boolean
150
[email protected]7541206c2010-02-19 20:24:06151 if (GetBoolFromDictionary(config_dict.get(),
[email protected]a9944f02009-12-10 10:37:27152 kSCPropNetProxiesExcludeSimpleHostnames,
[email protected]7541206c2010-02-19 20:24:06153 false)) {
154 config->bypass_rules.AddRuleToBypassLocal();
155 }
[email protected]a9944f02009-12-10 10:37:27156
157 return OK;
158}
159
160} // namespace net