• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
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_resolution/proxy_config_service_ios.h"
6 
7 #include <CFNetwork/CFProxySupport.h>
8 #include <CoreFoundation/CoreFoundation.h>
9 
10 #include "base/apple/foundation_util.h"
11 #include "base/apple/scoped_cftyperef.h"
12 #include "base/functional/bind.h"
13 #include "base/functional/callback.h"
14 #include "base/strings/sys_string_conversions.h"
15 #include "net/base/proxy_chain.h"
16 #include "net/proxy_resolution/proxy_chain_util_apple.h"
17 #include "net/proxy_resolution/proxy_config_with_annotation.h"
18 
19 namespace net {
20 
21 namespace {
22 
23 const int kPollIntervalSec = 10;
24 
25 // Utility function to pull out a boolean value from a dictionary and return it,
26 // returning a default value if the key is not present.
GetBoolFromDictionary(CFDictionaryRef dict,CFStringRef key,bool default_value)27 bool GetBoolFromDictionary(CFDictionaryRef dict,
28                            CFStringRef key,
29                            bool default_value) {
30   CFNumberRef number =
31       base::apple::GetValueFromDictionary<CFNumberRef>(dict, key);
32   if (!number) {
33     return default_value;
34   }
35 
36   int int_value;
37   if (CFNumberGetValue(number, kCFNumberIntType, &int_value)) {
38     return int_value;
39   } else {
40     return default_value;
41   }
42 }
43 
GetCurrentProxyConfig(const NetworkTrafficAnnotationTag traffic_annotation,ProxyConfigWithAnnotation * config)44 void GetCurrentProxyConfig(const NetworkTrafficAnnotationTag traffic_annotation,
45                            ProxyConfigWithAnnotation* config) {
46   base::apple::ScopedCFTypeRef<CFDictionaryRef> config_dict(
47       CFNetworkCopySystemProxySettings());
48   DCHECK(config_dict);
49   ProxyConfig proxy_config;
50   // Auto-detect is not supported.
51   // The kCFNetworkProxiesProxyAutoDiscoveryEnable key is not available on iOS.
52 
53   // PAC file
54 
55   if (GetBoolFromDictionary(config_dict.get(),
56                             kCFNetworkProxiesProxyAutoConfigEnable, false)) {
57     CFStringRef pac_url_ref = base::apple::GetValueFromDictionary<CFStringRef>(
58         config_dict.get(), kCFNetworkProxiesProxyAutoConfigURLString);
59     if (pac_url_ref) {
60       proxy_config.set_pac_url(GURL(base::SysCFStringRefToUTF8(pac_url_ref)));
61     }
62   }
63 
64   // Proxies (for now http).
65 
66   // The following keys are not available on iOS:
67   //   kCFNetworkProxiesFTPEnable
68   //   kCFNetworkProxiesFTPProxy
69   //   kCFNetworkProxiesFTPPort
70   //   kCFNetworkProxiesHTTPSEnable
71   //   kCFNetworkProxiesHTTPSProxy
72   //   kCFNetworkProxiesHTTPSPort
73   //   kCFNetworkProxiesSOCKSEnable
74   //   kCFNetworkProxiesSOCKSProxy
75   //   kCFNetworkProxiesSOCKSPort
76   if (GetBoolFromDictionary(config_dict.get(), kCFNetworkProxiesHTTPEnable,
77                             false)) {
78     ProxyChain proxy_chain = ProxyDictionaryToProxyChain(
79         kCFProxyTypeHTTP, config_dict.get(), kCFNetworkProxiesHTTPProxy,
80         kCFNetworkProxiesHTTPPort);
81     if (proxy_chain.IsValid()) {
82       proxy_config.proxy_rules().type =
83           ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
84       proxy_config.proxy_rules().proxies_for_http.SetSingleProxyChain(
85           proxy_chain);
86       // Desktop Safari applies the HTTP proxy to http:// URLs only, but
87       // Mobile Safari applies the HTTP proxy to https:// URLs as well.
88       proxy_config.proxy_rules().proxies_for_https.SetSingleProxyChain(
89           proxy_chain);
90     }
91   }
92 
93   // Proxy bypass list is not supported.
94   // The kCFNetworkProxiesExceptionsList key is not available on iOS.
95 
96   // Proxy bypass boolean is not supported.
97   // The kCFNetworkProxiesExcludeSimpleHostnames key is not available on iOS.
98 
99   // Source
100   proxy_config.set_from_system(true);
101   *config = ProxyConfigWithAnnotation(proxy_config, traffic_annotation);
102 }
103 
104 }  // namespace
105 
ProxyConfigServiceIOS(const NetworkTrafficAnnotationTag & traffic_annotation)106 ProxyConfigServiceIOS::ProxyConfigServiceIOS(
107     const NetworkTrafficAnnotationTag& traffic_annotation)
108     : PollingProxyConfigService(base::Seconds(kPollIntervalSec),
109                                 base::BindRepeating(GetCurrentProxyConfig),
110                                 traffic_annotation) {}
111 
112 ProxyConfigServiceIOS::~ProxyConfigServiceIOS() = default;
113 
114 }  // namespace net
115