FireBreath  1.4.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Pages
SystemProxyDetectorMac.cpp
1 
2 #include <boost/type_traits.hpp>
3 #include <CoreFoundation/CoreFoundation.h>
4 #include <ApplicationServices/ApplicationServices.h>
5 #include <SystemConfiguration/SystemConfiguration.h>
6 #include <SystemConfiguration/SCDynamicStore.h>
7 #include <boost/algorithm/string.hpp>
8 #include <boost/scoped_ptr.hpp>
9 #include <boost/scoped_array.hpp>
10 #include <vector>
11 
12 #include "URI.h"
13 
14 #include "Mac/SystemProxyDetectorMac.h"
15 
16 using boost::algorithm::split;
17 using boost::algorithm::is_any_of;
18 using std::string;
19 using std::vector;
20 using std::map;
21 
22 std::string conv_cfstring(CFStringRef s) {
23  size_t l = (CFStringGetLength(s) * 2) + 1;
24  boost::scoped_array<char> q(new char[l]);
25  q[0] = '\0';
26  CFStringGetCString(s, q.get(), l, kCFStringEncodingUTF8);
27  std::string res(q.get());
28  return res;
29 }
30 
31 int cfnumber_to_int(CFNumberRef n) {
32  if (! n) return 0;
33 
34  int nn;
35  CFNumberGetValue(n, kCFNumberIntType, &nn);
36  return nn;
37 }
38 
39 FB::SystemProxyDetector* FB::SystemProxyDetector::get()
40 {
41  static boost::scoped_ptr<FB::SystemProxyDetector> _inst(new FB::SystemProxyDetectorMac());
42  return _inst.get();
43 }
44 
45 bool FB::SystemProxyDetectorMac::detectProxy( map<string, string>& proxyMap, const string& URL )
46 {
47  CFDictionaryRef proxySettings(SCDynamicStoreCopyProxies(NULL));
48  if (! proxySettings) {
49  return false;
50  }
51  FB::URI uri(FB::URI::fromString(URL));
52  /*
53  * -- relevant dictionary keys
54  * kSCPropNetProxiesHTTPEnable "HTTPEnable" CFNumber (0 or 1)
55  * kSCPropNetProxiesHTTPPort "HTTPPort" CFNumber
56  * kSCPropNetProxiesHTTPProxy "HTTPProxy" CFString
57  * kSCPropNetProxiesSOCKSEnable "SOCKSEnable" CFNumber (0 or 1)
58  * kSCPropNetProxiesSOCKSPort "SOCKSPort" CFNumber
59  * kSCPropNetProxiesSOCKSProxy "SOCKSProxy" CFString
60  */
61 
62  if (uri.protocol == "http" && cfnumber_to_int((CFNumberRef) CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPEnable))) {
63  // HTTP proxy?
64  proxyMap["type"] = uri.protocol;
65  proxyMap["hostname"] = conv_cfstring((CFStringRef) CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPProxy));
66  int port = cfnumber_to_int((CFNumberRef) CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPPort));
67  proxyMap["port"] = boost::lexical_cast<std::string>(port);
68  } else if (uri.protocol == "https" && cfnumber_to_int((CFNumberRef) CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSEnable))) {
69  // HTTPS proxy?
70  proxyMap["type"] = uri.protocol;
71  proxyMap["hostname"] = conv_cfstring((CFStringRef) CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSProxy));
72  int port = cfnumber_to_int((CFNumberRef) CFDictionaryGetValue(proxySettings, kSCPropNetProxiesHTTPSPort));
73  proxyMap["port"] = boost::lexical_cast<std::string>(port);
74  } else if (cfnumber_to_int((CFNumberRef) CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSEnable))) {
75  // SOCKS proxy on fallback
76  proxyMap["type"] = "socks";
77  proxyMap["hostname"] = conv_cfstring((CFStringRef) CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSProxy));
78  int port = cfnumber_to_int((CFNumberRef) CFDictionaryGetValue(proxySettings, kSCPropNetProxiesSOCKSPort));
79  proxyMap["port"] = boost::lexical_cast<std::string>(port);
80  }
81 
82  CFRelease(proxySettings);
83  if (proxyMap.find("type") != proxyMap.end())
84  return true;
85  else
86  return false;
87 }
static URI fromString(const std::string &in_str)
Returns a URI object from the given string.
Definition: URI.cpp:90
Data structure for dealing with URI strings.
Definition: URI.h:42