summaryrefslogtreecommitdiff
path: root/indra/llmessage/llsocks5.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llmessage/llsocks5.h')
-rw-r--r--indra/llmessage/llsocks5.h243
1 files changed, 243 insertions, 0 deletions
diff --git a/indra/llmessage/llsocks5.h b/indra/llmessage/llsocks5.h
new file mode 100644
index 0000000000..83e311a962
--- /dev/null
+++ b/indra/llmessage/llsocks5.h
@@ -0,0 +1,243 @@
+/**
+ * @file llsocks5.h
+ * @brief Socks 5 implementation
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ *
+ * Copyright (c) 2001-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab. Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_SOCKS5_H
+#define LL_SOCKS5_H
+
+#include "llhost.h"
+#include "llmemory.h"
+#include "llsingleton.h"
+#include <string>
+
+// Error codes returned from the StartProxy method
+
+#define SOCKS_OK 0
+#define SOCKS_CONNECT_ERROR -1
+#define SOCKS_NOT_PERMITTED -2
+#define SOCKS_NOT_ACCEPTABLE -3
+#define SOCKS_AUTH_FAIL -4
+#define SOCKS_UDP_FWD_NOT_GRANTED -5
+#define SOCKS_HOST_CONNECT_FAILED -6
+
+#ifndef MAXHOSTNAMELEN
+#define MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */
+#endif
+
+#define SOCKS_VERSION 0x05 // we are using socks 5
+
+// socks 5 address/hostname types
+#define ADDRESS_IPV4 0x01
+#define ADDRESS_HOSTNAME 0x03
+#define ADDRESS_IPV6 0x04
+
+// Lets just use our own ipv4 struct rather than dragging in system
+// specific headers
+union ipv4_address_t {
+ unsigned char octects[4];
+ U32 addr32;
+};
+
+// Socks 5 control channel commands
+#define COMMAND_TCP_STREAM 0x01
+#define COMMAND_TCP_BIND 0x02
+#define COMMAND_UDP_ASSOCIATE 0x03
+
+// Socks 5 command replys
+#define REPLY_REQUEST_GRANTED 0x00
+#define REPLY_GENERAL_FAIL 0x01
+#define REPLY_RULESET_FAIL 0x02
+#define REPLY_NETWORK_UNREACHABLE 0x03
+#define REPLY_HOST_UNREACHABLE 0x04
+#define REPLY_CONNECTION_REFUSED 0x05
+#define REPLY_TTL_EXPIRED 0x06
+#define REPLY_PROTOCOL_ERROR 0x07
+#define REPLY_TYPE_NOT_SUPPORTED 0x08
+
+#define FIELD_RESERVED 0x00
+
+// The standard socks5 request packet
+// Push current alignment to stack and set alignment to 1 byte boundary
+// This enabled us to use structs directly to set up and receive network packets
+// into the correct fields, without fear of boundary alignment causing issues
+#pragma pack(push,1)
+
+// Socks5 command packet
+struct socks_command_request_t {
+ unsigned char version;
+ unsigned char command;
+ unsigned char flag;
+ unsigned char atype;
+ U32 address;
+ U16 port;
+};
+
+// Standard socks5 reply packet
+struct socks_command_response_t {
+ unsigned char version;
+ unsigned char reply;
+ unsigned char flag;
+ unsigned char atype;
+ unsigned char add_bytes[4];
+ U16 port;
+};
+
+#define AUTH_NOT_ACCEPTABLE 0xFF // reply if prefered methods are not avaiable
+#define AUTH_SUCCESS 0x00 // reply if authentication successfull
+
+// socks 5 authentication request, stating which methods the client supports
+struct socks_auth_request_t {
+ unsigned char version;
+ unsigned char num_methods;
+ unsigned char methods; // We are only using a single method currently
+};
+
+// socks 5 authentication response packet, stating server prefered method
+struct socks_auth_response_t {
+ unsigned char version;
+ unsigned char method;
+};
+
+// socks 5 password reply packet
+struct authmethod_password_reply_t {
+ unsigned char version;
+ unsigned char status;
+};
+
+// socks 5 UDP packet header
+struct proxywrap_t {
+ U16 rsv;
+ U8 frag;
+ U8 atype;
+ U32 addr;
+ U16 port;
+};
+
+#pragma pack(pop) /* restore original alignment from stack */
+
+
+// Currently selected http proxy type
+enum LLHttpProxyType
+{
+ LLPROXY_SOCKS = 0,
+ LLPROXY_HTTP = 1
+};
+
+// Auth types
+enum LLSocks5AuthType
+{
+ METHOD_NOAUTH = 0x00, // Client supports no auth
+ METHOD_GSSAPI = 0x01, // Client supports GSSAPI (Not currently supported)
+ METHOD_PASSWORD = 0x02 // Client supports username/password
+};
+
+class LLSocks: public LLSingleton<LLSocks>
+{
+public:
+ LLSocks();
+
+ // Start a connection to the socks 5 proxy
+ int startProxy(std::string host,U32 port);
+ int startProxy(LLHost proxy,U32 messagePort);
+
+ // Disconnect and clean up any connection to the socks 5 proxy
+ void stopProxy();
+
+ // Set up to use Password auth when connecting to the socks proxy
+ void setAuthPassword(std::string username,std::string password);
+
+ // Set up to use No Auth when connecting to the socks proxy;
+ void setAuthNone();
+
+ // get the currently selected auth method
+ LLSocks5AuthType getSelectedAuthMethod() { return mAuthMethodSelected; };
+
+ // static check for enabled status for UDP packets
+ static bool isEnabled(){return sUdpProxyEnabled;};
+
+ // static check for enabled status for http packets
+ static bool isHttpProxyEnabled(){return sHttpProxyEnabled;};
+
+ // Proxy http packets via httpHost, which can be a Socks5 or a http proxy
+ // as specified in type
+ void EnableHttpProxy(LLHost httpHost,LLHttpProxyType type);
+
+ // Stop proxying http packets
+ void DisableHttpProxy() {sHttpProxyEnabled = false;};
+
+ // get the UDP proxy address and port
+ LLHost getUDPProxy(){return mUDPProxy;};
+
+ // get the socks 5 TCP control channel address and port
+ LLHost getTCPProxy(){return mTCPProxy;};
+
+ //get the http proxy address and port
+ LLHost getHTTPProxy(){return mHTTPProxy;};
+
+ // get the currently selected http proxy type
+ LLHttpProxyType getHttpProxyType(){return mProxyType;};
+
+ //Get the username password in a curl compatible format
+ std::string getProxyUserPwd(){ return (mSocksUsername + ":" + mSocksPassword);};
+
+private:
+
+ // Open a communication channel to the socks5 proxy proxy, at port messagePort
+ int proxyHandshake(LLHost proxy,U32 messagePort);
+
+ // socket handle to proxy tcp control channel
+ S32 hProxyControlChannel;
+
+ // is the UDP proxy enabled
+ static bool sUdpProxyEnabled;
+ // is the http proxy enabled
+ static bool sHttpProxyEnabled;
+
+ // currently selected http proxy type
+ LLHttpProxyType mProxyType;
+
+ // UDP proxy address and port
+ LLHost mUDPProxy;
+ // TCP Proxy control channel address and port
+ LLHost mTCPProxy;
+ // HTTP proxy address and port
+ LLHost mHTTPProxy;
+
+ // socks 5 auth method selected
+ LLSocks5AuthType mAuthMethodSelected;
+
+ // socks 5 username
+ std::string mSocksUsername;
+ // socks 5 password
+ std::string mSocksPassword;
+};
+
+#endif