diff options
Diffstat (limited to 'src/proxy.cpp')
| -rw-r--r-- | src/proxy.cpp | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/src/proxy.cpp b/src/proxy.cpp index d7dc324..7d30911 100644 --- a/src/proxy.cpp +++ b/src/proxy.cpp | |||
| @@ -9,8 +9,10 @@ | |||
| 9 | 9 | ||
| 10 | static CCriticalSection cs_socks5; | 10 | static CCriticalSection cs_socks5; |
| 11 | static bool g_fSocks5Proxy = false; | 11 | static bool g_fSocks5Proxy = false; |
| 12 | static bool g_fTorProxy = false; | ||
| 12 | static std::string g_socks5Host; | 13 | static std::string g_socks5Host; |
| 13 | static unsigned short g_socks5Port = 0; | 14 | static unsigned short g_socks5Port = 0; |
| 15 | static const char* DEFAULT_TOR_SOCKS5_PROXY = "127.0.0.1:9050"; | ||
| 14 | 16 | ||
| 15 | static void SetSocketTimeout(SOCKET s, int nTimeoutSecs) | 17 | static void SetSocketTimeout(SOCKET s, int nTimeoutSecs) |
| 16 | { | 18 | { |
| @@ -67,6 +69,24 @@ static bool ValidProxyIpv6HostChar(char c) | |||
| 67 | return isxdigit((unsigned char)c) || c == ':' || c == '.'; | 69 | return isxdigit((unsigned char)c) || c == ':' || c == '.'; |
| 68 | } | 70 | } |
| 69 | 71 | ||
| 72 | static std::string LowerProxyHost(std::string host) | ||
| 73 | { | ||
| 74 | if (!host.empty() && host[host.size() - 1] == '.') | ||
| 75 | host.erase(host.size() - 1); | ||
| 76 | for (size_t i = 0; i < host.size(); i++) | ||
| 77 | host[i] = (char)tolower((unsigned char)host[i]); | ||
| 78 | return host; | ||
| 79 | } | ||
| 80 | |||
| 81 | bool BtfIsTorOnionHost(const std::string& host) | ||
| 82 | { | ||
| 83 | std::string lower = LowerProxyHost(host); | ||
| 84 | static const char* suffix = ".onion"; | ||
| 85 | size_t suffixLen = strlen(suffix); | ||
| 86 | return lower.size() > suffixLen && | ||
| 87 | lower.compare(lower.size() - suffixLen, suffixLen, suffix) == 0; | ||
| 88 | } | ||
| 89 | |||
| 70 | static bool ParsePort(const std::string& port, unsigned short& portOut, | 90 | static bool ParsePort(const std::string& port, unsigned short& portOut, |
| 71 | std::string& errOut) | 91 | std::string& errOut) |
| 72 | { | 92 | { |
| @@ -176,7 +196,8 @@ bool BtfParseSocks5Proxy(const std::string& spec, std::string& hostOut, | |||
| 176 | return true; | 196 | return true; |
| 177 | } | 197 | } |
| 178 | 198 | ||
| 179 | bool BtfSetSocks5Proxy(const std::string& spec, std::string& errOut) | 199 | static bool SetSocks5Proxy(const std::string& spec, bool fTorMode, |
| 200 | std::string& errOut) | ||
| 180 | { | 201 | { |
| 181 | std::string host; | 202 | std::string host; |
| 182 | unsigned short port = 0; | 203 | unsigned short port = 0; |
| @@ -187,15 +208,27 @@ bool BtfSetSocks5Proxy(const std::string& spec, std::string& errOut) | |||
| 187 | g_socks5Host = host; | 208 | g_socks5Host = host; |
| 188 | g_socks5Port = port; | 209 | g_socks5Port = port; |
| 189 | g_fSocks5Proxy = true; | 210 | g_fSocks5Proxy = true; |
| 211 | g_fTorProxy = fTorMode; | ||
| 190 | } | 212 | } |
| 191 | return true; | 213 | return true; |
| 192 | } | 214 | } |
| 193 | 215 | ||
| 216 | bool BtfSetSocks5Proxy(const std::string& spec, std::string& errOut) | ||
| 217 | { | ||
| 218 | return SetSocks5Proxy(spec, false, errOut); | ||
| 219 | } | ||
| 220 | |||
| 221 | bool BtfEnableTorProxy(const std::string& spec, std::string& errOut) | ||
| 222 | { | ||
| 223 | return SetSocks5Proxy(spec.empty() ? DEFAULT_TOR_SOCKS5_PROXY : spec, true, errOut); | ||
| 224 | } | ||
| 225 | |||
| 194 | void BtfClearSocks5Proxy() | 226 | void BtfClearSocks5Proxy() |
| 195 | { | 227 | { |
| 196 | CRITICAL_BLOCK(cs_socks5) | 228 | CRITICAL_BLOCK(cs_socks5) |
| 197 | { | 229 | { |
| 198 | g_fSocks5Proxy = false; | 230 | g_fSocks5Proxy = false; |
| 231 | g_fTorProxy = false; | ||
| 199 | g_socks5Host.clear(); | 232 | g_socks5Host.clear(); |
| 200 | g_socks5Port = 0; | 233 | g_socks5Port = 0; |
| 201 | } | 234 | } |
| @@ -208,6 +241,13 @@ bool BtfSocks5ProxyEnabled() | |||
| 208 | return false; | 241 | return false; |
| 209 | } | 242 | } |
| 210 | 243 | ||
| 244 | bool BtfTorProxyEnabled() | ||
| 245 | { | ||
| 246 | CRITICAL_BLOCK(cs_socks5) | ||
| 247 | return g_fSocks5Proxy && g_fTorProxy; | ||
| 248 | return false; | ||
| 249 | } | ||
| 250 | |||
| 211 | std::string BtfSocks5ProxyName() | 251 | std::string BtfSocks5ProxyName() |
| 212 | { | 252 | { |
| 213 | CRITICAL_BLOCK(cs_socks5) | 253 | CRITICAL_BLOCK(cs_socks5) |
| @@ -315,7 +355,15 @@ SOCKET BtfConnectSocket(const std::string& destHost, unsigned short destPort, | |||
| 315 | } | 355 | } |
| 316 | 356 | ||
| 317 | if (!fProxy) | 357 | if (!fProxy) |
| 358 | { | ||
| 359 | if (BtfIsTorOnionHost(destHost)) | ||
| 360 | { | ||
| 361 | error("Refusing direct .onion connection to %s:%u; use /tor or /socks\n", | ||
| 362 | destHost.c_str(), (unsigned)destPort); | ||
| 363 | return INVALID_SOCKET; | ||
| 364 | } | ||
| 318 | return ConnectDirect(destHost, destPort, nSockSite, nTimeoutSecs); | 365 | return ConnectDirect(destHost, destPort, nSockSite, nTimeoutSecs); |
| 366 | } | ||
| 319 | 367 | ||
| 320 | SOCKET s = ConnectDirect(proxyHost, proxyPort, nSockSite, nTimeoutSecs); | 368 | SOCKET s = ConnectDirect(proxyHost, proxyPort, nSockSite, nTimeoutSecs); |
| 321 | if (s == INVALID_SOCKET) | 369 | if (s == INVALID_SOCKET) |