Merged STORM-1112 with viewer-development. Fixed license in socks5.cpp and socks5.h.
commit
7cb18f5318
|
|
@ -76,6 +76,7 @@ set(llmessage_SOURCE_FILES
|
|||
llsdrpcserver.cpp
|
||||
llservicebuilder.cpp
|
||||
llservice.cpp
|
||||
llsocks5.cpp
|
||||
llstoredmessage.cpp
|
||||
lltemplatemessagebuilder.cpp
|
||||
lltemplatemessagedispatcher.cpp
|
||||
|
|
@ -174,6 +175,7 @@ set(llmessage_HEADER_FILES
|
|||
llsdrpcserver.h
|
||||
llservice.h
|
||||
llservicebuilder.h
|
||||
llsocks5.h
|
||||
llstoredmessage.h
|
||||
lltaskname.h
|
||||
llteleportflags.h
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@
|
|||
#include "llthread.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
#include "llsocks5.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
The trick to getting curl to do keep-alives is to reuse the
|
||||
|
|
@ -355,6 +357,27 @@ LLCurl::Easy* LLCurl::Easy::getEasy()
|
|||
// multi handles cache if they are added to one.
|
||||
CURLcode result = curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
|
||||
check_curl_code(result);
|
||||
|
||||
//Set the CURL options for either Socks or HTTP proxy
|
||||
if (LLSocks::getInstance()->isHttpProxyEnabled())
|
||||
{
|
||||
std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString();
|
||||
U16 port = LLSocks::getInstance()->getHTTPProxy().getPort();
|
||||
curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXY,address.c_str());
|
||||
curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYPORT,port);
|
||||
if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS)
|
||||
{
|
||||
curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
|
||||
if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD)
|
||||
{
|
||||
curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYUSERPWD,LLSocks::getInstance()->getProxyUserPwd().c_str());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
}
|
||||
}
|
||||
|
||||
++gCurlEasyCount;
|
||||
return easy;
|
||||
|
|
@ -534,6 +557,26 @@ void LLCurl::Easy::prepRequest(const std::string& url,
|
|||
//setopt(CURLOPT_VERBOSE, 1); // usefull for debugging
|
||||
setopt(CURLOPT_NOSIGNAL, 1);
|
||||
|
||||
if (LLSocks::getInstance()->isHttpProxyEnabled())
|
||||
{
|
||||
std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString();
|
||||
U16 port = LLSocks::getInstance()->getHTTPProxy().getPort();
|
||||
setoptString(CURLOPT_PROXY, address.c_str());
|
||||
setopt(CURLOPT_PROXYPORT, port);
|
||||
if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS)
|
||||
{
|
||||
setopt(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
|
||||
if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD)
|
||||
{
|
||||
setoptString(CURLOPT_PROXYUSERPWD,LLSocks::getInstance()->getProxyUserPwd());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setopt(CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
}
|
||||
}
|
||||
|
||||
mOutput.reset(new LLBufferArray);
|
||||
setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback);
|
||||
setopt(CURLOPT_WRITEDATA, (void*)this);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,17 @@
|
|||
#include "llrand.h"
|
||||
#include "u64.h"
|
||||
|
||||
#include "llsocks5.h"
|
||||
#include "message.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
#include <winsock2.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
LLPacketRing::LLPacketRing () :
|
||||
mUseInThrottle(FALSE),
|
||||
|
|
@ -216,8 +227,31 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap)
|
|||
else
|
||||
{
|
||||
// no delay, pull straight from net
|
||||
if (LLSocks::isEnabled())
|
||||
{
|
||||
U8 buffer[MAX_BUFFER_SIZE];
|
||||
packet_size = receive_packet(socket, (char*)buffer);
|
||||
|
||||
if (packet_size > 10)
|
||||
{
|
||||
memcpy(datap,buffer+10,packet_size-10);
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_size=0;
|
||||
}
|
||||
|
||||
proxywrap_t * header;
|
||||
header = (proxywrap_t *)buffer;
|
||||
mLastSender.setAddress(header->addr);
|
||||
mLastSender.setPort(ntohs(header->port));
|
||||
}
|
||||
else
|
||||
{
|
||||
packet_size = receive_packet(socket, datap);
|
||||
mLastSender = ::get_sender();
|
||||
}
|
||||
|
||||
mLastReceivingIF = ::get_receiving_interface();
|
||||
|
||||
if (packet_size) // did we actually get a packet?
|
||||
|
|
@ -243,7 +277,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
|
|||
BOOL status = TRUE;
|
||||
if (!mUseOutThrottle)
|
||||
{
|
||||
return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort() );
|
||||
return doSendPacket(h_socket, send_buffer, buf_size, host );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -264,7 +298,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
|
|||
mOutBufferLength -= packetp->getSize();
|
||||
packet_size = packetp->getSize();
|
||||
|
||||
status = send_packet(h_socket, packetp->getData(), packet_size, packetp->getHost().getAddress(), packetp->getHost().getPort());
|
||||
status = doSendPacket(h_socket, packetp->getData(), packet_size, packetp->getHost());
|
||||
|
||||
delete packetp;
|
||||
// Update the throttle
|
||||
|
|
@ -273,7 +307,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
|
|||
else
|
||||
{
|
||||
// If the queue's empty, we can just send this packet right away.
|
||||
status = send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort() );
|
||||
status = doSendPacket(h_socket, send_buffer, buf_size, host );
|
||||
packet_size = buf_size;
|
||||
|
||||
// Update the throttle
|
||||
|
|
@ -311,3 +345,23 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
BOOL LLPacketRing::doSendPacket(int h_socket, const char * send_buffer, S32 buf_size, LLHost host)
|
||||
{
|
||||
|
||||
if (!LLSocks::isEnabled())
|
||||
{
|
||||
return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort());
|
||||
}
|
||||
|
||||
proxywrap_t *socks_header = (proxywrap_t *)&mProxyWrappedSendBuffer;
|
||||
socks_header->rsv = 0;
|
||||
socks_header->addr = host.getAddress();
|
||||
socks_header->port = htons(host.getPort());
|
||||
socks_header->atype = ADDRESS_IPV4;
|
||||
socks_header->frag = 0;
|
||||
|
||||
memcpy(mProxyWrappedSendBuffer+10, send_buffer, buf_size);
|
||||
|
||||
return send_packet(h_socket,(const char*) mProxyWrappedSendBuffer, buf_size+10, LLSocks::getInstance()->getUDPProxy().getAddress(), LLSocks::getInstance()->getUDPProxy().getPort());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ protected:
|
|||
|
||||
LLHost mLastSender;
|
||||
LLHost mLastReceivingIF;
|
||||
|
||||
BOOL doSendPacket(int h_socket, const char * send_buffer, S32 buf_size, LLHost host);
|
||||
U8 mProxyWrappedSendBuffer[NET_BUFFER_SIZE];
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,218 @@
|
|||
/**
|
||||
* @file llsocks5.cpp
|
||||
* @brief Socks 5 implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "net.h"
|
||||
#include "llhost.h"
|
||||
#include "message.h"
|
||||
#include "llsocks5.h"
|
||||
|
||||
// Static class variable instances
|
||||
|
||||
// We want this to be static to avoid excessive indirection on every
|
||||
// incomming packet just to do a simple bool test. The getter for this
|
||||
// member is also static
|
||||
bool LLSocks::sUdpProxyEnabled;
|
||||
bool LLSocks::sHttpProxyEnabled;
|
||||
|
||||
LLSocks::LLSocks()
|
||||
{
|
||||
sUdpProxyEnabled = false;
|
||||
sHttpProxyEnabled = false;
|
||||
hProxyControlChannel = 0;
|
||||
mProxyType = LLPROXY_SOCKS;
|
||||
}
|
||||
|
||||
// Perform a Socks5 authentication and UDP assioacation to the proxy
|
||||
// specified by proxy, and assiocate UDP port message_port
|
||||
int LLSocks::proxyHandshake(LLHost proxy, U32 message_port)
|
||||
{
|
||||
int result;
|
||||
|
||||
/* Socks 5 Auth request */
|
||||
socks_auth_request_t socks_auth_request;
|
||||
socks_auth_response_t socks_auth_response;
|
||||
|
||||
socks_auth_request.version = SOCKS_VERSION; // Socks version 5
|
||||
socks_auth_request.num_methods = 1; // Sending 1 method
|
||||
socks_auth_request.methods = mAuthMethodSelected; // send only the selected metho
|
||||
|
||||
result = tcp_handshake(hProxyControlChannel, (char*)&socks_auth_request, sizeof(socks_auth_request_t), (char*)&socks_auth_response, sizeof(socks_auth_response_t));
|
||||
if (result != 0)
|
||||
{
|
||||
llwarns << "Socks authentication request failed, error on TCP control channel : " << result << llendl;
|
||||
stopProxy();
|
||||
return SOCKS_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE)
|
||||
{
|
||||
llwarns << "Socks5 server refused all our authentication methods" << llendl;
|
||||
stopProxy();
|
||||
return SOCKS_NOT_ACCEPTABLE;
|
||||
}
|
||||
|
||||
// SOCKS5 USERNAME/PASSWORD authentication
|
||||
if (socks_auth_response.method == METHOD_PASSWORD)
|
||||
{
|
||||
// The server has requested a username/password combination
|
||||
U32 request_size = mSocksUsername.size() + mSocksPassword.size() + 3;
|
||||
char * password_auth = (char *)malloc(request_size);
|
||||
password_auth[0] = 0x01;
|
||||
password_auth[1] = mSocksUsername.size();
|
||||
memcpy(&password_auth[2],mSocksUsername.c_str(), mSocksUsername.size());
|
||||
password_auth[mSocksUsername.size()+2] = mSocksPassword.size();
|
||||
memcpy(&password_auth[mSocksUsername.size()+3], mSocksPassword.c_str(), mSocksPassword.size());
|
||||
|
||||
authmethod_password_reply_t password_reply;
|
||||
|
||||
result = tcp_handshake(hProxyControlChannel, password_auth, request_size, (char*)&password_reply, sizeof(authmethod_password_reply_t));
|
||||
free (password_auth);
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
llwarns << "Socks authentication failed, error on TCP control channel : " << result << llendl;
|
||||
stopProxy();
|
||||
return SOCKS_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
if (password_reply.status != AUTH_SUCCESS)
|
||||
{
|
||||
llwarns << "Socks authentication failed" << llendl;
|
||||
stopProxy();
|
||||
return SOCKS_AUTH_FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* SOCKS5 connect request */
|
||||
|
||||
socks_command_request_t connect_request;
|
||||
socks_command_response_t connect_reply;
|
||||
|
||||
connect_request.version = SOCKS_VERSION; //Socks V5
|
||||
connect_request.command = COMMAND_UDP_ASSOCIATE; // Associate UDP
|
||||
connect_request.flag = FIELD_RESERVED;
|
||||
connect_request.atype = ADDRESS_IPV4;
|
||||
connect_request.address = 0; // 0.0.0.0 We are not fussy about address
|
||||
// UDP is promiscious receive for our protocol
|
||||
connect_request.port = 0; // Port must be 0 if you ever want to connect via NAT and your router does port rewrite for you
|
||||
|
||||
result = tcp_handshake(hProxyControlChannel, (char*)&connect_request, sizeof(socks_command_request_t), (char*)&connect_reply, sizeof(socks_command_response_t));
|
||||
if (result != 0)
|
||||
{
|
||||
llwarns << "Socks connect request failed, error on TCP control channel : " << result << llendl;
|
||||
stopProxy();
|
||||
return SOCKS_CONNECT_ERROR;
|
||||
}
|
||||
|
||||
if (connect_reply.reply != REPLY_REQUEST_GRANTED)
|
||||
{
|
||||
//Something went wrong
|
||||
llwarns << "Connection to SOCKS5 server failed, UDP forward request not granted" << llendl;
|
||||
stopProxy();
|
||||
return SOCKS_UDP_FWD_NOT_GRANTED;
|
||||
}
|
||||
|
||||
mUDPProxy.setPort(ntohs(connect_reply.port)); // reply port is in network byte order
|
||||
mUDPProxy.setAddress(proxy.getAddress());
|
||||
// All good now we have been given the UDP port to send requests that need forwarding.
|
||||
llinfos << "Socks 5 UDP proxy connected on " << mUDPProxy << llendl;
|
||||
return SOCKS_OK;
|
||||
}
|
||||
|
||||
int LLSocks::startProxy(LLHost proxy, U32 message_port)
|
||||
{
|
||||
int status;
|
||||
|
||||
mTCPProxy = proxy;
|
||||
|
||||
if (hProxyControlChannel)
|
||||
{
|
||||
tcp_close_channel(hProxyControlChannel);
|
||||
hProxyControlChannel=0;
|
||||
}
|
||||
|
||||
hProxyControlChannel = tcp_open_channel(proxy);
|
||||
if (hProxyControlChannel == -1)
|
||||
{
|
||||
return SOCKS_HOST_CONNECT_FAILED;
|
||||
}
|
||||
|
||||
status = proxyHandshake(proxy, message_port);
|
||||
if (status == SOCKS_OK)
|
||||
{
|
||||
sUdpProxyEnabled=true;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
int LLSocks::startProxy(std::string host, U32 port)
|
||||
{
|
||||
mTCPProxy.setHostByName(host);
|
||||
mTCPProxy.setPort(port);
|
||||
return startProxy(mTCPProxy, (U32)gMessageSystem->mPort);
|
||||
}
|
||||
|
||||
void LLSocks::stopProxy()
|
||||
{
|
||||
sUdpProxyEnabled = false;
|
||||
|
||||
// If the Socks proxy is requested to stop and we are using that for http as well
|
||||
// then we must shut down any http proxy operations. But it is allowable if web
|
||||
// proxy is being used to continue proxying http.
|
||||
|
||||
if(LLPROXY_SOCKS == mProxyType)
|
||||
{
|
||||
sHttpProxyEnabled = false;
|
||||
}
|
||||
|
||||
if (hProxyControlChannel)
|
||||
{
|
||||
tcp_close_channel(hProxyControlChannel);
|
||||
hProxyControlChannel=0;
|
||||
}
|
||||
}
|
||||
|
||||
void LLSocks::setAuthNone()
|
||||
{
|
||||
mAuthMethodSelected = METHOD_NOAUTH;
|
||||
}
|
||||
|
||||
void LLSocks::setAuthPassword(std::string username, std::string password)
|
||||
{
|
||||
mAuthMethodSelected = METHOD_PASSWORD;
|
||||
mSocksUsername = username;
|
||||
mSocksPassword = password;
|
||||
}
|
||||
|
||||
void LLSocks::EnableHttpProxy(LLHost httpHost, LLHttpProxyType type)
|
||||
{
|
||||
sHttpProxyEnabled = true;
|
||||
mHTTPProxy = httpHost;
|
||||
mProxyType = type;
|
||||
}
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
/**
|
||||
* @file llsocks5.h
|
||||
* @brief Socks 5 implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2011&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2011, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/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
|
||||
|
|
@ -50,6 +50,7 @@
|
|||
#include "lltimer.h"
|
||||
#include "indra_constants.h"
|
||||
|
||||
#include "llsocks5.h"
|
||||
|
||||
// Globals
|
||||
#if LL_WINDOWS
|
||||
|
|
@ -189,6 +190,90 @@ U32 ip_string_to_u32(const char* ip_string)
|
|||
|
||||
#if LL_WINDOWS
|
||||
|
||||
int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen)
|
||||
{
|
||||
int result;
|
||||
result = send(handle, dataout, outlen, 0);
|
||||
if (result != outlen)
|
||||
{
|
||||
S32 err = WSAGetLastError();
|
||||
llwarns << "Error sending data to proxy control channel, number of bytes sent were " << result << " error code was " << err << llendl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
result = recv(handle, datain, maxinlen, 0);
|
||||
if (result != maxinlen)
|
||||
{
|
||||
S32 err = WSAGetLastError();
|
||||
llwarns << "Error receiving data from proxy control channel, number of bytes received were " << result << " error code was " << err << llendl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
S32 tcp_open_channel(LLHost host)
|
||||
{
|
||||
// Open a TCP channel
|
||||
// Jump through some hoops to ensure that if the request hosts is down
|
||||
// or not reachable connect() does not block
|
||||
|
||||
S32 handle;
|
||||
handle = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (!handle)
|
||||
{
|
||||
llwarns << "Error opening TCP control socket, socket() returned " << handle << llendl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_in address;
|
||||
address.sin_port = htons(host.getPort());
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_addr.s_addr = host.getAddress();
|
||||
|
||||
// Non blocking
|
||||
WSAEVENT hEvent=WSACreateEvent();
|
||||
WSAEventSelect(handle, hEvent, FD_CONNECT) ;
|
||||
connect(handle, (struct sockaddr*)&address, sizeof(address)) ;
|
||||
// Wait fot 5 seconds, if we can't get a TCP channel open in this
|
||||
// time frame then there is something badly wrong.
|
||||
WaitForSingleObject(hEvent, 1000*5); // 5 seconds time out
|
||||
|
||||
WSANETWORKEVENTS netevents;
|
||||
WSAEnumNetworkEvents(handle,hEvent,&netevents);
|
||||
|
||||
// Check the async event status to see if we connected
|
||||
if ((netevents.lNetworkEvents & FD_CONNECT) == FD_CONNECT)
|
||||
{
|
||||
if (netevents.iErrorCode[FD_CONNECT_BIT] != 0)
|
||||
{
|
||||
llwarns << "Unable to open TCP channel, WSA returned an error code of " << netevents.iErrorCode[FD_CONNECT_BIT] << llendl;
|
||||
WSACloseEvent(hEvent);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Now we are connected disable non blocking
|
||||
// we don't need support an async interface as
|
||||
// currently our only consumer (socks5) will make one round
|
||||
// of packets then just hold the connection open
|
||||
WSAEventSelect(handle, hEvent, NULL) ;
|
||||
unsigned long NonBlock = 0;
|
||||
ioctlsocket(handle, FIONBIO, &NonBlock);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
llwarns << "Unable to open TCP channel, Timeout is the host up?" << netevents.iErrorCode[FD_CONNECT_BIT] << llendl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void tcp_close_channel(S32 handle)
|
||||
{
|
||||
llinfos << "Closing TCP channel" << llendl;
|
||||
shutdown(handle, SD_BOTH);
|
||||
closesocket(handle);
|
||||
}
|
||||
|
||||
S32 start_net(S32& socket_out, int& nPort)
|
||||
{
|
||||
// Create socket, make non-blocking
|
||||
|
|
@ -385,6 +470,77 @@ BOOL send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, i
|
|||
|
||||
#else
|
||||
|
||||
|
||||
int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen)
|
||||
{
|
||||
if (send(handle, dataout, outlen, 0) != outlen)
|
||||
{
|
||||
llwarns << "Error sending data to proxy control channel" << llendl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (recv(handle, datain, maxinlen, 0) != maxinlen)
|
||||
{
|
||||
llwarns << "Error receiving data to proxy control channel" << llendl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
S32 tcp_open_channel(LLHost host)
|
||||
{
|
||||
S32 handle;
|
||||
handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (!handle)
|
||||
{
|
||||
llwarns << "Error opening TCP control socket, socket() returned " << handle << llendl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct sockaddr_in address;
|
||||
address.sin_port = htons(host.getPort());
|
||||
address.sin_family = AF_INET;
|
||||
address.sin_addr.s_addr = host.getAddress();
|
||||
|
||||
// Set the socket to non blocking for the connect()
|
||||
int flags = fcntl(handle, F_GETFL, 0);
|
||||
fcntl(handle, F_SETFL, flags | O_NONBLOCK);
|
||||
|
||||
S32 error = connect(handle, (sockaddr*)&address, sizeof(address));
|
||||
if (error && (errno != EINPROGRESS))
|
||||
{
|
||||
llwarns << "Unable to open TCP channel, error code: " << errno << llendl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 5; // Maximum time to wait for the connect() to complete
|
||||
timeout.tv_usec = 0;
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(handle, &fds);
|
||||
|
||||
// See if we have connectde or time out after 5 seconds
|
||||
U32 rc = select(sizeof(fds)*8, NULL, &fds, NULL, &timeout);
|
||||
|
||||
if (rc != 1) // we require exactly one descriptor to be set
|
||||
{
|
||||
llwarns << "Unable to open TCP channel" << llendl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Return the socket to blocking operations
|
||||
fcntl(handle, F_SETFL, flags);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void tcp_close_channel(S32 handle)
|
||||
{
|
||||
close(handle);
|
||||
}
|
||||
|
||||
// Create socket, make non-blocking
|
||||
S32 start_net(S32& socket_out, int& nPort)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -52,6 +52,11 @@ U32 get_sender_ip(void);
|
|||
LLHost get_receiving_interface();
|
||||
U32 get_receiving_interface_ip(void);
|
||||
|
||||
// Some helpful tcp functions added for the socks 5 proxy support
|
||||
S32 tcp_open_channel(LLHost host); // Open a tcp channel to a given host
|
||||
void tcp_close_channel(S32 handle); // Close an open tcp channel
|
||||
int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen); // Do a TCP data handshake
|
||||
|
||||
const char* u32_to_ip_string(U32 ip); // Returns pointer to internal string buffer, "(bad IP addr)" on failure, cannot nest calls
|
||||
char* u32_to_ip_string(U32 ip, char *ip_string); // NULL on failure, ip_string on success, you must allocate at least MAXADDRSTR chars
|
||||
U32 ip_string_to_u32(const char* ip_string); // Wrapper for inet_addr()
|
||||
|
|
|
|||
|
|
@ -796,6 +796,83 @@
|
|||
<key>Value</key>
|
||||
<integer>5</integer>
|
||||
</map>
|
||||
<key>Socks5ProxyEnabled</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Use Socks5 Proxy</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>Socks5HttpProxyType</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Proxy type to use for HTTP operations</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>Socks</string>
|
||||
</map>
|
||||
<key>Socks5ProxyHost</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Socks 5 Proxy Host</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>64.79.219.97</string>
|
||||
</map>
|
||||
<key>Socks5ProxyPort</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Socks 5 Proxy Port</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>1080</integer>
|
||||
</map>
|
||||
<key>Socks5Username</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Socks 5 Username</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string></string>
|
||||
</map>
|
||||
<key>Socks5Password</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Socks 5 Password</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string></string>
|
||||
</map>
|
||||
<key>Socks5AuthType</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Selected Auth mechanism for Socks5</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>None</string>
|
||||
</map>
|
||||
<key>BuildAxisDeadZone0</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@
|
|||
#include "llviewermedia.h"
|
||||
#include "llpluginclassmedia.h"
|
||||
#include "llteleporthistorystorage.h"
|
||||
#include "llsocks5.h"
|
||||
|
||||
#include "lllogininstance.h" // to check if logged in yet
|
||||
#include "llsdserialize.h"
|
||||
|
|
@ -342,6 +343,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
|
|||
mCommitCallbackRegistrar.add("Pref.getUIColor", boost::bind(&LLFloaterPreference::getUIColor, this ,_1, _2));
|
||||
mCommitCallbackRegistrar.add("Pref.MaturitySettings", boost::bind(&LLFloaterPreference::onChangeMaturity, this));
|
||||
mCommitCallbackRegistrar.add("Pref.BlockList", boost::bind(&LLFloaterPreference::onClickBlockList, this));
|
||||
mCommitCallbackRegistrar.add("Pref.Proxy", boost::bind(&LLFloaterPreference::onClickProxySettings, this));
|
||||
|
||||
sSkin = gSavedSettings.getString("SkinCurrent");
|
||||
|
||||
|
|
@ -615,6 +617,12 @@ void LLFloaterPreference::cancel()
|
|||
updateDoubleClickControls();
|
||||
mDoubleClickActionDirty = false;
|
||||
}
|
||||
LLFloaterPreferenceProxy * advanced_socks_settings = LLFloaterReg::findTypedInstance<LLFloaterPreferenceProxy>("prefs_socks5_advanced");
|
||||
if(advanced_socks_settings)
|
||||
{
|
||||
advanced_socks_settings->cancel();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLFloaterPreference::onOpen(const LLSD& key)
|
||||
|
|
@ -1535,6 +1543,11 @@ void LLFloaterPreference::updateDoubleClickSettings()
|
|||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreference::onClickProxySettings()
|
||||
{
|
||||
LLFloaterReg::showInstance("prefs_proxy");
|
||||
}
|
||||
|
||||
void LLFloaterPreference::updateDoubleClickControls()
|
||||
{
|
||||
// check is one of double-click actions settings enabled
|
||||
|
|
@ -1902,3 +1915,161 @@ void LLPanelPreferenceGraphics::setHardwareDefaults()
|
|||
resetDirtyChilds();
|
||||
LLPanelPreference::setHardwareDefaults();
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
||||
LLFloaterPreferenceProxy::LLFloaterPreferenceProxy(const LLSD& key)
|
||||
: LLFloater(key),
|
||||
mSocksSettingsDirty(false)
|
||||
{
|
||||
mCommitCallbackRegistrar.add("Proxy.OK", boost::bind(&LLFloaterPreferenceProxy::onBtnOk, this));
|
||||
mCommitCallbackRegistrar.add("Proxy.Cancel", boost::bind(&LLFloaterPreferenceProxy::onBtnCancel, this));
|
||||
mCommitCallbackRegistrar.add("Proxy.Change", boost::bind(&LLFloaterPreferenceProxy::onChangeSocksSettings, this));
|
||||
}
|
||||
|
||||
LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy()
|
||||
{
|
||||
}
|
||||
|
||||
BOOL LLFloaterPreferenceProxy::postBuild()
|
||||
{
|
||||
LLLineEditor* edit = getChild<LLLineEditor>("socks_password_editor");
|
||||
if (edit) edit->setDrawAsterixes(TRUE);
|
||||
|
||||
LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type");
|
||||
if(socksAuth->getSelectedValue().asString() == "None")
|
||||
{
|
||||
getChild<LLLineEditor>("socks5_username")->setEnabled(false);
|
||||
getChild<LLLineEditor>("socks5_password")->setEnabled(false);
|
||||
}
|
||||
|
||||
center();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceProxy::onOpen(const LLSD& key)
|
||||
{
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceProxy::onClose(bool app_quitting)
|
||||
{
|
||||
if(mSocksSettingsDirty)
|
||||
{
|
||||
|
||||
// If the user plays with the Socks proxy settings after login, its only fair we let them know
|
||||
// it will not be updated untill next restart.
|
||||
if(LLStartUp::getStartupState()>STATE_LOGIN_WAIT)
|
||||
{
|
||||
if(this->mSocksSettingsDirty == true )
|
||||
{
|
||||
LLNotifications::instance().add("ChangeSocks5Settings",LLSD(),LLSD());
|
||||
mSocksSettingsDirty = false; // we have notified the user now be quiet again
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceProxy::saveSettings()
|
||||
{
|
||||
// Save the value of all controls in the hierarchy
|
||||
mSavedValues.clear();
|
||||
std::list<LLView*> view_stack;
|
||||
view_stack.push_back(this);
|
||||
while(!view_stack.empty())
|
||||
{
|
||||
// Process view on top of the stack
|
||||
LLView* curview = view_stack.front();
|
||||
view_stack.pop_front();
|
||||
|
||||
LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(curview);
|
||||
if (ctrl)
|
||||
{
|
||||
LLControlVariable* control = ctrl->getControlVariable();
|
||||
if (control)
|
||||
{
|
||||
mSavedValues[control] = control->getValue();
|
||||
}
|
||||
}
|
||||
|
||||
// Push children onto the end of the work stack
|
||||
for (child_list_t::const_iterator iter = curview->getChildList()->begin();
|
||||
iter != curview->getChildList()->end(); ++iter)
|
||||
{
|
||||
view_stack.push_back(*iter);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceProxy::onBtnOk()
|
||||
{
|
||||
// commit any outstanding text entry
|
||||
if (hasFocus())
|
||||
{
|
||||
LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
|
||||
if (cur_focus && cur_focus->acceptsTextInput())
|
||||
{
|
||||
cur_focus->onCommit();
|
||||
}
|
||||
}
|
||||
closeFloater(false);
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceProxy::onBtnCancel()
|
||||
{
|
||||
if (hasFocus())
|
||||
{
|
||||
LLUICtrl* cur_focus = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
|
||||
if (cur_focus && cur_focus->acceptsTextInput())
|
||||
{
|
||||
cur_focus->onCommit();
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
cancel();
|
||||
|
||||
}
|
||||
void LLFloaterPreferenceProxy::cancel()
|
||||
{
|
||||
|
||||
for (control_values_map_t::iterator iter = mSavedValues.begin();
|
||||
iter != mSavedValues.end(); ++iter)
|
||||
{
|
||||
LLControlVariable* control = iter->first;
|
||||
LLSD ctrl_value = iter->second;
|
||||
control->set(ctrl_value);
|
||||
}
|
||||
|
||||
closeFloater();
|
||||
}
|
||||
|
||||
void LLFloaterPreferenceProxy::onChangeSocksSettings()
|
||||
{
|
||||
mSocksSettingsDirty = true;
|
||||
|
||||
LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type");
|
||||
if(socksAuth->getSelectedValue().asString() == "None")
|
||||
{
|
||||
getChild<LLLineEditor>("socks5_username")->setEnabled(false);
|
||||
getChild<LLLineEditor>("socks5_password")->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLLineEditor>("socks5_username")->setEnabled(true);
|
||||
getChild<LLLineEditor>("socks5_password")->setEnabled(true);
|
||||
}
|
||||
|
||||
//Check for invalid states for the other http proxy radio
|
||||
LLRadioGroup* otherHttpProxy = getChild<LLRadioGroup>("other_http_proxy_selection");
|
||||
if( (otherHttpProxy->getSelectedValue().asString() == "Socks" &&
|
||||
getChild<LLCheckBoxCtrl>("socks_proxy_enabled")->get() == FALSE )||(
|
||||
otherHttpProxy->getSelectedValue().asString() == "Web" &&
|
||||
getChild<LLCheckBoxCtrl>("web_proxy_enabled")->get() == FALSE ) )
|
||||
{
|
||||
otherHttpProxy->selectFirstItem();
|
||||
}
|
||||
|
||||
};
|
||||
|
|
@ -155,6 +155,7 @@ public:
|
|||
void applyResolution();
|
||||
void onChangeMaturity();
|
||||
void onClickBlockList();
|
||||
void onClickProxySettings();
|
||||
void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
|
||||
void getUIColor(LLUICtrl* ctrl, const LLSD& param);
|
||||
|
||||
|
|
@ -228,4 +229,33 @@ protected:
|
|||
|
||||
};
|
||||
|
||||
class LLFloaterPreferenceProxy : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLFloaterPreferenceProxy(const LLSD& key);
|
||||
~LLFloaterPreferenceProxy();
|
||||
|
||||
/// show off our menu
|
||||
static void show();
|
||||
void cancel();
|
||||
|
||||
protected:
|
||||
BOOL postBuild();
|
||||
void onOpen(const LLSD& key);
|
||||
void onClose(bool app_quitting);
|
||||
void saveSettings();
|
||||
void onBtnOk();
|
||||
void onBtnCancel();
|
||||
|
||||
void onChangeSocksSettings();
|
||||
|
||||
private:
|
||||
|
||||
bool mSocksSettingsDirty;
|
||||
typedef std::map<LLControlVariable*, LLSD> control_values_map_t;
|
||||
control_values_map_t mSavedValues;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // LL_LLPREFERENCEFLOATER_H
|
||||
|
|
|
|||
|
|
@ -191,6 +191,8 @@
|
|||
#include "llevents.h"
|
||||
#include "llstartuplistener.h"
|
||||
|
||||
#include "llsocks5.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
#include "lldxhardware.h"
|
||||
#endif
|
||||
|
|
@ -390,7 +392,7 @@ bool idle_startup()
|
|||
gSavedSettings.setS32("LastGPUClass", LLFeatureManager::getInstance()->getGPUClass());
|
||||
|
||||
// load dynamic GPU/feature tables from website (S3)
|
||||
LLFeatureManager::getInstance()->fetchHTTPTables();
|
||||
//LLFeatureManager::getInstance()->fetchHTTPTables();
|
||||
|
||||
std::string xml_file = LLUI::locateSkin("xui_version.xml");
|
||||
LLXMLNodePtr root;
|
||||
|
|
@ -592,6 +594,15 @@ bool idle_startup()
|
|||
|
||||
LL_INFOS("AppInit") << "Message System Initialized." << LL_ENDL;
|
||||
|
||||
//-------------------------------------------------
|
||||
// Init the socks 5 proxy and open the control TCP
|
||||
// connection if the user is using SOCKS5
|
||||
// We need to do this early incase the user is using
|
||||
// socks for http so we get the login screen via socks
|
||||
//-------------------------------------------------
|
||||
|
||||
LLStartUp::handleSocksProxy(false);
|
||||
|
||||
//-------------------------------------------------
|
||||
// Init audio, which may be needed for prefs dialog
|
||||
// or audio cues in connection UI.
|
||||
|
|
@ -807,6 +818,27 @@ bool idle_startup()
|
|||
|
||||
if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())
|
||||
{
|
||||
// Post login screen, we should see if any settings have changed that may
|
||||
// require us to either start/stop or change the socks proxy. As various communications
|
||||
// past this point may require the proxy to be up.
|
||||
if ( gSavedSettings.getBOOL("Socks5ProxyEnabled") )
|
||||
{
|
||||
if (!LLStartUp::handleSocksProxy(true))
|
||||
{
|
||||
// Proxy start up failed, we should now bail the state machine
|
||||
// HandleSocksProxy() will have reported an error to the user
|
||||
// already, so we just go back to the login screen. The user
|
||||
// could then change the preferences to fix the issue.
|
||||
LLStartUp::setStartupState(STATE_LOGIN_SHOW);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSocks::getInstance()->stopProxy();
|
||||
}
|
||||
|
||||
|
||||
//reset the values that could have come in from a slurl
|
||||
// DEV-42215: Make sure they're not empty -- gUserCredential
|
||||
// might already have been set from gSavedSettings, and it's too bad
|
||||
|
|
@ -2728,6 +2760,95 @@ void LLStartUp::setStartSLURL(const LLSLURL& slurl)
|
|||
}
|
||||
}
|
||||
|
||||
bool LLStartUp::handleSocksProxy(bool reportOK)
|
||||
{
|
||||
std::string httpProxyType = gSavedSettings.getString("Socks5HttpProxyType");
|
||||
|
||||
// Determine the http proxy type (if any)
|
||||
if ((httpProxyType.compare("Web") == 0) && gSavedSettings.getBOOL("BrowserProxyEnabled"))
|
||||
{
|
||||
LLHost httpHost;
|
||||
httpHost.setHostByName(gSavedSettings.getString("BrowserProxyAddress"));
|
||||
httpHost.setPort(gSavedSettings.getS32("BrowserProxyPort"));
|
||||
LLSocks::getInstance()->EnableHttpProxy(httpHost,LLPROXY_HTTP);
|
||||
}
|
||||
else if ((httpProxyType.compare("Socks") == 0) && gSavedSettings.getBOOL("Socks5ProxyEnabled"))
|
||||
{
|
||||
LLHost httpHost;
|
||||
httpHost.setHostByName(gSavedSettings.getString("Socks5ProxyHost"));
|
||||
httpHost.setPort(gSavedSettings.getU32("Socks5ProxyPort"));
|
||||
LLSocks::getInstance()->EnableHttpProxy(httpHost,LLPROXY_SOCKS);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSocks::getInstance()->DisableHttpProxy();
|
||||
}
|
||||
|
||||
bool use_socks_proxy = gSavedSettings.getBOOL("Socks5ProxyEnabled");
|
||||
if (use_socks_proxy)
|
||||
{
|
||||
|
||||
// Determine and update LLSocks with the saved authentication system
|
||||
std::string auth_type = gSavedSettings.getString("Socks5AuthType");
|
||||
|
||||
if (auth_type.compare("None") == 0)
|
||||
{
|
||||
LLSocks::getInstance()->setAuthNone();
|
||||
}
|
||||
|
||||
if (auth_type.compare("UserPass") == 0)
|
||||
{
|
||||
LLSocks::getInstance()->setAuthPassword(gSavedSettings.getString("Socks5Username"),gSavedSettings.getString("Socks5Password"));
|
||||
}
|
||||
|
||||
// Start the proxy and check for errors
|
||||
int status = LLSocks::getInstance()->startProxy(gSavedSettings.getString("Socks5ProxyHost"), gSavedSettings.getU32("Socks5ProxyPort"));
|
||||
LLSD subs;
|
||||
LLSD payload;
|
||||
subs["HOST"] = gSavedSettings.getString("Socks5ProxyHost");
|
||||
subs["PORT"] = (S32)gSavedSettings.getU32("Socks5ProxyPort");
|
||||
|
||||
switch(status)
|
||||
{
|
||||
case SOCKS_OK:
|
||||
return true;
|
||||
break;
|
||||
|
||||
case SOCKS_CONNECT_ERROR: // TCP Fail
|
||||
LLNotifications::instance().add("SOCKS_CONNECT_ERROR", subs,payload);
|
||||
break;
|
||||
|
||||
case SOCKS_NOT_PERMITTED: // Socks5 server rule set refused connection
|
||||
LLNotifications::instance().add("SOCKS_NOT_PERMITTED", subs,payload);
|
||||
break;
|
||||
|
||||
case SOCKS_NOT_ACCEPTABLE: // Selected authentication is not acceptable to server
|
||||
LLNotifications::instance().add("SOCKS_NOT_ACCEPTABLE", subs,payload);
|
||||
break;
|
||||
|
||||
case SOCKS_AUTH_FAIL: // Authentication failed
|
||||
LLNotifications::instance().add("SOCKS_AUTH_FAIL", subs,payload);
|
||||
break;
|
||||
|
||||
case SOCKS_UDP_FWD_NOT_GRANTED: // UDP forward request failed
|
||||
LLNotifications::instance().add("SOCKS_UDP_FWD_NOT_GRANTED", subs,payload);
|
||||
break;
|
||||
|
||||
case SOCKS_HOST_CONNECT_FAILED: // Failed to open a TCP channel to the socks server
|
||||
LLNotifications::instance().add("SOCKS_HOST_CONNECT_FAILED", subs,payload);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LLSocks::getInstance()->stopProxy(); //ensure no UDP proxy is running and its all cleaned up
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool login_alert_done(const LLSD& notification, const LLSD& response)
|
||||
{
|
||||
LLPanelLogin::giveFocus();
|
||||
|
|
|
|||
|
|
@ -113,6 +113,8 @@ public:
|
|||
static void setStartSLURL(const LLSLURL& slurl);
|
||||
static LLSLURL& getStartSLURL() { return sStartSLURL; }
|
||||
|
||||
static bool handleSocksProxy(bool reportOK); //handle kicking the socks 5 proxy code at startup time
|
||||
|
||||
private:
|
||||
static LLSLURL sStartSLURL;
|
||||
|
||||
|
|
|
|||
|
|
@ -230,6 +230,7 @@ void LLViewerFloaterReg::registerFloaters()
|
|||
|
||||
LLFloaterReg::add("postcard", "floater_postcard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPostcard>);
|
||||
LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
|
||||
LLFloaterReg::add("prefs_proxy", "floater_preferences_proxy.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreferenceProxy>);
|
||||
LLFloaterReg::add("prefs_hardware_settings", "floater_hardware_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHardwareSettings>);
|
||||
LLFloaterReg::add("perm_prefs", "floater_perm_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPerms>);
|
||||
LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@
|
|||
#include "llappviewer.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
#include "llsocks5.h"
|
||||
|
||||
// Static instance of LLXMLRPCListener declared here so that every time we
|
||||
// bring in this code, we instantiate a listener. If we put the static
|
||||
// instance of LLXMLRPCListener into llxmlrpclistener.cpp, the linker would
|
||||
|
|
@ -307,16 +309,23 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip)
|
|||
}
|
||||
mErrorCert = NULL;
|
||||
|
||||
if (gSavedSettings.getBOOL("BrowserProxyEnabled"))
|
||||
if (LLSocks::getInstance()->isHttpProxyEnabled())
|
||||
{
|
||||
mProxyAddress = gSavedSettings.getString("BrowserProxyAddress");
|
||||
S32 port = gSavedSettings.getS32 ( "BrowserProxyPort" );
|
||||
|
||||
// tell curl about the settings
|
||||
mCurlRequest->setoptString(CURLOPT_PROXY, mProxyAddress);
|
||||
std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString();
|
||||
U16 port = LLSocks::getInstance()->getHTTPProxy().getPort();
|
||||
mCurlRequest->setoptString(CURLOPT_PROXY, address.c_str());
|
||||
mCurlRequest->setopt(CURLOPT_PROXYPORT, port);
|
||||
if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS)
|
||||
{
|
||||
mCurlRequest->setopt(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5);
|
||||
if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD)
|
||||
mCurlRequest->setoptString(CURLOPT_PROXYUSERPWD,LLSocks::getInstance()->getProxyUserPwd());
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurlRequest->setopt(CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
}
|
||||
}
|
||||
|
||||
// mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // usefull for debugging
|
||||
mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,274 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater
|
||||
legacy_header_height="18"
|
||||
height="490"
|
||||
layout="topleft"
|
||||
name="Socks5 Advanced Settings Floater"
|
||||
help_topic="hardware_settings_floater"
|
||||
title="Socks5 proxy advanced settings"
|
||||
width="385">
|
||||
<check_box
|
||||
control_name="BrowserProxyEnabled"
|
||||
top="30"
|
||||
enabled="true"
|
||||
follows="left|top"
|
||||
height="14"
|
||||
initial_value="false"
|
||||
commit_callback.function="Proxy.Change"
|
||||
label="Use HTTP Proxy for Web pages"
|
||||
left_delta="10"
|
||||
mouse_opaque="true"
|
||||
name="web_proxy_enabled"
|
||||
radio_style="false"
|
||||
width="400"
|
||||
top_pad="5" />
|
||||
<check_box
|
||||
control_name="Socks5ProxyEnabled"
|
||||
height="16"
|
||||
label="Use Socks 5 Proxy for UDP traffic"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="socks_proxy_enabled"
|
||||
top_pad="5"
|
||||
width="256"
|
||||
commit_callback.function="Proxy.Change" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="10"
|
||||
name="Proxy location"
|
||||
top_delta="30"
|
||||
width="300">
|
||||
Other Http traffic proxy:
|
||||
</text>
|
||||
<radio_group
|
||||
control_name="Socks5HttpProxyType"
|
||||
height="60"
|
||||
layout="topleft"
|
||||
name="other_http_proxy_selection"
|
||||
top_pad="10"
|
||||
width="120"
|
||||
border="1"
|
||||
left_delta="10"
|
||||
commit_callback.function="Proxy.Change" >
|
||||
<radio_item
|
||||
height="16"
|
||||
label="Do not proxy"
|
||||
layout="topleft"
|
||||
value="None"
|
||||
width="120"
|
||||
tool_tip="Non web Http trafic should NOT be sent to any proxy."/>
|
||||
<radio_item
|
||||
height="16"
|
||||
label="Use Socks 5 Proxy"
|
||||
layout="topleft"
|
||||
value="Socks"
|
||||
width="120"
|
||||
enabled_control="Socks5ProxyEnabled"
|
||||
tool_tip="Non-web Http will be sent to the configured Socks 5 proxy."/>
|
||||
<radio_item
|
||||
height="16"
|
||||
label="Use Http Proxy"
|
||||
layout="topleft"
|
||||
value="Web"
|
||||
width="120"
|
||||
enabled_control="BrowserProxyEnabled"
|
||||
tool_tip="Non-web Http will be sent to the configured Web proxy." />
|
||||
</radio_group>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
left="15"
|
||||
layout="topleft"
|
||||
name="Proxy location"
|
||||
top_delta="82"
|
||||
width="300">
|
||||
HTTP Proxy:
|
||||
</text>
|
||||
<line_editor
|
||||
control_name="BrowserProxyAddress"
|
||||
enabled_control="BrowserProxyEnabled"
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="web_proxy_editor"
|
||||
tool_tip="The DNS name or IP address of the HTTP proxy you would like to use."
|
||||
top_pad="4"
|
||||
width="200" />
|
||||
<spinner
|
||||
control_name="BrowserProxyPort"
|
||||
enabled_control="BrowserProxyEnabled"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="23"
|
||||
increment="1"
|
||||
initial_value="80"
|
||||
label="Port number:"
|
||||
label_width="95"
|
||||
layout="topleft"
|
||||
left_delta="210"
|
||||
max_val="12000"
|
||||
min_val="10"
|
||||
name="web_proxy_port"
|
||||
top_delta="0"
|
||||
tool_tip="The port of the HTTP proxy you would like to use."
|
||||
width="145" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="15"
|
||||
name="Proxy location"
|
||||
top_delta="32"
|
||||
width="300">
|
||||
SOCKS 5 Proxy:
|
||||
</text>
|
||||
<line_editor
|
||||
control_name="Socks5ProxyHost"
|
||||
enabled_control="Socks5ProxyEnabled"
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="socks_proxy_editor"
|
||||
tool_tip="The DNS name or IP address of the SOCKS 5 proxy you would like to use."
|
||||
top_pad="4"
|
||||
width="200"
|
||||
commit_callback.function="Proxy.Change" />
|
||||
<spinner
|
||||
control_name="Socks5ProxyPort"
|
||||
enabled_control="Socks5ProxyEnabled"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="23"
|
||||
increment="1"
|
||||
initial_value="80"
|
||||
label="Port number:"
|
||||
label_width="95"
|
||||
layout="topleft"
|
||||
left_delta="210"
|
||||
max_val="12000"
|
||||
min_val="10"
|
||||
name="socks_proxy_port"
|
||||
top_delta="0"
|
||||
width="145"
|
||||
tool_tip="The port of the SOCKS 5 proxy you would like to use."
|
||||
commit_callback.function="Pref.SocksProxy" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="16"
|
||||
name="Proxy location"
|
||||
top_delta="35"
|
||||
width="300">
|
||||
Authentication:
|
||||
</text>
|
||||
<radio_group
|
||||
control_name="Socks5AuthType"
|
||||
enabled_control="Socks5ProxyEnabled"
|
||||
height="50"
|
||||
layout="topleft"
|
||||
name="socks5_auth_type"
|
||||
top_pad="10"
|
||||
width="120"
|
||||
border="1"
|
||||
commit_callback.function="Proxy.Change" >
|
||||
<radio_item
|
||||
height="16"
|
||||
label="No Authentication"
|
||||
layout="topleft"
|
||||
name="Socks5NoAuth"
|
||||
value="None"
|
||||
tool_tip="Socks5 proxy requires no authentication."/>
|
||||
width="120" />
|
||||
<radio_item
|
||||
height="16"
|
||||
label="Username/Password"
|
||||
layout="topleft"
|
||||
name="Socks5UserPass"
|
||||
value="UserPass"
|
||||
tool_tip="Socks5 proxy requires username/password authentication."/>
|
||||
width="120" />
|
||||
</radio_group>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="20"
|
||||
top_delta="50"
|
||||
width="300">
|
||||
Username:
|
||||
</text>
|
||||
<line_editor
|
||||
control_name="Socks5Username"
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="socks5_username"
|
||||
tool_tip="The username used to authenticate with your SOCKS 5 server"
|
||||
top_pad="4"
|
||||
width="200"
|
||||
commit_callback.function="Proxy.Change" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
top_delta="30"
|
||||
width="300">
|
||||
Password:
|
||||
</text>
|
||||
<line_editor
|
||||
control_name="Socks5Password"
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="socks5_password"
|
||||
tool_tip="The password used to authenticate with your SOCKS 5 server"
|
||||
top_pad="4"
|
||||
width="200"
|
||||
commit_callback.function="Proxy.Change" />
|
||||
<button
|
||||
follows="left|top"
|
||||
height="22"
|
||||
label="OK"
|
||||
label_selected="OK"
|
||||
layout="topleft"
|
||||
right="275"
|
||||
name="OK"
|
||||
top_delta="53"
|
||||
width="90"
|
||||
commit_callback.function="Proxy.OK" />
|
||||
<button
|
||||
follows="left|top"
|
||||
height="22"
|
||||
label="Cancel"
|
||||
label_selected="Cancel"
|
||||
layout="topleft"
|
||||
right="375"
|
||||
name="Cancel"
|
||||
top_delta="0"
|
||||
width="90"
|
||||
commit_callback.function="Proxy.Cancel" />
|
||||
</floater>
|
||||
|
|
@ -7158,6 +7158,76 @@ Click and drag anywhere on the world to rotate your view
|
|||
</form>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="SOCKS_NOT_PERMITTED"
|
||||
type="alertmodal">
|
||||
The Socks5 proxy "[HOST]:[PORT]" refused the connection, not allowed by rule set
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="SOCKS_CONNECT_ERROR"
|
||||
type="alertmodal">
|
||||
The Socks5 proxy "[HOST]:[PORT]" refused the connection, could not open TCP channel
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="SOCKS_NOT_ACCEPTABLE"
|
||||
type="alertmodal">
|
||||
The Socks5 proxy "[HOST]:[PORT]" refused the selected authentication system
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="SOCKS_AUTH_FAIL"
|
||||
type="alertmodal">
|
||||
The Socks5 proxy "[HOST]:[PORT]" reported your credentials are invalid
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="SOCKS_UDP_FWD_NOT_GRANTED"
|
||||
type="alertmodal">
|
||||
The Socks5 proxy "[HOST]:[PORT]" refused the UDP associate request
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="SOCKS_HOST_CONNECT_FAILED"
|
||||
type="alertmodal">
|
||||
Could not connect to Socks5 proxy server "[HOST]:[PORT]"
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="ChangeSocks5Settings"
|
||||
type="alert">
|
||||
Socks 5 proxy settings take effect after you restart [APP_NAME].
|
||||
<usetemplate
|
||||
name="okbutton"
|
||||
yestext="OK"/>
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
name="AuthRequest"
|
||||
type="browser">
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@
|
|||
layout="topleft"
|
||||
left="77"
|
||||
name="connection_port_enabled"
|
||||
top_pad="20"
|
||||
top_pad="10"
|
||||
width="256">
|
||||
<check_box.commit_callback
|
||||
function="Notification.Show"
|
||||
|
|
@ -195,60 +195,6 @@
|
|||
name="media_popup_enabled"
|
||||
width="400"
|
||||
top_pad="5"/>
|
||||
<check_box
|
||||
top_delta="4"
|
||||
enabled="true"
|
||||
follows="left|top"
|
||||
height="14"
|
||||
initial_value="false"
|
||||
control_name="BrowserProxyEnabled"
|
||||
label="Enable Web Proxy"
|
||||
left_delta="0"
|
||||
mouse_opaque="true"
|
||||
name="web_proxy_enabled"
|
||||
radio_style="false"
|
||||
width="400" top_pad="5"/>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left_delta="20"
|
||||
name="Proxy location"
|
||||
top_delta="16"
|
||||
width="300">
|
||||
Proxy location:
|
||||
</text>
|
||||
<line_editor
|
||||
control_name="BrowserProxyAddress"
|
||||
enabled_control="BrowserProxyEnabled"
|
||||
follows="left|top"
|
||||
font="SansSerif"
|
||||
height="23"
|
||||
layout="topleft"
|
||||
left_delta="0"
|
||||
name="web_proxy_editor"
|
||||
tool_tip="The name or IP address of the proxy you would like to use"
|
||||
top_pad="4"
|
||||
width="200" />
|
||||
<spinner
|
||||
control_name="BrowserProxyPort"
|
||||
enabled_control="BrowserProxyEnabled"
|
||||
decimal_digits="0"
|
||||
follows="left|top"
|
||||
height="23"
|
||||
increment="1"
|
||||
initial_value="80"
|
||||
label="Port number:"
|
||||
label_width="95"
|
||||
layout="topleft"
|
||||
left_delta="210"
|
||||
max_val="12000"
|
||||
min_val="10"
|
||||
name="web_proxy_port"
|
||||
top_delta="0"
|
||||
width="145" />
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
|
|
@ -286,4 +232,31 @@
|
|||
name="Install_manual"
|
||||
value="0" />
|
||||
</combo_box>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="10"
|
||||
layout="topleft"
|
||||
left="30"
|
||||
name="Software updates:"
|
||||
mouse_opaque="false"
|
||||
top_pad="5"
|
||||
width="300">
|
||||
Proxy Settings:
|
||||
</text>
|
||||
<button
|
||||
label="Adjust proxy settings"
|
||||
follows="left|top"
|
||||
height="23"
|
||||
width="140"
|
||||
label_selected="Browse"
|
||||
layout="topleft"
|
||||
left_delta="50"
|
||||
name="set_proxy"
|
||||
top_pad="5"
|
||||
>
|
||||
<button.commit_callback
|
||||
function="Pref.Proxy" />
|
||||
</button>
|
||||
</panel>
|
||||
|
|
|
|||
Loading…
Reference in New Issue