diff options
33 files changed, 1154 insertions, 6 deletions
| diff --git a/BuildTools/SCons/SConstruct b/BuildTools/SCons/SConstruct index 43b6df0..246092d 100644 --- a/BuildTools/SCons/SConstruct +++ b/BuildTools/SCons/SConstruct @@ -193,7 +193,7 @@ if env.get("coverage", 0) :  	env.Append(LINKFLAGS = ["-fprofile-arcs", "-ftest-coverage"])  if env["PLATFORM"] == "win32" : -	env.Append(LIBS = ["user32", "crypt32", "dnsapi", "ws2_32", "wsock32"]) +	env.Append(LIBS = ["user32", "crypt32", "dnsapi", "ws2_32", "wsock32", "Advapi32"])  	env.Append(CCFLAGS = ["/EHsc", "/nologo"])  	# FIXME: We should find a decent solution for MSVS 10  	if int(env["MSVS_VERSION"].split(".")[0]) < 10 : @@ -201,7 +201,7 @@ if env["PLATFORM"] == "win32" :  		env["SHLINKCOM"] = [env["SHLINKCOM"], 'mt.exe -nologo -manifest ${TARGET}.manifest -outputresource:$TARGET;2']  if env["PLATFORM"] == "darwin" and not env["target"] in ["iphone-device", "iphone-simulator", "xcode"] : -	env.Append(FRAMEWORKS = ["IOKit", "AppKit"]) +	env.Append(FRAMEWORKS = ["IOKit", "AppKit", "SystemConfiguration"])  # Testing  env["TEST_TYPE"] = env["test"] @@ -421,6 +421,22 @@ if env["PLATFORM"] != "win32" and env["PLATFORM"] != "darwin" :  		env["XSS_FLAGS"] = xss_flags  	conf.Finish() +# GConf +env["HAVE_GCONF"] = 0 +if env["PLATFORM"] != "win32" and env["PLATFORM"] != "darwin" : +	gconf_env = Environment() +	gconf_env.ParseConfig('pkg-config --cflags gconf-2.0 --libs gconf-2.0') +	conf = Configure(gconf_env) +	if conf.CheckCHeader("gconf/gconf-client.h") and conf.CheckLib("gconf-2") : +		env["HAVE_GCONF"] = 1 +		env["GCONF_FLAGS"] = { +			"LIBS": gconf_env["LIBS"], +			"CCFLAGS": gconf_env["CCFLAGS"], +			"CPPPATH": gconf_env["CPPPATH"], +			"CPPDEFINES": gconf_env["CPPDEFINES"], +		} +	conf.Finish() +  # Sparkle  env["HAVE_SPARKLE"] = 0  if env["PLATFORM"] == "darwin" : diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp index 8e51c8e..348f3b3 100644 --- a/Swiften/Client/CoreClient.cpp +++ b/Swiften/Client/CoreClient.cpp @@ -19,17 +19,28 @@  #include "Swiften/Base/IDGenerator.h"  #include "Swiften/Client/ClientSessionStanzaChannel.h"  #include <Swiften/Base/Log.h> +#include "Swiften/Network/PlatformProxyProvider.h" +#include "Swiften/Network/SOCKS5ProxiedConnectionFactory.h" +#include "Swiften/Network/HTTPConnectProxiedConnectionFactory.h"  namespace Swift { -CoreClient::CoreClient(const JID& jid, const std::string& password, NetworkFactories* networkFactories) : jid_(jid), password_(password), networkFactories(networkFactories), useStreamCompression(true), useTLS(UseTLSWhenAvailable), disconnectRequested_(false), certificateTrustChecker(NULL) { +CoreClient::CoreClient(const JID& jid, const std::string& password, NetworkFactories* networkFactories) : jid_(jid), password_(password), networkFactories(networkFactories), useStreamCompression(true), useTLS(UseTLSWhenAvailable), proxyConnectionFactory_(NULL), disconnectRequested_(false), certificateTrustChecker(NULL) {  	stanzaChannel_ = new ClientSessionStanzaChannel();  	stanzaChannel_->onMessageReceived.connect(boost::bind(&CoreClient::handleMessageReceived, this, _1));  	stanzaChannel_->onPresenceReceived.connect(boost::bind(&CoreClient::handlePresenceReceived, this, _1));  	stanzaChannel_->onStanzaAcked.connect(boost::bind(&CoreClient::handleStanzaAcked, this, _1));  	stanzaChannel_->onAvailableChanged.connect(boost::bind(&CoreClient::handleStanzaChannelAvailableChanged, this, _1)); +	PlatformProxyProvider proxyProvider; +  	iqRouter_ = new IQRouter(stanzaChannel_); +	if(proxyProvider.getSOCKS5Proxy().isValid()) { +		proxyConnectionFactory_ = new SOCKS5ProxiedConnectionFactory(networkFactories->getConnectionFactory(), proxyProvider.getSOCKS5Proxy()); +	} +	else if(proxyProvider.getHTTPConnectProxy().isValid()) { +		proxyConnectionFactory_ = new HTTPConnectProxiedConnectionFactory(networkFactories->getConnectionFactory(), proxyProvider.getHTTPConnectProxy()); +	}  	tlsFactories = new PlatformTLSFactories();  } @@ -38,6 +49,7 @@ CoreClient::~CoreClient() {  		std::cerr << "Warning: Client not disconnected properly" << std::endl;  	}  	delete tlsFactories; +	delete proxyConnectionFactory_;  	delete iqRouter_;  	stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&CoreClient::handleStanzaChannelAvailableChanged, this, _1)); @@ -56,7 +68,7 @@ void CoreClient::connect(const std::string& host) {  	SWIFT_LOG(debug) << "Connecting to host " << host << std::endl;  	disconnectRequested_ = false;  	assert(!connector_); -	connector_ = Connector::create(host, networkFactories->getDomainNameResolver(), networkFactories->getConnectionFactory(), networkFactories->getTimerFactory()); +	connector_ = Connector::create(host, networkFactories->getDomainNameResolver(), proxyConnectionFactory_ != NULL ? proxyConnectionFactory_ : networkFactories->getConnectionFactory(), networkFactories->getTimerFactory());  	connector_->onConnectFinished.connect(boost::bind(&CoreClient::handleConnectorFinished, this, _1));  	connector_->setTimeoutMilliseconds(60*1000);  	connector_->start(); diff --git a/Swiften/Client/CoreClient.h b/Swiften/Client/CoreClient.h index ceb0b0a..2debb7f 100644 --- a/Swiften/Client/CoreClient.h +++ b/Swiften/Client/CoreClient.h @@ -221,6 +221,7 @@ namespace Swift {  			ClientSessionStanzaChannel* stanzaChannel_;  			IQRouter* iqRouter_;  			boost::shared_ptr<Connector> connector_; +			ConnectionFactory* proxyConnectionFactory_;  			PlatformTLSFactories* tlsFactories;  			boost::shared_ptr<Connection> connection_;  			boost::shared_ptr<BasicSessionStream> sessionStream_; diff --git a/Swiften/Network/EnvironmentProxyProvider.cpp b/Swiften/Network/EnvironmentProxyProvider.cpp new file mode 100644 index 0000000..b3bd0f6 --- /dev/null +++ b/Swiften/Network/EnvironmentProxyProvider.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <iostream> + +#include "Swiften/Base/Log.h" +#include "Swiften/Network/EnvironmentProxyProvider.h" + +namespace Swift { + +EnvironmentProxyProvider::EnvironmentProxyProvider() { +	socksProxy = getFromEnv("all_proxy", "socks"); +	httpProxy = getFromEnv("http_proxy", "http"); +	SWIFT_LOG(debug) << "Environment: SOCKS5 => " << socksProxy.toString() << "; HTTP Connect => " << httpProxy.toString() << std::endl; +} + +HostAddressPort EnvironmentProxyProvider::getHTTPConnectProxy() const { +	return httpProxy; +} + +HostAddressPort EnvironmentProxyProvider::getSOCKS5Proxy() const { +	return socksProxy; +} + +HostAddressPort EnvironmentProxyProvider::getFromEnv(const char* envVarName, std::string proxyProtocol) { +	char* envVar = NULL; +	std::string address; +	int port = 0; + +	envVar = getenv(envVarName); + +	proxyProtocol += "://"; +	address = envVar != NULL ? envVar : "0.0.0.0"; +	if(envVar != NULL && address.compare(0, proxyProtocol.length(), proxyProtocol) == 0) { +		address = address.substr(proxyProtocol.length(), address.length()); +		port = atoi(address.substr(address.find(':') + 1, address.length()).c_str()); +		address = address.substr(0, address.find(':')); +	} + +	return HostAddressPort(HostAddress(address), port); +} + +} diff --git a/Swiften/Network/EnvironmentProxyProvider.h b/Swiften/Network/EnvironmentProxyProvider.h new file mode 100644 index 0000000..1743269 --- /dev/null +++ b/Swiften/Network/EnvironmentProxyProvider.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include "Swiften/Network/ProxyProvider.h" + +namespace Swift { +	class EnvironmentProxyProvider : public ProxyProvider { +		public: +			EnvironmentProxyProvider(); +			virtual HostAddressPort getHTTPConnectProxy() const; +			virtual HostAddressPort getSOCKS5Proxy() const; +		private: +			HostAddressPort getFromEnv(const char* envVarName, std::string proxyProtocol); +			HostAddressPort socksProxy; +			HostAddressPort httpProxy; +	}; +} + + diff --git a/Swiften/Network/GConfProxyProvider.cpp b/Swiften/Network/GConfProxyProvider.cpp new file mode 100644 index 0000000..687bf77 --- /dev/null +++ b/Swiften/Network/GConfProxyProvider.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <iostream> + +#include <gconf/gconf-client.h> + +#include "Swiften/Base/Log.h" +#include "Swiften/Network/GConfProxyProvider.h" + +namespace Swift { + +GConfProxyProvider::GConfProxyProvider() { +	socksProxy = getFromGConf("/system/proxy/socks_host", "/system/proxy/socks_port"); +	httpProxy = getFromGConf("/system/http_proxy/host", "/system/http_proxy/port"); +	SWIFT_LOG(debug) << "GConf: SOCKS5 => " << socksProxy.toString() << "; HTTP Connect => " << httpProxy.toString() << std::endl; +} + +HostAddressPort GConfProxyProvider::getHTTPConnectProxy() const { +	return httpProxy; +} + +HostAddressPort GConfProxyProvider::getSOCKS5Proxy() const { +	return socksProxy; +} + +HostAddressPort GConfProxyProvider::getFromGConf(const char* gcHost, const char* gcPort) { +	std::string address; +	int port = 0; +	gchar* str; + +	GConfClient* client = gconf_client_get_default(); + +	str = gconf_client_get_string(client, gcHost, NULL); +	port = static_cast<int> (gconf_client_get_int(client, gcPort, NULL)); + +	if(str) { +		address = static_cast<char*> (str); +		g_free(str); +	} + +	g_object_unref(client); +	return HostAddressPort(HostAddress(address), port); +} + +} diff --git a/Swiften/Network/GConfProxyProvider.h b/Swiften/Network/GConfProxyProvider.h new file mode 100644 index 0000000..15586ad --- /dev/null +++ b/Swiften/Network/GConfProxyProvider.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include "Swiften/Network/ProxyProvider.h" + +namespace Swift { +	class GConfProxyProvider : public ProxyProvider { +		public: +			GConfProxyProvider(); +			virtual HostAddressPort getHTTPConnectProxy() const; +			virtual HostAddressPort getSOCKS5Proxy() const; +		private: +			HostAddressPort getFromGConf(const char* gcHost, const char* gcPort); +			HostAddressPort socksProxy; +			HostAddressPort httpProxy; +	}; +} + + diff --git a/Swiften/Network/HTTPConnectProxiedConnection.cpp b/Swiften/Network/HTTPConnectProxiedConnection.cpp new file mode 100644 index 0000000..4e05f29 --- /dev/null +++ b/Swiften/Network/HTTPConnectProxiedConnection.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "Swiften/Network/HTTPConnectProxiedConnection.h" + +#include <iostream> +#include <boost/bind.hpp> +#include <boost/thread.hpp> +#include <boost/lexical_cast.hpp> +#include <math.h> + +#include "Swiften/Base/Log.h" +#include "Swiften/Base/String.h" +#include "Swiften/Base/ByteArray.h" +#include "Swiften/Network/HostAddressPort.h" + +namespace Swift { + +HTTPConnectProxiedConnection::HTTPConnectProxiedConnection(ConnectionFactory* connectionFactory, HostAddressPort proxy) +: connectionFactory_(connectionFactory), proxy_(proxy), server_(HostAddressPort(HostAddress("0.0.0.0"), 0)) +{ +	connected_ = false; +} + +HTTPConnectProxiedConnection::~HTTPConnectProxiedConnection() { +	if(connection_) { +		connection_->onDataRead.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleDataRead, shared_from_this(), _1)); +		connection_->onDisconnected.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleDisconnected, shared_from_this(), _1)); +	} + +	if(connected_) { +		std::cerr << "Warning: Connection was still established." << std::endl; +	} +} + +void HTTPConnectProxiedConnection::connect(const HostAddressPort& server) { +	server_ = server; +	connection_ = connectionFactory_->createConnection(); +	connection_->onConnectFinished.connect(boost::bind(&HTTPConnectProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1)); +	connection_->onDataRead.connect(boost::bind(&HTTPConnectProxiedConnection::handleDataRead, shared_from_this(), _1)); +	connection_->onDisconnected.connect(boost::bind(&HTTPConnectProxiedConnection::handleDisconnected, shared_from_this(), _1)); +	connection_->connect(proxy_); +} + +void HTTPConnectProxiedConnection::listen() { +	assert(false); +	connection_->listen(); +} + +void HTTPConnectProxiedConnection::disconnect() { +	connected_ = false; +	connection_->disconnect(); +} + +void HTTPConnectProxiedConnection::handleDisconnected(const boost::optional<Error>& error) { +	onDisconnected(error); +} + +void HTTPConnectProxiedConnection::write(const ByteArray& data) { +	connection_->write(data); +} + +void HTTPConnectProxiedConnection::handleConnectionConnectFinished(bool error) { +	connection_->onConnectFinished.disconnect(boost::bind(&HTTPConnectProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1)); +	if(!error) { +		proxyState_ = ProxyConnecting; +		std::stringstream connect; +		connect << "CONNECT " << server_.getAddress().toString() << ":" << server_.getPort() << " HTTP/1.1\r\n\r\n"; +		connection_->write(ByteArray(connect.str())); +	} +	else { +		onConnectFinished(true); +	} +} + +void HTTPConnectProxiedConnection::handleDataRead(const ByteArray& data) { +	if (!connected_) { +		if (proxyState_ == ProxyConnecting) { +			SWIFT_LOG(debug) << data.toString() << std::endl; +			std::vector<std::string> tmp = String::split(data.toString(), ' '); +			if(tmp.size() > 1) { +				int status = boost::lexical_cast<int> (tmp[1].c_str());  +				SWIFT_LOG(debug) << "Proxy Status: " << status << std::endl; +				if (status / 100 == 2) { // all 2XX states are OK +					connected_ = true; +					onConnectFinished(false); +					return; +				} +			} + +			std::cerr << "HTTP Proxy returned an error: " << data.toString() << std::endl; +			return; +		} +	} +	else { +		onDataRead(data); +		return; +	} +	disconnect(); +	onConnectFinished(true); +} + +HostAddressPort HTTPConnectProxiedConnection::getLocalAddress() const { +	return connection_->getLocalAddress(); +} + +//namespace +} diff --git a/Swiften/Network/HTTPConnectProxiedConnection.h b/Swiften/Network/HTTPConnectProxiedConnection.h new file mode 100644 index 0000000..88b4f66 --- /dev/null +++ b/Swiften/Network/HTTPConnectProxiedConnection.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/enable_shared_from_this.hpp> + +#include "Swiften/Network/ConnectionFactory.h" +#include "Swiften/Network/Connection.h" +#include "Swiften/Network/HostAddressPort.h" + +namespace boost { +	class thread; +	namespace system { +		class error_code; +	} +} + +namespace Swift { +	class HTTPConnectProxiedConnection : public Connection, public boost::enable_shared_from_this<HTTPConnectProxiedConnection> { +		public: +			typedef boost::shared_ptr<HTTPConnectProxiedConnection> ref; + +			~HTTPConnectProxiedConnection(); + +			static ref create(ConnectionFactory* connectionFactory, HostAddressPort proxy) { +				return ref(new HTTPConnectProxiedConnection(connectionFactory, proxy)); +			} + +			virtual void listen(); +			virtual void connect(const HostAddressPort& address); +			virtual void disconnect(); +			virtual void write(const ByteArray& data); + +			virtual HostAddressPort getLocalAddress() const; +		private: +			enum { +				ProxyAuthenticating = 0, +				ProxyConnecting, +			} proxyState_; + +			HTTPConnectProxiedConnection(ConnectionFactory* connectionFactory, HostAddressPort proxy); + +			void handleConnectionConnectFinished(bool error); +			void handleDataRead(const ByteArray& data); +			void handleDisconnected(const boost::optional<Error>& error); + +		private: +			bool connected_; +			ConnectionFactory* connectionFactory_;	 +			HostAddressPort proxy_; +			HostAddressPort server_; +			boost::shared_ptr<Connection> connection_; +	}; +} diff --git a/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp b/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp new file mode 100644 index 0000000..0212945 --- /dev/null +++ b/Swiften/Network/HTTPConnectProxiedConnectionFactory.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "Swiften/Network/HTTPConnectProxiedConnectionFactory.h" +#include "Swiften/Network/HTTPConnectProxiedConnection.h" + +namespace Swift { + +HTTPConnectProxiedConnectionFactory::HTTPConnectProxiedConnectionFactory(ConnectionFactory* connectionFactory, HostAddressPort proxy) +: connectionFactory_(connectionFactory), proxy_(proxy) +{ + +} + +boost::shared_ptr<Connection> HTTPConnectProxiedConnectionFactory::createConnection() { +	return HTTPConnectProxiedConnection::create(connectionFactory_, proxy_); +} + +} diff --git a/Swiften/Network/HTTPConnectProxiedConnectionFactory.h b/Swiften/Network/HTTPConnectProxiedConnectionFactory.h new file mode 100644 index 0000000..7aeb337 --- /dev/null +++ b/Swiften/Network/HTTPConnectProxiedConnectionFactory.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include "Swiften/Network/ConnectionFactory.h" +#include "Swiften/Network/HTTPConnectProxiedConnection.h" +#include "Swiften/Network/HostAddressPort.h" + +namespace Swift { +	class HTTPConnectProxiedConnection; + +	class HTTPConnectProxiedConnectionFactory : public ConnectionFactory { +		public: +			HTTPConnectProxiedConnectionFactory(ConnectionFactory* connectionFactory, HostAddressPort proxy); + +			virtual boost::shared_ptr<Connection> createConnection(); + +		private: +			ConnectionFactory* connectionFactory_; +			HostAddressPort proxy_; +	}; +} diff --git a/Swiften/Network/HostAddress.cpp b/Swiften/Network/HostAddress.cpp index 331a233..f734329 100644 --- a/Swiften/Network/HostAddress.cpp +++ b/Swiften/Network/HostAddress.cpp @@ -57,4 +57,8 @@ bool HostAddress::isValid() const {  	return !(address_.is_v4() && address_.to_v4().to_ulong() == 0);  } +boost::asio::ip::address HostAddress::getRawAddress() const { +	return address_; +} +  } diff --git a/Swiften/Network/HostAddress.h b/Swiften/Network/HostAddress.h index 3e9c8a6..0b3bdda 100644 --- a/Swiften/Network/HostAddress.h +++ b/Swiften/Network/HostAddress.h @@ -3,7 +3,6 @@   * Licensed under the GNU General Public License v3.   * See Documentation/Licenses/GPLv3.txt for more information.   */ -  #pragma once  #include <string> @@ -18,6 +17,7 @@ namespace Swift {  			HostAddress(const boost::asio::ip::address& address);  			std::string toString() const; +			boost::asio::ip::address getRawAddress() const;  			bool operator==(const HostAddress& o) const {  				return address_ == o.address_; diff --git a/Swiften/Network/HostAddressPort.h b/Swiften/Network/HostAddressPort.h index c99ca65..5655f4d 100644 --- a/Swiften/Network/HostAddressPort.h +++ b/Swiften/Network/HostAddressPort.h @@ -7,6 +7,7 @@  #pragma once  #include <boost/asio/ip/tcp.hpp> +#include <boost/lexical_cast.hpp>  #include "Swiften/Network/HostAddress.h" @@ -37,6 +38,10 @@ namespace Swift {  			bool isValid() const {  				return address_.isValid() && port_ > 0;  			} +			 +			std::string toString() const { +				return getAddress().toString() + ":" + boost::lexical_cast<std::string>(getPort()); +			}  		private:  			HostAddress address_; diff --git a/Swiften/Network/MacOSXProxyProvider.cpp b/Swiften/Network/MacOSXProxyProvider.cpp new file mode 100644 index 0000000..babcc7f --- /dev/null +++ b/Swiften/Network/MacOSXProxyProvider.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <iostream> +#include <utility> + +#include "Swiften/Network/MacOSXProxyProvider.h" +#include <SystemConfiguration/SystemConfiguration.h> + +namespace Swift { + +MacOSXProxyProvider::MacOSXProxyProvider() +: ProxyProvider() +{ +	CFDictionaryRef proxies = SCDynamicStoreCopyProxies(NULL); +	if(proxies != NULL) { +		socksProxy = getFromDictionary(proxies, kSCPropNetProxiesSOCKSEnable, kSCPropNetProxiesSOCKSProxy, kSCPropNetProxiesSOCKSPort); +		httpProxy = getFromDictionary(proxies, kSCPropNetProxiesHTTPEnable, kSCPropNetProxiesHTTPProxy, kSCPropNetProxiesHTTPPort); +	} +} + +HostAddressPort MacOSXProxyProvider::getHTTPConnectProxy() const { +	return httpProxy; +} + +HostAddressPort MacOSXProxyProvider::getSOCKS5Proxy() const { +	return socksProxy; +} + +HostAddressPort MacOSXProxyProvider::getFromDictionary(CFDictionaryRef dict, CFStringRef enabledKey, CFStringRef hostKey, CFStringRef portKey) { +	CFNumberRef numberValue = NULL; +	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, NULL); +		CFRelease(numberValue); + +		if(result != kCFCompareEqualTo) { +			int port = 0; +			std::string host = ""; + +			try { +				CFNumberRef numberValue = reinterpret_cast<CFNumberRef> (CFDictionaryGetValue(dict, portKey)); +				if(numberValue != NULL) { +					CFNumberGetValue(numberValue, kCFNumberIntType, &port); +					CFRelease(numberValue); +				} + +				CFStringRef stringValue = reinterpret_cast<CFStringRef> (CFDictionaryGetValue(dict, hostKey)); +				if(stringValue != NULL) { +					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(length); +					if(CFStringGetCString(stringValue, &buffer[0], length, kCFStringEncodingMacRoman)) { +						for(std::vector<char>::iterator iter = buffer.begin(); iter != buffer.end(); iter++) { +							host += *iter; +						} +					} +					CFRelease(stringValue); +				} +			} +			catch(...) { +				std::cerr << "Exception caught ... " << std::endl; +			} +			 +			if(host != "" && port != 0) { +				ret = HostAddressPort(HostAddress(host), port); +			} +		} +	} +	return ret; +} + +} diff --git a/Swiften/Network/MacOSXProxyProvider.h b/Swiften/Network/MacOSXProxyProvider.h new file mode 100644 index 0000000..1cb001f --- /dev/null +++ b/Swiften/Network/MacOSXProxyProvider.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once +#include "Swiften/Network/ProxyProvider.h" +#include <CoreFoundation/CoreFoundation.h> + +namespace Swift { +	class MacOSXProxyProvider : public ProxyProvider { +		public: +			MacOSXProxyProvider(); +			virtual HostAddressPort getHTTPConnectProxy() const; +			virtual HostAddressPort getSOCKS5Proxy() const; + +		private: +			HostAddressPort getFromDictionary(CFDictionaryRef dict, CFStringRef enabledKey, CFStringRef hostKey, CFStringRef portKey); +			HostAddressPort socksProxy; +			HostAddressPort httpProxy; +	}; +} diff --git a/Swiften/Network/PlatformProxyProvider.h b/Swiften/Network/PlatformProxyProvider.h new file mode 100644 index 0000000..13b15d2 --- /dev/null +++ b/Swiften/Network/PlatformProxyProvider.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include "Swiften/Base/Platform.h" + +#if defined(SWIFTEN_PLATFORM_MACOSX) +#include "Swiften/Network/MacOSXProxyProvider.h" +namespace Swift { +	typedef MacOSXProxyProvider PlatformProxyProvider; +} +#elif defined(SWIFTEN_PLATFORM_WIN32) +#include "Swiften/Network/WindowsProxyProvider.h" +namespace Swift { +	typedef WindowsProxyProvider PlatformProxyProvider; +} +#else +#include "Swiften/Network/UnixProxyProvider.h" +namespace Swift { +	typedef UnixProxyProvider PlatformProxyProvider; +} +#endif diff --git a/Swiften/Network/ProxyProvider.cpp b/Swiften/Network/ProxyProvider.cpp new file mode 100644 index 0000000..fe235b1 --- /dev/null +++ b/Swiften/Network/ProxyProvider.cpp @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "ProxyProvider.h" + +namespace Swift { + +ProxyProvider::ProxyProvider() +{ +} + +ProxyProvider::~ProxyProvider() +{ +} + +} diff --git a/Swiften/Network/ProxyProvider.h b/Swiften/Network/ProxyProvider.h new file mode 100644 index 0000000..05bb5a7 --- /dev/null +++ b/Swiften/Network/ProxyProvider.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once +#include <map> + +#include "Swiften/Base/Log.h" +#include "Swiften/Network/HostAddressPort.h" +#include "Swiften/Base/String.h" + +namespace Swift { +	class ProxyProvider { +		public: +			ProxyProvider(); +			virtual ~ProxyProvider(); +			virtual HostAddressPort getHTTPConnectProxy() const = 0; +			virtual HostAddressPort getSOCKS5Proxy() const = 0; +	}; +} + diff --git a/Swiften/Network/SConscript b/Swiften/Network/SConscript index 93732d1..426118b 100644 --- a/Swiften/Network/SConscript +++ b/Swiften/Network/SConscript @@ -6,6 +6,10 @@ if myenv.get("HAVE_CARES", False) :     myenv.MergeFlags(myenv.get("CARES_FLAGS", {}))  sourceList = [ +			"HTTPConnectProxiedConnection.cpp", +			"HTTPConnectProxiedConnectionFactory.cpp", +			"SOCKS5ProxiedConnection.cpp", +			"SOCKS5ProxiedConnectionFactory.cpp",  			"BoostConnection.cpp",  			"BoostConnectionFactory.cpp",  			"BoostConnectionServer.cpp", @@ -30,10 +34,25 @@ sourceList = [  			"NetworkFactories.cpp",  			"BoostNetworkFactories.cpp",  			"Timer.cpp", -			"BoostTimer.cpp"] +			"BoostTimer.cpp", +			"ProxyProvider.cpp" +	] +  if myenv.get("HAVE_CARES", False) :     sourceList.append("CAresDomainNameResolver.cpp") +if myenv["PLATFORM"] == "darwin" : +	myenv.Append(FRAMEWORKS = ["CoreServices", "SystemConfiguration"]) +	sourceList += [ "MacOSXProxyProvider.cpp" ] +elif myenv["PLATFORM"] == "win32" : +	sourceList += [ "WindowsProxyProvider.cpp" ] +else : +	sourceList += [ "UnixProxyProvider.cpp" ] +	sourceList += [ "EnvironmentProxyProvider.cpp" ] +	if myenv.get("HAVE_GCONF", 0) : +		myenv.Append(CPPDEFINES = "HAVE_GCONF") +		myenv.MergeFlags(myenv["GCONF_FLAGS"]) +		sourceList += [ "GConfProxyProvider.cpp" ]  objects = myenv.SwiftenObject(sourceList)  swiften_env.Append(SWIFTEN_OBJECTS = [objects]) diff --git a/Swiften/Network/SOCKS5ProxiedConnection.cpp b/Swiften/Network/SOCKS5ProxiedConnection.cpp new file mode 100644 index 0000000..d32a0f9 --- /dev/null +++ b/Swiften/Network/SOCKS5ProxiedConnection.cpp @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "Swiften/Network/SOCKS5ProxiedConnection.h" + +#include <iostream> +#include <boost/bind.hpp> +#include <boost/thread.hpp> +#include <math.h> + +#include "Swiften/Base/Log.h" +#include "Swiften/Base/String.h" +#include "Swiften/Base/ByteArray.h" +#include "Swiften/Network/HostAddressPort.h" + +namespace Swift { + +SOCKS5ProxiedConnection::SOCKS5ProxiedConnection(ConnectionFactory* connectionFactory, HostAddressPort proxy) +: connectionFactory_(connectionFactory), proxy_(proxy), server_(HostAddressPort(HostAddress("0.0.0.0"), 0)) +{ +	connected_ = false; +} + +SOCKS5ProxiedConnection::~SOCKS5ProxiedConnection() { +	if(connection_) { +		connection_->onDataRead.disconnect(boost::bind(&SOCKS5ProxiedConnection::handleDataRead, shared_from_this(), _1)); +		connection_->onDisconnected.disconnect(boost::bind(&SOCKS5ProxiedConnection::handleDisconnected, shared_from_this(), _1)); +	} + +	if(connected_) { +		std::cerr << "Warning: Connection was still established." << std::endl; +	} +} + +void SOCKS5ProxiedConnection::connect(const HostAddressPort& server) { +	server_ = server; +	connection_ = connectionFactory_->createConnection(); +	connection_->onConnectFinished.connect(boost::bind(&SOCKS5ProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1)); +	connection_->onDataRead.connect(boost::bind(&SOCKS5ProxiedConnection::handleDataRead, shared_from_this(), _1)); +	connection_->onDisconnected.connect(boost::bind(&SOCKS5ProxiedConnection::handleDisconnected, shared_from_this(), _1)); +	SWIFT_LOG(debug) << "Trying to connect via proxy " << proxy_.getAddress().toString() << ":" << proxy_.getPort() << std::endl; +	SWIFT_LOG(debug) << "to server " << server.getAddress().toString() << ":" << server.getPort() << std::endl; +	connection_->connect(proxy_); +} + +void SOCKS5ProxiedConnection::listen() { +	assert(false); +	connection_->listen(); +} + +void SOCKS5ProxiedConnection::disconnect() { +	connected_ = false; +	if(connection_) +		connection_->disconnect(); +} + +void SOCKS5ProxiedConnection::handleDisconnected(const boost::optional<Error>& error) { +	onDisconnected(error); +} + +void SOCKS5ProxiedConnection::write(const ByteArray& data) { +	if(connection_) +		connection_->write(data); +} + +void SOCKS5ProxiedConnection::handleConnectionConnectFinished(bool error) { +	connection_->onConnectFinished.disconnect(boost::bind(&SOCKS5ProxiedConnection::handleConnectionConnectFinished, shared_from_this(), _1)); +	if(!error) { +		SWIFT_LOG(debug) << "Connection to proxy established, now connect to the server via it." << std::endl; +		 +		proxyState_ = ProxyAuthenticating; +		ByteArray socksConnect; +		socksConnect += 0x05; // VER = SOCKS5 = 0x05 +		socksConnect += 0x01; // Number of authentication methods after this byte. +		socksConnect += 0x00; // 0x00 == no authentication +		// buffer.push_back(0x01); // 0x01 == GSSAPI  +		// buffer.push_back(0x02); // 0x02 ==  Username/Password +		// rest see RFC 1928 (http://tools.ietf.org/html/rfc1928) +		connection_->write(socksConnect); +	} +	else { +		onConnectFinished(true); +	} +} + +void SOCKS5ProxiedConnection::handleDataRead(const ByteArray& data) { +	ByteArray socksConnect; +	boost::asio::ip::address rawAddress = server_.getAddress().getRawAddress(); +	assert(rawAddress.is_v4() || rawAddress.is_v6()); +	if (!connected_) { +		if (proxyState_ == ProxyAuthenticating) { +			SWIFT_LOG(debug) << "ProxyAuthenticating response received, reply with the connect BYTEs" << std::endl; +			unsigned char choosenMethod = static_cast<unsigned char> (data[1]); +			if (data[0] == 0x05 && choosenMethod != 0xFF) { +				switch(choosenMethod) { // use the correct Method +					case 0x00: +						try { +							proxyState_ = ProxyConnecting; +							socksConnect += 0x05; // VER = SOCKS5 = 0x05 +							socksConnect += 0x01; // Construct a TCP connection. (CMD) +							socksConnect += 0x00; // reserved. +							socksConnect += rawAddress.is_v4() ? 0x01 : 0x04; // IPv4 == 0x01, Hostname == 0x02, IPv6 == 0x04. (ATYP) +							size_t size = rawAddress.is_v4() ? rawAddress.to_v4().to_bytes().size() : rawAddress.to_v6().to_bytes().size(); +							for (size_t s = 0; s < size; s++) { +								unsigned char uc; +								if(rawAddress.is_v4()) { +									uc = rawAddress.to_v4().to_bytes()[s]; // the address. +								} +								else +									uc = rawAddress.to_v6().to_bytes()[s]; // the address. +								socksConnect += static_cast<char> (uc); +						 +							} +							socksConnect += static_cast<unsigned char> (server_.getPort() >> 8); // highbyte of the port. +							socksConnect += static_cast<unsigned char> (server_.getPort()); // lowbyte of the port. +							connection_->write(socksConnect); +							return; +						} +						catch(...) { +							std::cerr << "exception caught" << std::endl; +						} +						connection_->write(socksConnect); +						break; +					default: +						onConnectFinished(true); +						break; +				} +				return; +			} +		} +		else if (proxyState_ == ProxyConnecting) { +			SWIFT_LOG(debug) << "Connect response received, check if successfully." << std::endl; +			SWIFT_LOG(debug) << "Errorbyte: 0x" << std::hex << static_cast<int> (data[1]) << std::dec << std::endl; +			/* + +			data.at(1) can be one of the following: +			0x00 	succeeded +			0x01 	general SOCKS server failure +			0x02 	connection not allowed by ruleset +			0x03 	Network unreachable +			0x04 	Host unreachable +			0x05 	Connection refused +			0x06 	TTL expired +			0x07 	Command not supported (CMD) +			0x08 	Address type not supported (ATYP) +			0x09 bis 0xFF 	unassigned +			*/ +			if (data[0] == 0x05 && data[1] == 0x0) { +				SWIFT_LOG(debug) << "Successfully connected the server via the proxy." << std::endl; +				connected_ = true; +				onConnectFinished(false); +				return; +			} +			else { +				std::cerr << "SOCKS Proxy returned an error: " << std::hex << data[1] << std::endl; +			} +			return; +		} +	} +	else { +		onDataRead(data); +		return; +	} +	disconnect(); +	onConnectFinished(true); +} + +HostAddressPort SOCKS5ProxiedConnection::getLocalAddress() const { +	return connection_->getLocalAddress(); +} + +//namespace +} diff --git a/Swiften/Network/SOCKS5ProxiedConnection.h b/Swiften/Network/SOCKS5ProxiedConnection.h new file mode 100644 index 0000000..b222fd7 --- /dev/null +++ b/Swiften/Network/SOCKS5ProxiedConnection.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/asio.hpp> +#include <boost/enable_shared_from_this.hpp> + +#include "Swiften/Network/ConnectionFactory.h" +#include "Swiften/Network/Connection.h" +#include "Swiften/Network/HostAddressPort.h" + +namespace boost { +	class thread; +	namespace system { +		class error_code; +	} +} + +namespace Swift { +	class SOCKS5ProxiedConnection : public Connection, public boost::enable_shared_from_this<SOCKS5ProxiedConnection> { +		public: +			typedef boost::shared_ptr<SOCKS5ProxiedConnection> ref; + +			~SOCKS5ProxiedConnection(); + +			static ref create(ConnectionFactory* connectionFactory, HostAddressPort proxy) { +				return ref(new SOCKS5ProxiedConnection(connectionFactory, proxy)); +			} + +			virtual void listen(); +			virtual void connect(const HostAddressPort& address); +			virtual void disconnect(); +			virtual void write(const ByteArray& data); + +			virtual HostAddressPort getLocalAddress() const; +		private: +			enum { +				ProxyAuthenticating = 0, +				ProxyConnecting, +			} proxyState_; + +			SOCKS5ProxiedConnection(ConnectionFactory* connectionFactory, HostAddressPort proxy); + +			void handleConnectionConnectFinished(bool error); +			void handleDataRead(const ByteArray& data); +			void handleDisconnected(const boost::optional<Error>& error); + +		private: +			bool connected_; +			ConnectionFactory* connectionFactory_;	 +			HostAddressPort proxy_; +			HostAddressPort server_; +			boost::shared_ptr<Connection> connection_; +	}; +} diff --git a/Swiften/Network/SOCKS5ProxiedConnectionFactory.cpp b/Swiften/Network/SOCKS5ProxiedConnectionFactory.cpp new file mode 100644 index 0000000..0be0931 --- /dev/null +++ b/Swiften/Network/SOCKS5ProxiedConnectionFactory.cpp @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include "Swiften/Network/SOCKS5ProxiedConnectionFactory.h" +#include "Swiften/Network/SOCKS5ProxiedConnection.h" + +namespace Swift { + +SOCKS5ProxiedConnectionFactory::SOCKS5ProxiedConnectionFactory(ConnectionFactory* connectionFactory, HostAddressPort proxy) +: connectionFactory_(connectionFactory), proxy_(proxy) +{ + +} + +boost::shared_ptr<Connection> SOCKS5ProxiedConnectionFactory::createConnection() { +	return SOCKS5ProxiedConnection::create(connectionFactory_, proxy_); +} + +} diff --git a/Swiften/Network/SOCKS5ProxiedConnectionFactory.h b/Swiften/Network/SOCKS5ProxiedConnectionFactory.h new file mode 100644 index 0000000..a78a9e8 --- /dev/null +++ b/Swiften/Network/SOCKS5ProxiedConnectionFactory.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once + +#include <boost/asio.hpp> + +#include "Swiften/Network/ConnectionFactory.h" +#include "Swiften/Network/SOCKS5ProxiedConnection.h" +#include "Swiften/Network/HostAddressPort.h" + +namespace Swift { +	class SOCKS5ProxiedConnection; + +	class SOCKS5ProxiedConnectionFactory : public ConnectionFactory { +		public: +			SOCKS5ProxiedConnectionFactory(ConnectionFactory* connectionFactory, HostAddressPort proxy); + +			virtual boost::shared_ptr<Connection> createConnection(); + +		private: +			ConnectionFactory* connectionFactory_; +			HostAddressPort proxy_; +	}; +} diff --git a/Swiften/Network/UnixProxyProvider.cpp b/Swiften/Network/UnixProxyProvider.cpp new file mode 100644 index 0000000..e21b310 --- /dev/null +++ b/Swiften/Network/UnixProxyProvider.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <iostream> + +#include "Swiften/Base/foreach.h" +#include "Swiften/Network/UnixProxyProvider.h" + +namespace Swift { + +UnixProxyProvider::UnixProxyProvider() : +#if defined(HAVE_GCONF) +	gconfProxyProvider(), +#endif +	environmentProxyProvider() +{ +} + +HostAddressPort UnixProxyProvider::getSOCKS5Proxy() const { +	HostAddressPort proxy; +#if defined(HAVE_GCONF) +	proxy = gconfProxyProvider.getSOCKS5Proxy(); +	if(proxy.isValid()) { +		return proxy; +	} +#endif +	proxy = environmentProxyProvider.getSOCKS5Proxy(); +	if(proxy.isValid()) { +		return proxy; +	} +	return HostAddressPort(HostAddress(), 0); +} + +HostAddressPort UnixProxyProvider::getHTTPConnectProxy() const { +	HostAddressPort proxy; +#if defined(HAVE_GCONF) +	proxy = gconfProxyProvider.getHTTPConnectProxy(); +	if(proxy.isValid()) { +		return proxy; +	} +#endif +	proxy = environmentProxyProvider.getHTTPConnectProxy(); +	if(proxy.isValid()) { +		return proxy; +	} +	return HostAddressPort(HostAddress(), 0); +} + + +} diff --git a/Swiften/Network/UnixProxyProvider.h b/Swiften/Network/UnixProxyProvider.h new file mode 100644 index 0000000..509cf4b --- /dev/null +++ b/Swiften/Network/UnixProxyProvider.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once +#if defined(HAVE_GCONF) +#  include "Swiften/Network/GConfProxyProvider.h" +#endif +#include "Swiften/Network/EnvironmentProxyProvider.h" + +namespace Swift { +	class UnixProxyProvider : public ProxyProvider { +		public: +			UnixProxyProvider(); +			virtual HostAddressPort getHTTPConnectProxy() const; +			virtual HostAddressPort getSOCKS5Proxy() const; +		private: +#if defined(HAVE_GCONF) +			GConfProxyProvider gconfProxyProvider; +#endif +			EnvironmentProxyProvider environmentProxyProvider; +	}; +} diff --git a/Swiften/Network/WindowsProxyProvider.cpp b/Swiften/Network/WindowsProxyProvider.cpp new file mode 100644 index 0000000..5f6f5d2 --- /dev/null +++ b/Swiften/Network/WindowsProxyProvider.cpp @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <math.h> +#include <iostream> +#include <boost/lexical_cast.hpp> + +#include "Swiften/Base/log.h" +#include "Swiften/Base/foreach.h" +#include "Swiften/Network/WindowsProxyProvider.h" +#include "Swiften/Base/ByteArray.h" + +#include <windows.h> + +namespace Swift { + +WindowsProxyProvider::WindowsProxyProvider() +: ProxyProvider() +{ +	HKEY hKey = (HKEY)INVALID_HANDLE_VALUE; +	long result; +		 +	result = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", 0, KEY_READ, &hKey); +	if (result == ERROR_SUCCESS && hKey != INVALID_HANDLE_VALUE && proxyEnabled(hKey)) { +		DWORD dataType = REG_SZ; +		DWORD dataSize = 0; +		ByteArray dataBuffer; + +		result = RegQueryValueEx(hKey, "ProxyServer", NULL, &dataType, NULL, &dataSize); +		if(result != ERROR_SUCCESS) { +			return; +		} +		dataBuffer.resize(dataSize); +		result = RegQueryValueEx(hKey, "ProxyServer", NULL, &dataType, reinterpret_cast<BYTE*>(dataBuffer.getData()), &dataSize); +		if(result == ERROR_SUCCESS) { +			std::vector<std::string> proxies = String::split(dataBuffer.toString(), ';'); +			std::pair<std::string, std::string> protocolAndProxy; +			foreach(std::string proxy, proxies) { +				if(proxy.find('=') != std::string::npos) { +					protocolAndProxy = String::getSplittedAtFirst(proxy, '='); +					SWIFT_LOG(debug) << "Found proxy: " << protocolAndProxy.first << " => " << protocolAndProxy.second << std::endl; +					if(protocolAndProxy.first.compare("socks") == 0) { +						socksProxy = getAsHostAddressPort(protocolAndProxy.second); +					} +					else if (protocolAndProxy.first.compare("http") == 0) { +						httpProxy = getAsHostAddressPort(protocolAndProxy.second); +					} +				} +			} +		} +	} +} + +HostAddressPort WindowsProxyProvider::getHTTPConnectProxy() const { +	return httpProxy; +} + +HostAddressPort WindowsProxyProvider::getSOCKS5Proxy() const { +	return socksProxy; +} + +HostAddressPort WindowsProxyProvider::getAsHostAddressPort(std::string proxy) { +	HostAddressPort ret(HostAddress(), 0); + +	try { +		std::pair<std::string, std::string> tmp; +		int port = 0; +		tmp = String::getSplittedAtFirst(proxy, ':'); +		// .c_str() is needed as tmp.second can include a \0 char which will end in an exception of the lexical cast. +		// with .c_str() the \0 will not be part of the string which is to be casted +		port = boost::lexical_cast<int> (tmp.second.c_str()); +		ret = HostAddressPort(HostAddress(tmp.first), port); +	} +	catch(...) { +			std::cerr << "Exception occured while parsing windows proxy \"getHostAddressPort\"." << std::endl; +	} + +	return ret; +} + + +bool WindowsProxyProvider::proxyEnabled(HKEY hKey) const { +	bool ret = false; +	long result; +	DWORD dataType = REG_DWORD; +	DWORD dataSize = 0; +	DWORD data = 0; +	ByteArray dataBuffer; + +	if(hKey == INVALID_HANDLE_VALUE) +		return ret; + +	result = RegQueryValueEx(hKey, "ProxyEnable", NULL, &dataType, NULL, &dataSize); +	if(result != ERROR_SUCCESS) +		return ret; + +	dataBuffer.resize(dataSize); +	result = RegQueryValueEx(hKey, "ProxyEnable", NULL, &dataType, reinterpret_cast<BYTE*>(dataBuffer.getData()), &dataSize); +	if(result != ERROR_SUCCESS) +		return ret; + +	for(size_t t = 0; t < dataBuffer.getSize(); t++) { +		data += static_cast<int> (dataBuffer[t]) * pow(256, static_cast<double>(t)); +	} +	return (data == 1); +} + +} diff --git a/Swiften/Network/WindowsProxyProvider.h b/Swiften/Network/WindowsProxyProvider.h new file mode 100644 index 0000000..d8d08f0 --- /dev/null +++ b/Swiften/Network/WindowsProxyProvider.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2010-2011 Thilo Cestonaro + * Licensed under the simplified BSD license. + * See Documentation/Licenses/BSD-simplified.txt for more information. + */ + +#pragma once +#include "Swiften/Network/ProxyProvider.h" + +namespace Swift { +	class WindowsProxyProvider : public ProxyProvider { +		public: +			WindowsProxyProvider(); +			virtual HostAddressPort getHTTPConnectProxy() const; +			virtual HostAddressPort getSOCKS5Proxy() const; +		private: +			HostAddressPort getAsHostAddressPort(std::string proxy); +			bool proxyEnabled(HKEY hKey) const; +			HostAddressPort socksProxy; +			HostAddressPort httpProxy; +	}; +} diff --git a/Swiften/QA/ProxyProviderTest/.gitignore b/Swiften/QA/ProxyProviderTest/.gitignore new file mode 100644 index 0000000..9d4b9b8 --- /dev/null +++ b/Swiften/QA/ProxyProviderTest/.gitignore @@ -0,0 +1 @@ +ProxyProviderTest diff --git a/Swiften/QA/ProxyProviderTest/ProxyProviderTest.cpp b/Swiften/QA/ProxyProviderTest/ProxyProviderTest.cpp new file mode 100644 index 0000000..ddaee01 --- /dev/null +++ b/Swiften/QA/ProxyProviderTest/ProxyProviderTest.cpp @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010 Thilo Cestonaro + * Licensed under the BSD License. + * See Documentation/Licenses/BSD.txt for more information. + */ + +#include <iostream> + +#include <Swiften/Network/PlatformProxyProvider.h> +#include <Swiften/Base/foreach.h> + +using namespace Swift; + +int main(void) +{ +	int ret = 0; +	HostAddressPort hap; +	 +	std::cout << "constructing PlatfromProxyProvider instance ..." << std::endl; +	PlatformProxyProvider ppp; + +	hap = ppp.getSOCKS5Proxy(); +	std::cout << "SOCKS5 Proxy configured: " << hap.isValid() << std::endl; +	if(hap.isValid()) { +		std::cout << "SOCKS5 Proxy: " << hap.getAddress().toString() << ":" << hap.getPort() << std::endl; +	} + +	hap = ppp.getHTTPConnectProxy(); +	std::cout << "HTTPConnect Proxy configured: " << hap.isValid() << std::endl; +	if(hap.isValid()) { +		std::cout << "HTTPConnect Proxy: " << hap.getAddress().toString() << ":" << hap.getPort() << std::endl; +	} + +	return ret; +} diff --git a/Swiften/QA/ProxyProviderTest/SConscript b/Swiften/QA/ProxyProviderTest/SConscript new file mode 100644 index 0000000..e9c5139 --- /dev/null +++ b/Swiften/QA/ProxyProviderTest/SConscript @@ -0,0 +1,11 @@ +import os + +Import("env") + +myenv = env.Clone() +myenv.MergeFlags(myenv["SWIFTEN_FLAGS"]) +myenv.MergeFlags(myenv["BOOST_FLAGS"]) + +myenv.Program("ProxyProviderTest", [ +		"ProxyProviderTest.cpp", +	]) diff --git a/Swiften/QA/SConscript b/Swiften/QA/SConscript index 25ba814..41d7206 100644 --- a/Swiften/QA/SConscript +++ b/Swiften/QA/SConscript @@ -8,4 +8,5 @@ SConscript(dirs = [  		"StorageTest",  		"TLSTest",  		"ScriptedTests", +		"ProxyProviderTest",  	]) diff --git a/Swiften/SConscript b/Swiften/SConscript index 57c95fc..0a229e8 100644 --- a/Swiften/SConscript +++ b/Swiften/SConscript @@ -159,6 +159,9 @@ if env["SCONS_STAGE"] == "build" :  			"StringCodecs/Hexify.cpp",  		] +	if myenv["PLATFORM"] != "darwin" and myenv["PLATFORM"] != "win32" and myenv.get("HAVE_GCONF", 0) : +		env.MergeFlags(env["GCONF_FLAGS"]) +  	SConscript(dirs = [  			"Avatars",  			"Base", @@ -333,6 +336,8 @@ if env["SCONS_STAGE"] == "build" :  					continue  				if file.startswith("CAres") or file.startswith("LibXML") or file.startswith("Expat") or file.startswith("foreach") or file.startswith("Log.h") or file.startswith("format.h") :  					continue +				if file.find("ProxyProvider") != -1 : +					continue  				swiften_header += "#include <" + include + ">\n"  				swiften_includes.append(include)  	for file in ["EventLoop/SimpleEventLoop.h"] : | 
 Swift
 Swift