summaryrefslogtreecommitdiffstats
blob: d3b10ddbe1b96390dffc9e547ebb3003a303bfdb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
 * Copyright (c) 2010-2011 Thilo Cestonaro
 * Licensed under the simplified BSD license.
 * See Documentation/Licenses/BSD-simplified.txt for more information.
 */

/*
 * Copyright (c) 2013-2018 Isode Limited.
 * All rights reserved.
 * See the COPYING file for more information.
 */

#include <Swiften/Base/Platform.h>
#include <Swiften/Network/MacOSXProxyProvider.h>

#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <utility>

#include <boost/numeric/conversion/cast.hpp>

#ifndef SWIFTEN_PLATFORM_IPHONE
#include <SystemConfiguration/SystemConfiguration.h>
#endif

#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"

using namespace Swift;

#ifndef SWIFTEN_PLATFORM_IPHONE
static HostAddressPort getFromDictionary(CFDictionaryRef dict, CFStringRef enabledKey, CFStringRef hostKey, CFStringRef portKey) {
    CFNumberRef numberValue = nullptr;
    HostAddressPort ret = HostAddressPort(HostAddress(), 0);

    if(CFDictionaryGetValueIfPresent(dict, reinterpret_cast<const void*> (enabledKey), reinterpret_cast<const void**> (&numberValue)) == true) {
        const int i = 0;
        CFNumberRef zero = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &i);
        CFComparisonResult result = CFNumberCompare(numberValue, zero, nullptr);
        CFRelease(zero);

        if(result != kCFCompareEqualTo) {
            unsigned short port = 0;
            std::string host = "";

            try {
                CFNumberRef numberValue = reinterpret_cast<CFNumberRef> (CFDictionaryGetValue(dict, portKey));
                if(numberValue != nullptr) {
                    int intPort = 0;
                    CFNumberGetValue(numberValue, kCFNumberIntType, &intPort);
                    port = boost::numeric_cast<unsigned short>(intPort);
                }

                CFStringRef stringValue = reinterpret_cast<CFStringRef> (CFDictionaryGetValue(dict, hostKey));
                if(stringValue != nullptr) {
                    std::vector<char> buffer;
                     // length must be +1 for the ending zero; and the Docu of CFStringGetCString tells it like
                    // if the string is toby the length must be at least 5.
                    CFIndex length = CFStringGetLength(stringValue) + 1;
                    buffer.resize(boost::numeric_cast<size_t>(length));
                    if(CFStringGetCString(stringValue, &buffer[0], length, kCFStringEncodingMacRoman)) {
                        for(char& iter : buffer) {
                            host += iter;
                        }
                    }
                }
            }
            catch(...) {
                std::cerr << "Exception caught ... " << std::endl;
            }

            if(host != "" && port != 0) {
                ret = HostAddressPort(HostAddress::fromString(host).get(), port);
            }
        }
    }
    return ret;
}
#endif
namespace Swift {

MacOSXProxyProvider::MacOSXProxyProvider() {
}

HostAddressPort MacOSXProxyProvider::getHTTPConnectProxy() const {
    HostAddressPort result;
#ifndef SWIFTEN_PLATFORM_IPHONE
    CFDictionaryRef proxies = SCDynamicStoreCopyProxies(nullptr);
    if(proxies != nullptr) {
        result = getFromDictionary(proxies, kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort);
        CFRelease(proxies);
    }
#endif
    return result;
}

HostAddressPort MacOSXProxyProvider::getSOCKS5Proxy() const {
    HostAddressPort result;
#ifndef SWIFTEN_PLATFORM_IPHONE
    CFDictionaryRef proxies = SCDynamicStoreCopyProxies(nullptr);
    if(proxies != nullptr) {
        result = getFromDictionary(proxies, kSCPropNetProxiesSOCKSEnable, kSCPropNetProxiesSOCKSProxy, kSCPropNetProxiesSOCKSPort);
        CFRelease(proxies);
    }
#endif
    return result;
}

}