diff options
author | McCabe Maxsted | 2011-04-12 17:41:10 -0700 |
---|---|---|
committer | McCabe Maxsted | 2011-04-12 17:41:10 -0700 |
commit | 809de77034c5956a95f35c90024e62b02b439164 (patch) | |
tree | 69beeac02b6c37b38c881d702ede4b7b83642a31 /linden | |
parent | Partial revert of a47ebd78. This caused issues with selection and alt-camming... (diff) | |
download | meta-impy-809de77034c5956a95f35c90024e62b02b439164.zip meta-impy-809de77034c5956a95f35c90024e62b02b439164.tar.gz meta-impy-809de77034c5956a95f35c90024e62b02b439164.tar.bz2 meta-impy-809de77034c5956a95f35c90024e62b02b439164.tar.xz |
Ported SOCKS5 proxy support from Snowglobe 1.5
Diffstat (limited to 'linden')
-rw-r--r-- | linden/indra/llmessage/CMakeLists.txt | 2 | ||||
-rw-r--r-- | linden/indra/llmessage/llcurl.cpp | 40 | ||||
-rw-r--r-- | linden/indra/llmessage/llpacketring.cpp | 56 | ||||
-rw-r--r-- | linden/indra/llmessage/llpacketring.h | 3 | ||||
-rw-r--r-- | linden/indra/llmessage/llsocks5.cpp | 210 | ||||
-rw-r--r-- | linden/indra/llmessage/llsocks5.h | 248 | ||||
-rw-r--r-- | linden/indra/llmessage/message.cpp | 8 | ||||
-rw-r--r-- | linden/indra/llmessage/message.h | 14 | ||||
-rw-r--r-- | linden/indra/llmessage/net.cpp | 158 | ||||
-rw-r--r-- | linden/indra/llmessage/net.h | 3 | ||||
-rw-r--r-- | linden/indra/newview/app_settings/settings.xml | 99 | ||||
-rw-r--r-- | linden/indra/newview/llpanelnetwork.cpp | 126 | ||||
-rw-r--r-- | linden/indra/newview/llpanelnetwork.h | 8 | ||||
-rw-r--r-- | linden/indra/newview/llstartup.cpp | 125 | ||||
-rw-r--r-- | linden/indra/newview/llstartup.h | 3 | ||||
-rw-r--r-- | linden/indra/newview/llxmlrpctransaction.cpp | 17 | ||||
-rw-r--r-- | linden/indra/newview/skins/default/xui/en-us/notifications.xml | 56 | ||||
-rw-r--r-- | linden/indra/newview/skins/default/xui/en-us/panel_preferences_network.xml | 115 |
18 files changed, 1259 insertions, 32 deletions
diff --git a/linden/indra/llmessage/CMakeLists.txt b/linden/indra/llmessage/CMakeLists.txt index 9965191..b3f2b4c 100644 --- a/linden/indra/llmessage/CMakeLists.txt +++ b/linden/indra/llmessage/CMakeLists.txt | |||
@@ -98,6 +98,7 @@ set(llmessage_SOURCE_FILES | |||
98 | patch_code.cpp | 98 | patch_code.cpp |
99 | patch_dct.cpp | 99 | patch_dct.cpp |
100 | patch_idct.cpp | 100 | patch_idct.cpp |
101 | llsocks5.cpp | ||
101 | sound_ids.cpp | 102 | sound_ids.cpp |
102 | ) | 103 | ) |
103 | 104 | ||
@@ -198,6 +199,7 @@ set(llmessage_HEADER_FILES | |||
198 | patch_code.h | 199 | patch_code.h |
199 | patch_dct.h | 200 | patch_dct.h |
200 | sound_ids.h | 201 | sound_ids.h |
202 | llsocks5.h | ||
201 | ) | 203 | ) |
202 | 204 | ||
203 | set_source_files_properties(${llmessage_HEADER_FILES} | 205 | set_source_files_properties(${llmessage_HEADER_FILES} |
diff --git a/linden/indra/llmessage/llcurl.cpp b/linden/indra/llmessage/llcurl.cpp index 9ecfee4..b23ef33 100644 --- a/linden/indra/llmessage/llcurl.cpp +++ b/linden/indra/llmessage/llcurl.cpp | |||
@@ -56,6 +56,8 @@ | |||
56 | #include "llsdserialize.h" | 56 | #include "llsdserialize.h" |
57 | #include "llthread.h" | 57 | #include "llthread.h" |
58 | 58 | ||
59 | #include "llsocks5.h" | ||
60 | |||
59 | ////////////////////////////////////////////////////////////////////////////// | 61 | ////////////////////////////////////////////////////////////////////////////// |
60 | /* | 62 | /* |
61 | The trick to getting curl to do keep-alives is to reuse the | 63 | The trick to getting curl to do keep-alives is to reuse the |
@@ -270,6 +272,25 @@ LLCurl::Easy* LLCurl::Easy::getEasy() | |||
270 | // set no DMS caching as default for all easy handles. This prevents them adopting a | 272 | // set no DMS caching as default for all easy handles. This prevents them adopting a |
271 | // multi handles cache if they are added to one. | 273 | // multi handles cache if they are added to one. |
272 | curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0); | 274 | curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0); |
275 | |||
276 | if (LLSocks::getInstance()->isHttpProxyEnabled()) | ||
277 | { | ||
278 | std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString(); | ||
279 | U16 port = LLSocks::getInstance()->getHTTPProxy().getPort(); | ||
280 | curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXY,address.c_str()); | ||
281 | curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYPORT,port); | ||
282 | if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS) | ||
283 | { | ||
284 | curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); | ||
285 | if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD) | ||
286 | curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYUSERPWD,LLSocks::getInstance()->getProxyUserPwd().c_str()); | ||
287 | } | ||
288 | else | ||
289 | { | ||
290 | curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); | ||
291 | } | ||
292 | } | ||
293 | |||
273 | ++gCurlEasyCount; | 294 | ++gCurlEasyCount; |
274 | return easy; | 295 | return easy; |
275 | } | 296 | } |
@@ -443,6 +464,24 @@ void LLCurl::Easy::prepRequest(const std::string& url, | |||
443 | // setopt(CURLOPT_VERBOSE, 1); // usefull for debugging | 464 | // setopt(CURLOPT_VERBOSE, 1); // usefull for debugging |
444 | setopt(CURLOPT_NOSIGNAL, 1); | 465 | setopt(CURLOPT_NOSIGNAL, 1); |
445 | 466 | ||
467 | if (LLSocks::getInstance()->isHttpProxyEnabled()) | ||
468 | { | ||
469 | std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString(); | ||
470 | U16 port = LLSocks::getInstance()->getHTTPProxy().getPort(); | ||
471 | setoptString(CURLOPT_PROXY, address.c_str()); | ||
472 | setopt(CURLOPT_PROXYPORT, port); | ||
473 | if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS) | ||
474 | { | ||
475 | setopt(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); | ||
476 | if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD) | ||
477 | setoptString(CURLOPT_PROXYUSERPWD,LLSocks::getInstance()->getProxyUserPwd()); | ||
478 | } | ||
479 | else | ||
480 | { | ||
481 | setopt(CURLOPT_PROXYTYPE, CURLPROXY_HTTP); | ||
482 | } | ||
483 | } | ||
484 | |||
446 | mOutput.reset(new LLBufferArray); | 485 | mOutput.reset(new LLBufferArray); |
447 | setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback); | 486 | setopt(CURLOPT_WRITEFUNCTION, (void*)&curlWriteCallback); |
448 | setopt(CURLOPT_WRITEDATA, (void*)this); | 487 | setopt(CURLOPT_WRITEDATA, (void*)this); |
@@ -742,6 +781,7 @@ bool LLCurlRequest::getByteRange(const std::string& url, | |||
742 | if (length > 0) | 781 | if (length > 0) |
743 | { | 782 | { |
744 | std::string range = llformat("Range: bytes=%d-%d", offset,offset+length-1); | 783 | std::string range = llformat("Range: bytes=%d-%d", offset,offset+length-1); |
784 | //llinfos << "http url: " << url << " " << range << llendl; | ||
745 | easy->slist_append(range.c_str()); | 785 | easy->slist_append(range.c_str()); |
746 | } | 786 | } |
747 | easy->setHeaders(); | 787 | easy->setHeaders(); |
diff --git a/linden/indra/llmessage/llpacketring.cpp b/linden/indra/llmessage/llpacketring.cpp index 7dcb606..a39b435 100644 --- a/linden/indra/llmessage/llpacketring.cpp +++ b/linden/indra/llmessage/llpacketring.cpp | |||
@@ -43,6 +43,15 @@ | |||
43 | #include "llmessagelog.h" | 43 | #include "llmessagelog.h" |
44 | #include "message.h" | 44 | #include "message.h" |
45 | 45 | ||
46 | #include "llsocks5.h" | ||
47 | |||
48 | #if LL_WINDOWS | ||
49 | #include <winsock2.h> | ||
50 | #else | ||
51 | #include <sys/socket.h> | ||
52 | #include <netinet/in.h> | ||
53 | #endif | ||
54 | |||
46 | /////////////////////////////////////////////////////////// | 55 | /////////////////////////////////////////////////////////// |
47 | LLPacketRing::LLPacketRing () : | 56 | LLPacketRing::LLPacketRing () : |
48 | mUseInThrottle(FALSE), | 57 | mUseInThrottle(FALSE), |
@@ -224,8 +233,25 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap) | |||
224 | else | 233 | else |
225 | { | 234 | { |
226 | // no delay, pull straight from net | 235 | // no delay, pull straight from net |
227 | packet_size = receive_packet(socket, datap); | 236 | if (LLSocks::isEnabled()) |
228 | mLastSender = ::get_sender(); | 237 | { |
238 | proxywrap_t * header; | ||
239 | datap = datap-10; | ||
240 | header = (proxywrap_t *)datap; | ||
241 | packet_size = receive_packet(socket, datap); | ||
242 | mLastSender.setAddress(header->addr); | ||
243 | mLastSender.setPort(ntohs(header->port)); | ||
244 | if (packet_size > 10) | ||
245 | { | ||
246 | packet_size -= 10; | ||
247 | } | ||
248 | } | ||
249 | else | ||
250 | { | ||
251 | packet_size = receive_packet(socket, datap); | ||
252 | mLastSender = ::get_sender(); | ||
253 | } | ||
254 | |||
229 | mLastReceivingIF = ::get_receiving_interface(); | 255 | mLastReceivingIF = ::get_receiving_interface(); |
230 | 256 | ||
231 | if (packet_size) // did we actually get a packet? | 257 | if (packet_size) // did we actually get a packet? |
@@ -254,7 +280,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL | |||
254 | BOOL status = TRUE; | 280 | BOOL status = TRUE; |
255 | if (!mUseOutThrottle) | 281 | if (!mUseOutThrottle) |
256 | { | 282 | { |
257 | return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort() ); | 283 | return doSendPacket(h_socket, send_buffer, buf_size, host ); |
258 | } | 284 | } |
259 | else | 285 | else |
260 | { | 286 | { |
@@ -275,7 +301,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL | |||
275 | mOutBufferLength -= packetp->getSize(); | 301 | mOutBufferLength -= packetp->getSize(); |
276 | packet_size = packetp->getSize(); | 302 | packet_size = packetp->getSize(); |
277 | 303 | ||
278 | status = send_packet(h_socket, packetp->getData(), packet_size, packetp->getHost().getAddress(), packetp->getHost().getPort()); | 304 | status = doSendPacket(h_socket, packetp->getData(), packet_size, packetp->getHost()); |
279 | 305 | ||
280 | delete packetp; | 306 | delete packetp; |
281 | // Update the throttle | 307 | // Update the throttle |
@@ -284,7 +310,7 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL | |||
284 | else | 310 | else |
285 | { | 311 | { |
286 | // If the queue's empty, we can just send this packet right away. | 312 | // If the queue's empty, we can just send this packet right away. |
287 | status = send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort() ); | 313 | status = doSendPacket(h_socket, send_buffer, buf_size, host ); |
288 | packet_size = buf_size; | 314 | packet_size = buf_size; |
289 | 315 | ||
290 | // Update the throttle | 316 | // Update the throttle |
@@ -322,3 +348,23 @@ BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LL | |||
322 | 348 | ||
323 | return status; | 349 | return status; |
324 | } | 350 | } |
351 | |||
352 | BOOL LLPacketRing::doSendPacket(int h_socket, const char * send_buffer, S32 buf_size, LLHost host) | ||
353 | { | ||
354 | |||
355 | if (!LLSocks::isEnabled()) | ||
356 | { | ||
357 | return send_packet(h_socket, send_buffer, buf_size, host.getAddress(), host.getPort()); | ||
358 | } | ||
359 | |||
360 | proxywrap_t *socks_header = (proxywrap_t *)&mProxyWrappedSendBuffer; | ||
361 | socks_header->rsv = 0; | ||
362 | socks_header->addr = host.getAddress(); | ||
363 | socks_header->port = htons(host.getPort()); | ||
364 | socks_header->atype = ADDRESS_IPV4; | ||
365 | socks_header->frag = 0; | ||
366 | |||
367 | memcpy(mProxyWrappedSendBuffer+10, send_buffer, buf_size); | ||
368 | |||
369 | return send_packet(h_socket,(const char*) mProxyWrappedSendBuffer, buf_size+10, LLSocks::getInstance()->getUDPPproxy().getAddress(), LLSocks::getInstance()->getUDPPproxy().getPort()); | ||
370 | } | ||
diff --git a/linden/indra/llmessage/llpacketring.h b/linden/indra/llmessage/llpacketring.h index 4408abe..5d2c246 100644 --- a/linden/indra/llmessage/llpacketring.h +++ b/linden/indra/llmessage/llpacketring.h | |||
@@ -88,6 +88,9 @@ protected: | |||
88 | 88 | ||
89 | LLHost mLastSender; | 89 | LLHost mLastSender; |
90 | LLHost mLastReceivingIF; | 90 | LLHost mLastReceivingIF; |
91 | |||
92 | BOOL doSendPacket(int h_socket, const char * send_buffer, S32 buf_size, LLHost host); | ||
93 | U8 mProxyWrappedSendBuffer[NET_BUFFER_SIZE]; | ||
91 | }; | 94 | }; |
92 | 95 | ||
93 | 96 | ||
diff --git a/linden/indra/llmessage/llsocks5.cpp b/linden/indra/llmessage/llsocks5.cpp new file mode 100644 index 0000000..7326e80 --- /dev/null +++ b/linden/indra/llmessage/llsocks5.cpp | |||
@@ -0,0 +1,210 @@ | |||
1 | /** | ||
2 | * @file llsocks5.cpp | ||
3 | * @brief Socks 5 implementation | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2000&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2000-2009, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at | ||
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #include <string> | ||
34 | |||
35 | #include "linden_common.h" | ||
36 | #include "net.h" | ||
37 | #include "llhost.h" | ||
38 | #include "message.h" | ||
39 | #include "llsocks5.h" | ||
40 | |||
41 | // Static class variable instances | ||
42 | |||
43 | // We want this to be static to avoid excessive indirection on every | ||
44 | // incomming packet just to do a simple bool test. The getter for this | ||
45 | // member is also static | ||
46 | bool LLSocks::sUdpProxyEnabled; | ||
47 | bool LLSocks::sHttpProxyEnabled; | ||
48 | |||
49 | LLSocks::LLSocks() | ||
50 | { | ||
51 | sUdpProxyEnabled = false; | ||
52 | sHttpProxyEnabled = false; | ||
53 | mNeedUpdate = false; | ||
54 | } | ||
55 | |||
56 | // Perform a Socks5 authentication and UDP assioacation to the proxy | ||
57 | // specified by proxy, and assiocate UDP port message_port | ||
58 | int LLSocks::proxyHandshake(LLHost proxy, U32 message_port) | ||
59 | { | ||
60 | int result; | ||
61 | |||
62 | /* Socks 5 Auth request */ | ||
63 | socks_auth_request_t socks_auth_request; | ||
64 | socks_auth_response_t socks_auth_response; | ||
65 | |||
66 | socks_auth_request.version = SOCKS_VERSION; // Socks version 5 | ||
67 | socks_auth_request.num_methods = 1; // Sending 1 method | ||
68 | socks_auth_request.methods = mAuthMethodSelected; // send only the selected metho | ||
69 | |||
70 | result = tcp_handshake(hProxyControlChannel, (char*)&socks_auth_request, sizeof(socks_auth_request_t), (char*)&socks_auth_response, sizeof(socks_auth_response_t)); | ||
71 | if (result != 0) | ||
72 | { | ||
73 | llwarns << "Socks authentication request failed, error on TCP control channel : " << result << llendl; | ||
74 | stopProxy(); | ||
75 | return SOCKS_CONNECT_ERROR; | ||
76 | } | ||
77 | |||
78 | if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE) | ||
79 | { | ||
80 | llwarns << "Socks5 server refused all our authentication methods" << llendl; | ||
81 | stopProxy(); | ||
82 | return SOCKS_NOT_ACCEPTABLE; | ||
83 | } | ||
84 | |||
85 | // SOCKS5 USERNAME/PASSWORD authentication | ||
86 | if (socks_auth_response.method == METHOD_PASSWORD) | ||
87 | { | ||
88 | // The server has requested a username/password combination | ||
89 | U32 request_size = mSocksUsername.size() + mSocksPassword.size() + 3; | ||
90 | char * password_auth = (char *)malloc(request_size); | ||
91 | password_auth[0] = 0x01; | ||
92 | password_auth[1] = mSocksUsername.size(); | ||
93 | memcpy(&password_auth[2],mSocksUsername.c_str(), mSocksUsername.size()); | ||
94 | password_auth[mSocksUsername.size()+2] = mSocksPassword.size(); | ||
95 | memcpy(&password_auth[mSocksUsername.size()+3], mSocksPassword.c_str(), mSocksPassword.size()); | ||
96 | |||
97 | authmethod_password_reply_t password_reply; | ||
98 | |||
99 | result = tcp_handshake(hProxyControlChannel, password_auth, request_size, (char*)&password_reply, sizeof(authmethod_password_reply_t)); | ||
100 | free (password_auth); | ||
101 | |||
102 | if (result != 0) | ||
103 | { | ||
104 | llwarns << "Socks authentication failed, error on TCP control channel : " << result << llendl; | ||
105 | stopProxy(); | ||
106 | return SOCKS_CONNECT_ERROR; | ||
107 | } | ||
108 | |||
109 | if (password_reply.status != AUTH_SUCCESS) | ||
110 | { | ||
111 | llwarns << "Socks authentication failed" << llendl; | ||
112 | stopProxy(); | ||
113 | return SOCKS_AUTH_FAIL; | ||
114 | } | ||
115 | } | ||
116 | |||
117 | /* SOCKS5 connect request */ | ||
118 | |||
119 | socks_command_request_t connect_request; | ||
120 | socks_command_response_t connect_reply; | ||
121 | |||
122 | connect_request.version = SOCKS_VERSION; //Socks V5 | ||
123 | connect_request.command = COMMAND_UDP_ASSOCIATE; // Associate UDP | ||
124 | connect_request.flag = FIELD_RESERVED; | ||
125 | connect_request.atype = ADDRESS_IPV4; | ||
126 | connect_request.address = 0; // 0.0.0.0 We are not fussy about address | ||
127 | // UDP is promiscious receive for our protocol | ||
128 | connect_request.port = 0; // Port must be 0 if you ever want to connect via NAT and your router does port rewrite for you | ||
129 | |||
130 | result = tcp_handshake(hProxyControlChannel, (char*)&connect_request, sizeof(socks_command_request_t), (char*)&connect_reply, sizeof(socks_command_response_t)); | ||
131 | if (result != 0) | ||
132 | { | ||
133 | llwarns << "Socks connect request failed, error on TCP control channel : " << result << llendl; | ||
134 | stopProxy(); | ||
135 | return SOCKS_CONNECT_ERROR; | ||
136 | } | ||
137 | |||
138 | if (connect_reply.reply != REPLY_REQUEST_GRANTED) | ||
139 | { | ||
140 | //Something went wrong | ||
141 | llwarns << "Connection to SOCKS5 server failed, UDP forward request not granted" << llendl; | ||
142 | stopProxy(); | ||
143 | return SOCKS_UDP_FWD_NOT_GRANTED; | ||
144 | } | ||
145 | |||
146 | mUDPProxy.setPort(ntohs(connect_reply.port)); // reply port is in network byte order | ||
147 | mUDPProxy.setAddress(proxy.getAddress()); | ||
148 | // All good now we have been given the UDP port to send requests that need forwarding. | ||
149 | llinfos << "Socks 5 UDP proxy connected on " << mUDPProxy << llendl; | ||
150 | return SOCKS_OK; | ||
151 | } | ||
152 | |||
153 | int LLSocks::startProxy(LLHost proxy, U32 message_port) | ||
154 | { | ||
155 | int status; | ||
156 | |||
157 | mTCPProxy = proxy; | ||
158 | mNeedUpdate = false; | ||
159 | |||
160 | stopProxy(); | ||
161 | hProxyControlChannel = tcp_open_channel(proxy); | ||
162 | if (hProxyControlChannel == -1) | ||
163 | { | ||
164 | return SOCKS_HOST_CONNECT_FAILED; | ||
165 | } | ||
166 | |||
167 | status = proxyHandshake(proxy, message_port); | ||
168 | if (status == SOCKS_OK) | ||
169 | { | ||
170 | sUdpProxyEnabled=true; | ||
171 | } | ||
172 | return status; | ||
173 | } | ||
174 | |||
175 | int LLSocks::startProxy(std::string host, U32 port) | ||
176 | { | ||
177 | mTCPProxy.setHostByName(host); | ||
178 | mTCPProxy.setPort(port); | ||
179 | return startProxy(mTCPProxy, (U32)gMessageSystem->mPort); | ||
180 | } | ||
181 | |||
182 | void LLSocks::stopProxy() | ||
183 | { | ||
184 | sUdpProxyEnabled = false; | ||
185 | |||
186 | if (hProxyControlChannel) | ||
187 | { | ||
188 | tcp_close_channel(hProxyControlChannel); | ||
189 | } | ||
190 | } | ||
191 | |||
192 | void LLSocks::setAuthNone() | ||
193 | { | ||
194 | mAuthMethodSelected = METHOD_NOAUTH; | ||
195 | } | ||
196 | |||
197 | |||
198 | void LLSocks::setAuthPassword(std::string username, std::string password) | ||
199 | { | ||
200 | mAuthMethodSelected = METHOD_PASSWORD; | ||
201 | mSocksUsername = username; | ||
202 | mSocksPassword = password; | ||
203 | } | ||
204 | |||
205 | void LLSocks::EnableHttpProxy(LLHost httpHost, LLHttpProxyType type) | ||
206 | { | ||
207 | sHttpProxyEnabled = true; | ||
208 | mHTTPProxy = httpHost; | ||
209 | mProxyType = type; | ||
210 | } | ||
diff --git a/linden/indra/llmessage/llsocks5.h b/linden/indra/llmessage/llsocks5.h new file mode 100644 index 0000000..d422d20 --- /dev/null +++ b/linden/indra/llmessage/llsocks5.h | |||
@@ -0,0 +1,248 @@ | |||
1 | /** | ||
2 | * @file llsocks5.h | ||
3 | * @brief Socks 5 implementation | ||
4 | * | ||
5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | ||
6 | * | ||
7 | * Copyright (c) 2001-2009, Linden Research, Inc. | ||
8 | * | ||
9 | * Second Life Viewer Source Code | ||
10 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
11 | * to you under the terms of the GNU General Public License, version 2.0 | ||
12 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
13 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
14 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
15 | * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 | ||
16 | * | ||
17 | * There are special exceptions to the terms and conditions of the GPL as | ||
18 | * it is applied to this Source Code. View the full text of the exception | ||
19 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
20 | * online at | ||
21 | * http://secondlifegrid.net/programs/open_source/licensing/flossexception | ||
22 | * | ||
23 | * By copying, modifying or distributing this software, you acknowledge | ||
24 | * that you have read and understood your obligations described above, | ||
25 | * and agree to abide by those obligations. | ||
26 | * | ||
27 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
28 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
29 | * COMPLETENESS OR PERFORMANCE. | ||
30 | * $/LicenseInfo$ | ||
31 | */ | ||
32 | |||
33 | #ifndef LL_SOCKS5_H | ||
34 | #define LL_SOCKS5_H | ||
35 | |||
36 | #include "llhost.h" | ||
37 | #include "llmemory.h" | ||
38 | #include <string> | ||
39 | |||
40 | // Error codes returned from the StartProxy method | ||
41 | |||
42 | #define SOCKS_OK 0 | ||
43 | #define SOCKS_CONNECT_ERROR -1 | ||
44 | #define SOCKS_NOT_PERMITTED -2 | ||
45 | #define SOCKS_NOT_ACCEPTABLE -3 | ||
46 | #define SOCKS_AUTH_FAIL -4 | ||
47 | #define SOCKS_UDP_FWD_NOT_GRANTED -5 | ||
48 | #define SOCKS_HOST_CONNECT_FAILED -6 | ||
49 | |||
50 | #ifndef MAXHOSTNAMELEN | ||
51 | #define MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */ | ||
52 | #endif | ||
53 | |||
54 | #define SOCKS_VERSION 0x05 // we are using socks 5 | ||
55 | |||
56 | // socks 5 address/hostname types | ||
57 | #define ADDRESS_IPV4 0x01 | ||
58 | #define ADDRESS_HOSTNAME 0x03 | ||
59 | #define ADDRESS_IPV6 0x04 | ||
60 | |||
61 | // Lets just use our own ipv4 struct rather than dragging in system | ||
62 | // specific headers | ||
63 | union ipv4_address_t { | ||
64 | unsigned char octects[4]; | ||
65 | U32 addr32; | ||
66 | }; | ||
67 | |||
68 | // Socks 5 control channel commands | ||
69 | #define COMMAND_TCP_STREAM 0x01 | ||
70 | #define COMMAND_TCP_BIND 0x02 | ||
71 | #define COMMAND_UDP_ASSOCIATE 0x03 | ||
72 | |||
73 | // Socks 5 command replys | ||
74 | #define REPLY_REQUEST_GRANTED 0x00 | ||
75 | #define REPLY_GENERAL_FAIL 0x01 | ||
76 | #define REPLY_RULESET_FAIL 0x02 | ||
77 | #define REPLY_NETWORK_UNREACHABLE 0x03 | ||
78 | #define REPLY_HOST_UNREACHABLE 0x04 | ||
79 | #define REPLY_CONNECTION_REFUSED 0x05 | ||
80 | #define REPLY_TTL_EXPIRED 0x06 | ||
81 | #define REPLY_PROTOCOL_ERROR 0x07 | ||
82 | #define REPLY_TYPE_NOT_SUPPORTED 0x08 | ||
83 | |||
84 | #define FIELD_RESERVED 0x00 | ||
85 | |||
86 | // The standard socks5 request packet | ||
87 | // Push current alignment to stack and set alignment to 1 byte boundary | ||
88 | // This enabled us to use structs directly to set up and receive network packets | ||
89 | // into the correct fields, without fear of boundary alignment causing issues | ||
90 | #pragma pack(push,1) | ||
91 | |||
92 | // Socks5 command packet | ||
93 | struct socks_command_request_t { | ||
94 | unsigned char version; | ||
95 | unsigned char command; | ||
96 | unsigned char flag; | ||
97 | unsigned char atype; | ||
98 | U32 address; | ||
99 | U16 port; | ||
100 | }; | ||
101 | |||
102 | // Standard socks5 reply packet | ||
103 | struct socks_command_response_t { | ||
104 | unsigned char version; | ||
105 | unsigned char reply; | ||
106 | unsigned char flag; | ||
107 | unsigned char atype; | ||
108 | unsigned char add_bytes[4]; | ||
109 | U16 port; | ||
110 | }; | ||
111 | |||
112 | #define AUTH_NOT_ACCEPTABLE 0xFF // reply if prefered methods are not avaiable | ||
113 | #define AUTH_SUCCESS 0x00 // reply if authentication successfull | ||
114 | |||
115 | // socks 5 authentication request, stating which methods the client supports | ||
116 | struct socks_auth_request_t { | ||
117 | unsigned char version; | ||
118 | unsigned char num_methods; | ||
119 | unsigned char methods; // We are only using a single method currently | ||
120 | }; | ||
121 | |||
122 | // socks 5 authentication response packet, stating server prefered method | ||
123 | struct socks_auth_response_t { | ||
124 | unsigned char version; | ||
125 | unsigned char method; | ||
126 | }; | ||
127 | |||
128 | // socks 5 password reply packet | ||
129 | struct authmethod_password_reply_t { | ||
130 | unsigned char version; | ||
131 | unsigned char status; | ||
132 | }; | ||
133 | |||
134 | // socks 5 UDP packet header | ||
135 | struct proxywrap_t { | ||
136 | U16 rsv; | ||
137 | U8 frag; | ||
138 | U8 atype; | ||
139 | U32 addr; | ||
140 | U16 port; | ||
141 | }; | ||
142 | |||
143 | #pragma pack(pop) /* restore original alignment from stack */ | ||
144 | |||
145 | |||
146 | // Currently selected http proxy type | ||
147 | enum LLHttpProxyType | ||
148 | { | ||
149 | LLPROXY_SOCKS=0, | ||
150 | LLPROXY_HTTP=1 | ||
151 | }; | ||
152 | |||
153 | // Auth types | ||
154 | enum LLSocks5AuthType | ||
155 | { | ||
156 | METHOD_NOAUTH=0x00, // Client supports no auth | ||
157 | METHOD_GSSAPI=0x01, // Client supports GSSAPI (Not currently supported) | ||
158 | METHOD_PASSWORD=0x02 // Client supports username/password | ||
159 | }; | ||
160 | |||
161 | class LLSocks: public LLSingleton<LLSocks> | ||
162 | { | ||
163 | public: | ||
164 | LLSocks(); | ||
165 | |||
166 | // Start a connection to the socks 5 proxy | ||
167 | int startProxy(std::string host,U32 port); | ||
168 | int startProxy(LLHost proxy,U32 messagePort); | ||
169 | |||
170 | // Disconnect and clean up any connection to the socks 5 proxy | ||
171 | void stopProxy(); | ||
172 | |||
173 | // Set up to use Password auth when connecting to the socks proxy | ||
174 | void setAuthPassword(std::string username,std::string password); | ||
175 | |||
176 | // Set up to use No Auth when connecting to the socks proxy; | ||
177 | void setAuthNone(); | ||
178 | |||
179 | // get the currently selected auth method | ||
180 | LLSocks5AuthType getSelectedAuthMethod() { return mAuthMethodSelected; }; | ||
181 | |||
182 | // static check for enabled status for UDP packets | ||
183 | static bool isEnabled(){return sUdpProxyEnabled;}; | ||
184 | |||
185 | // static check for enabled status for http packets | ||
186 | static bool isHttpProxyEnabled(){return sHttpProxyEnabled;}; | ||
187 | |||
188 | // Proxy http packets via httpHost, which can be a Socks5 or a http proxy | ||
189 | // as specified in type | ||
190 | void EnableHttpProxy(LLHost httpHost,LLHttpProxyType type); | ||
191 | |||
192 | // Stop proxying http packets | ||
193 | void DisableHttpProxy() {sHttpProxyEnabled = false;}; | ||
194 | |||
195 | // get the UDP proxy address and port | ||
196 | LLHost getUDPPproxy(){return mUDPProxy;}; | ||
197 | // get the socks 5 TCP control channel address and port | ||
198 | LLHost getTCPProxy(){return mTCPProxy;}; | ||
199 | //get the http proxy address and port | ||
200 | LLHost getHTTPProxy(){return mHTTPProxy;}; | ||
201 | |||
202 | // get the currently selected http proxy type | ||
203 | LLHttpProxyType getHttpProxyType(){return mProxyType;}; | ||
204 | |||
205 | // mark that we need an update due to a settings change | ||
206 | void updated() { mNeedUpdate = true; }; | ||
207 | // report if the current settings are applied or dirty pending a startProxy | ||
208 | bool needsUpdate() { return mNeedUpdate; }; | ||
209 | |||
210 | //Get the username password in a curl compatible format | ||
211 | std::string getProxyUserPwd(){ return (mSocksUsername+":"+mSocksPassword);}; | ||
212 | |||
213 | private: | ||
214 | |||
215 | // Open a communication channel to the socks5 proxy proxy, at port messagePort | ||
216 | int proxyHandshake(LLHost proxy,U32 messagePort); | ||
217 | |||
218 | // socket handle to proxy tcp control channel | ||
219 | S32 hProxyControlChannel; | ||
220 | |||
221 | // is the UDP proxy enabled | ||
222 | static bool sUdpProxyEnabled; | ||
223 | // is the http proxy enabled | ||
224 | static bool sHttpProxyEnabled; | ||
225 | |||
226 | // Have all settings been applied | ||
227 | bool mNeedUpdate; | ||
228 | |||
229 | // currently selected http proxy type | ||
230 | LLHttpProxyType mProxyType; | ||
231 | |||
232 | // UDP proxy address and port | ||
233 | LLHost mUDPProxy; | ||
234 | // TCP Proxy control channel address and port | ||
235 | LLHost mTCPProxy; | ||
236 | // HTTP proxy address and port | ||
237 | LLHost mHTTPProxy; | ||
238 | |||
239 | // socks 5 auth method selected | ||
240 | LLSocks5AuthType mAuthMethodSelected; | ||
241 | |||
242 | // socks 5 username | ||
243 | std::string mSocksUsername; | ||
244 | // socks 5 password | ||
245 | std::string mSocksPassword; | ||
246 | }; | ||
247 | |||
248 | #endif | ||
diff --git a/linden/indra/llmessage/message.cpp b/linden/indra/llmessage/message.cpp index 53036bc..81f7c2a 100644 --- a/linden/indra/llmessage/message.cpp +++ b/linden/indra/llmessage/message.cpp | |||
@@ -548,9 +548,9 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count, bool faked_message, U8 fak | |||
548 | S32 acks = 0; | 548 | S32 acks = 0; |
549 | S32 true_rcv_size = 0; | 549 | S32 true_rcv_size = 0; |
550 | 550 | ||
551 | U8* buffer = mTrueReceiveBuffer; | 551 | U8* buffer = mTrueReceiveBuffer.buffer; |
552 | 552 | ||
553 | mTrueReceiveSize = mPacketRing.receivePacket(mSocket, (char *)mTrueReceiveBuffer); | 553 | mTrueReceiveSize = mPacketRing.receivePacket(mSocket, (char *)mTrueReceiveBuffer.buffer); |
554 | // If you want to dump all received packets into SecondLife.log, uncomment this | 554 | // If you want to dump all received packets into SecondLife.log, uncomment this |
555 | //dumpPacketToLog(); | 555 | //dumpPacketToLog(); |
556 | // <edit> | 556 | // <edit> |
@@ -622,7 +622,7 @@ BOOL LLMessageSystem::checkMessages( S64 frame_count, bool faked_message, U8 fak | |||
622 | for(S32 i = 0; i < acks; ++i) | 622 | for(S32 i = 0; i < acks; ++i) |
623 | { | 623 | { |
624 | true_rcv_size -= sizeof(TPACKETID); | 624 | true_rcv_size -= sizeof(TPACKETID); |
625 | memcpy(&mem_id, &mTrueReceiveBuffer[true_rcv_size], /* Flawfinder: ignore*/ | 625 | memcpy(&mem_id, &buffer[true_rcv_size], /* Flawfinder: ignore*/ |
626 | sizeof(TPACKETID)); | 626 | sizeof(TPACKETID)); |
627 | packet_id = ntohl(mem_id); | 627 | packet_id = ntohl(mem_id); |
628 | //LL_INFOS("Messaging") << "got ack: " << packet_id << llendl; | 628 | //LL_INFOS("Messaging") << "got ack: " << packet_id << llendl; |
@@ -3386,7 +3386,7 @@ void LLMessageSystem::dumpPacketToLog() | |||
3386 | { | 3386 | { |
3387 | S32 offset = cur_line_pos * 3; | 3387 | S32 offset = cur_line_pos * 3; |
3388 | snprintf(line_buffer + offset, sizeof(line_buffer) - offset, | 3388 | snprintf(line_buffer + offset, sizeof(line_buffer) - offset, |
3389 | "%02x ", mTrueReceiveBuffer[i]); /* Flawfinder: ignore */ | 3389 | "%02x ", mTrueReceiveBuffer.buffer[i]); /* Flawfinder: ignore */ |
3390 | cur_line_pos++; | 3390 | cur_line_pos++; |
3391 | if (cur_line_pos >= 16) | 3391 | if (cur_line_pos >= 16) |
3392 | { | 3392 | { |
diff --git a/linden/indra/llmessage/message.h b/linden/indra/llmessage/message.h index e6391d9..43c3b0a 100644 --- a/linden/indra/llmessage/message.h +++ b/linden/indra/llmessage/message.h | |||
@@ -66,6 +66,7 @@ | |||
66 | #include "llmessagesenderinterface.h" | 66 | #include "llmessagesenderinterface.h" |
67 | 67 | ||
68 | #include "llstoredmessage.h" | 68 | #include "llstoredmessage.h" |
69 | #include "llsocks5.h" | ||
69 | 70 | ||
70 | const U32 MESSAGE_MAX_STRINGS_LENGTH = 64; | 71 | const U32 MESSAGE_MAX_STRINGS_LENGTH = 64; |
71 | const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192; | 72 | const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192; |
@@ -775,7 +776,18 @@ private: | |||
775 | LLMessagePollInfo *mPollInfop; | 776 | LLMessagePollInfo *mPollInfop; |
776 | 777 | ||
777 | U8 mEncodedRecvBuffer[MAX_BUFFER_SIZE]; | 778 | U8 mEncodedRecvBuffer[MAX_BUFFER_SIZE]; |
778 | U8 mTrueReceiveBuffer[MAX_BUFFER_SIZE]; | 779 | |
780 | // Push current alignment to stack and set alignment to 1 byte boundary | ||
781 | #pragma pack(push,1) | ||
782 | |||
783 | struct ReceiveBuffer_t | ||
784 | { | ||
785 | proxywrap_t header; | ||
786 | U8 buffer[MAX_BUFFER_SIZE]; | ||
787 | } mTrueReceiveBuffer; | ||
788 | |||
789 | #pragma pack(pop) /* restore original alignment from stack */ | ||
790 | |||
779 | S32 mTrueReceiveSize; | 791 | S32 mTrueReceiveSize; |
780 | 792 | ||
781 | // Must be valid during decode | 793 | // Must be valid during decode |
diff --git a/linden/indra/llmessage/net.cpp b/linden/indra/llmessage/net.cpp index f63faa5..6db7214 100644 --- a/linden/indra/llmessage/net.cpp +++ b/linden/indra/llmessage/net.cpp | |||
@@ -56,6 +56,7 @@ | |||
56 | #include "lltimer.h" | 56 | #include "lltimer.h" |
57 | #include "indra_constants.h" | 57 | #include "indra_constants.h" |
58 | 58 | ||
59 | #include "llsocks5.h" | ||
59 | 60 | ||
60 | // Globals | 61 | // Globals |
61 | #if LL_WINDOWS | 62 | #if LL_WINDOWS |
@@ -179,7 +180,91 @@ U32 ip_string_to_u32(const char* ip_string) | |||
179 | ////////////////////////////////////////////////////////////////////////////////////////// | 180 | ////////////////////////////////////////////////////////////////////////////////////////// |
180 | 181 | ||
181 | #if LL_WINDOWS | 182 | #if LL_WINDOWS |
182 | 183 | ||
184 | int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen) | ||
185 | { | ||
186 | int result; | ||
187 | result = send(handle, dataout, outlen, 0); | ||
188 | if (result != outlen) | ||
189 | { | ||
190 | S32 err = WSAGetLastError(); | ||
191 | llwarns << "Error sending data to proxy control channel, number of bytes sent were " << result << " error code was " << err << llendl; | ||
192 | return -1; | ||
193 | } | ||
194 | |||
195 | result = recv(handle, datain, maxinlen, 0); | ||
196 | if (result != maxinlen) | ||
197 | { | ||
198 | S32 err = WSAGetLastError(); | ||
199 | llwarns << "Error receiving data from proxy control channel, number of bytes received were " << result << " error code was " << err << llendl; | ||
200 | return -1; | ||
201 | } | ||
202 | |||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | S32 tcp_open_channel(LLHost host) | ||
207 | { | ||
208 | // Open a TCP channel | ||
209 | // Jump through some hoops to ensure that if the request hosts is down | ||
210 | // or not reachable connect() does not block | ||
211 | |||
212 | S32 handle; | ||
213 | handle = socket(AF_INET, SOCK_STREAM, 0); | ||
214 | if (!handle) | ||
215 | { | ||
216 | llwarns << "Error opening TCP control socket, socket() returned " << handle << llendl; | ||
217 | return -1; | ||
218 | } | ||
219 | |||
220 | struct sockaddr_in address; | ||
221 | address.sin_port = htons(host.getPort()); | ||
222 | address.sin_family = AF_INET; | ||
223 | address.sin_addr.s_addr = host.getAddress(); | ||
224 | |||
225 | // Non blocking | ||
226 | WSAEVENT hEvent=WSACreateEvent(); | ||
227 | WSAEventSelect(handle, hEvent, FD_CONNECT) ; | ||
228 | connect(handle, (struct sockaddr*)&address, sizeof(address)) ; | ||
229 | // Wait fot 5 seconds, if we can't get a TCP channel open in this | ||
230 | // time frame then there is something badly wrong. | ||
231 | WaitForSingleObject(hEvent, 1000*5); // 5 seconds time out | ||
232 | |||
233 | WSANETWORKEVENTS netevents; | ||
234 | WSAEnumNetworkEvents(handle,hEvent,&netevents); | ||
235 | |||
236 | // Check the async event status to see if we connected | ||
237 | if ((netevents.lNetworkEvents & FD_CONNECT) == FD_CONNECT) | ||
238 | { | ||
239 | if (netevents.iErrorCode[FD_CONNECT_BIT] != 0) | ||
240 | { | ||
241 | llwarns << "Unable to open TCP channel, WSA returned an error code of " << netevents.iErrorCode[FD_CONNECT_BIT] << llendl; | ||
242 | WSACloseEvent(hEvent); | ||
243 | return -1; | ||
244 | } | ||
245 | |||
246 | // Now we are connected disable non blocking | ||
247 | // we don't need support an async interface as | ||
248 | // currently our only consumer (socks5) will make one round | ||
249 | // of packets then just hold the connection open | ||
250 | WSAEventSelect(handle, hEvent, NULL) ; | ||
251 | unsigned long NonBlock = 0; | ||
252 | ioctlsocket(handle, FIONBIO, &NonBlock); | ||
253 | |||
254 | return handle; | ||
255 | } | ||
256 | |||
257 | llwarns << "Unable to open TCP channel, Timeout is the host up?" << netevents.iErrorCode[FD_CONNECT_BIT] << llendl; | ||
258 | return -1; | ||
259 | } | ||
260 | |||
261 | void tcp_close_channel(S32 handle) | ||
262 | { | ||
263 | llinfos << "Closing TCP channel" << llendl; | ||
264 | shutdown(handle, SD_BOTH); | ||
265 | closesocket(handle); | ||
266 | } | ||
267 | |||
183 | S32 start_net(S32& socket_out, int& nPort) | 268 | S32 start_net(S32& socket_out, int& nPort) |
184 | { | 269 | { |
185 | // Create socket, make non-blocking | 270 | // Create socket, make non-blocking |
@@ -377,6 +462,77 @@ BOOL send_packet(int hSocket, const char *sendBuffer, int size, U32 recipient, i | |||
377 | 462 | ||
378 | #else | 463 | #else |
379 | 464 | ||
465 | |||
466 | int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen) | ||
467 | { | ||
468 | if (send(handle, dataout, outlen, 0) != outlen) | ||
469 | { | ||
470 | llwarns << "Error sending data to proxy control channel" << llendl; | ||
471 | return -1; | ||
472 | } | ||
473 | |||
474 | if (recv(handle, datain, maxinlen, 0) != maxinlen) | ||
475 | { | ||
476 | llwarns << "Error receiving data to proxy control channel" << llendl; | ||
477 | return -1; | ||
478 | } | ||
479 | |||
480 | return 0; | ||
481 | } | ||
482 | |||
483 | S32 tcp_open_channel(LLHost host) | ||
484 | { | ||
485 | S32 handle; | ||
486 | handle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); | ||
487 | if (!handle) | ||
488 | { | ||
489 | llwarns << "Error opening TCP control socket, socket() returned " << handle << llendl; | ||
490 | return -1; | ||
491 | } | ||
492 | |||
493 | struct sockaddr_in address; | ||
494 | address.sin_port = htons(host.getPort()); | ||
495 | address.sin_family = AF_INET; | ||
496 | address.sin_addr.s_addr = host.getAddress(); | ||
497 | |||
498 | // Set the socket to non blocking for the connect() | ||
499 | int flags = fcntl(handle, F_GETFL, 0); | ||
500 | fcntl(handle, F_SETFL, flags | O_NONBLOCK); | ||
501 | |||
502 | S32 error = connect(handle, (sockaddr*)&address, sizeof(address)); | ||
503 | if (error && (errno != EINPROGRESS)) | ||
504 | { | ||
505 | llwarns << "Unable to open TCP channel, error code: " << errno << llendl; | ||
506 | return -1; | ||
507 | } | ||
508 | |||
509 | struct timeval timeout; | ||
510 | timeout.tv_sec = 5; // Maximum time to wait for the connect() to complete | ||
511 | timeout.tv_usec = 0; | ||
512 | fd_set fds; | ||
513 | FD_ZERO(&fds); | ||
514 | FD_SET(handle, &fds); | ||
515 | |||
516 | // See if we have connectde or time out after 5 seconds | ||
517 | U32 rc = select(sizeof(fds)*8, NULL, &fds, NULL, &timeout); | ||
518 | |||
519 | if (rc != 1) // we require exactly one descriptor to be set | ||
520 | { | ||
521 | llwarns << "Unable to open TCP channel" << llendl; | ||
522 | return -1; | ||
523 | } | ||
524 | |||
525 | // Return the socket to blocking operations | ||
526 | fcntl(handle, F_SETFL, flags); | ||
527 | |||
528 | return handle; | ||
529 | } | ||
530 | |||
531 | void tcp_close_channel(S32 handle) | ||
532 | { | ||
533 | close(handle); | ||
534 | } | ||
535 | |||
380 | // Create socket, make non-blocking | 536 | // Create socket, make non-blocking |
381 | S32 start_net(S32& socket_out, int& nPort) | 537 | S32 start_net(S32& socket_out, int& nPort) |
382 | { | 538 | { |
diff --git a/linden/indra/llmessage/net.h b/linden/indra/llmessage/net.h index 45b07a0..531b5c3 100644 --- a/linden/indra/llmessage/net.h +++ b/linden/indra/llmessage/net.h | |||
@@ -64,6 +64,9 @@ U32 ip_string_to_u32(const char* ip_string); // Wrapper for inet_addr() | |||
64 | 64 | ||
65 | extern const char* LOOPBACK_ADDRESS_STRING; | 65 | extern const char* LOOPBACK_ADDRESS_STRING; |
66 | 66 | ||
67 | void tcp_close_channel(S32 handle); | ||
68 | S32 tcp_open_channel(LLHost host); | ||
69 | int tcp_handshake(S32 handle, char * dataout, int outlen, char * datain, int maxinlen); | ||
67 | 70 | ||
68 | // useful MTU consts | 71 | // useful MTU consts |
69 | 72 | ||
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 00c30c1..3523c7f 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml | |||
@@ -2,7 +2,9 @@ | |||
2 | <llsd> | 2 | <llsd> |
3 | <map> | 3 | <map> |
4 | 4 | ||
5 | <!-- for Aurora Sim --> | 5 | <!-- BEGIN IMPRUDENCE-SPECIFIC SETTINGS --> |
6 | |||
7 | <!-- begin Aurora-specific settings --> | ||
6 | 8 | ||
7 | <key>TimeOffset</key> | 9 | <key>TimeOffset</key> |
8 | <map> | 10 | <map> |
@@ -48,7 +50,8 @@ | |||
48 | <key>Value</key> | 50 | <key>Value</key> |
49 | <string>SLVoice</string> | 51 | <string>SLVoice</string> |
50 | </map> | 52 | </map> |
51 | <!-- Imprudence-specific settings --> | 53 | |
54 | <!-- end Aurora-specific settings --> | ||
52 | 55 | ||
53 | <key>AllowEditingOfTrees</key> | 56 | <key>AllowEditingOfTrees</key> |
54 | <map> | 57 | <map> |
@@ -1689,6 +1692,7 @@ | |||
1689 | </map> | 1692 | </map> |
1690 | 1693 | ||
1691 | <!-- Begin: Client Name Tag --> | 1694 | <!-- Begin: Client Name Tag --> |
1695 | |||
1692 | <key>ShowClientColor</key> | 1696 | <key>ShowClientColor</key> |
1693 | <map> | 1697 | <map> |
1694 | <key>Comment</key> | 1698 | <key>Comment</key> |
@@ -2091,6 +2095,8 @@ | |||
2091 | </map> | 2095 | </map> |
2092 | 2096 | ||
2093 | <!-- End: Spellcheck & Translation --> | 2097 | <!-- End: Spellcheck & Translation --> |
2098 | |||
2099 | <!-- Begin: RLVa --> | ||
2094 | 2100 | ||
2095 | <key>RestrainedLove</key> | 2101 | <key>RestrainedLove</key> |
2096 | <map> | 2102 | <map> |
@@ -2268,6 +2274,93 @@ | |||
2268 | <key>Value</key> | 2274 | <key>Value</key> |
2269 | <integer>1</integer> | 2275 | <integer>1</integer> |
2270 | </map> | 2276 | </map> |
2277 | |||
2278 | <!-- End: RLVa --> | ||
2279 | |||
2280 | <!-- Begin: socks5 --> | ||
2281 | |||
2282 | <key>Socks5ProxyEnabled</key> | ||
2283 | <map> | ||
2284 | <key>Comment</key> | ||
2285 | <string>Use Socks5 Proxy</string> | ||
2286 | <key>Persist</key> | ||
2287 | <integer>1</integer> | ||
2288 | <key>Type</key> | ||
2289 | <string>Boolean</string> | ||
2290 | <key>Value</key> | ||
2291 | <integer>0</integer> | ||
2292 | </map> | ||
2293 | <key>Socks5HttpProxyType</key> | ||
2294 | <map> | ||
2295 | <key>Comment</key> | ||
2296 | <string>Proxy type to use for HTTP operations</string> | ||
2297 | <key>Persist</key> | ||
2298 | <integer>1</integer> | ||
2299 | <key>Type</key> | ||
2300 | <string>String</string> | ||
2301 | <key>Value</key> | ||
2302 | <integer>None</integer> | ||
2303 | </map> | ||
2304 | <key>Socks5ProxyHost</key> | ||
2305 | <map> | ||
2306 | <key>Comment</key> | ||
2307 | <string>Socks 5 Proxy Host</string> | ||
2308 | <key>Persist</key> | ||
2309 | <integer>1</integer> | ||
2310 | <key>Type</key> | ||
2311 | <string>String</string> | ||
2312 | <key>Value</key> | ||
2313 | <string /> | ||
2314 | </map> | ||
2315 | <key>Socks5ProxyPort</key> | ||
2316 | <map> | ||
2317 | <key>Comment</key> | ||
2318 | <string>Socks 5 Proxy Port</string> | ||
2319 | <key>Persist</key> | ||
2320 | <integer>1</integer> | ||
2321 | <key>Type</key> | ||
2322 | <string>U32</string> | ||
2323 | <key>Value</key> | ||
2324 | <integer>1080</integer> | ||
2325 | </map> | ||
2326 | <key>Socks5Username</key> | ||
2327 | <map> | ||
2328 | <key>Comment</key> | ||
2329 | <string>Socks 5 Username</string> | ||
2330 | <key>Persist</key> | ||
2331 | <integer>1</integer> | ||
2332 | <key>Type</key> | ||
2333 | <string>String</string> | ||
2334 | <key>Value</key> | ||
2335 | <string></string> | ||
2336 | </map> | ||
2337 | <key>Socks5Password</key> | ||
2338 | <map> | ||
2339 | <key>Comment</key> | ||
2340 | <string>Socks 5 Password</string> | ||
2341 | <key>Persist</key> | ||
2342 | <integer>1</integer> | ||
2343 | <key>Type</key> | ||
2344 | <string>String</string> | ||
2345 | <key>Value</key> | ||
2346 | <string></string> | ||
2347 | </map> | ||
2348 | <key>Socks5AuthType</key> | ||
2349 | <map> | ||
2350 | <key>Comment</key> | ||
2351 | <string>Selected Auth mechanism for Socks5</string> | ||
2352 | <key>Persist</key> | ||
2353 | <integer>1</integer> | ||
2354 | <key>Type</key> | ||
2355 | <string>String</string> | ||
2356 | <key>Value</key> | ||
2357 | <string>None</string> | ||
2358 | </map> | ||
2359 | |||
2360 | <!-- End: socks5 --> | ||
2361 | |||
2362 | <!-- END IMPRUDENCE-SPECIFIC SETTINGS --> | ||
2363 | |||
2271 | <key>AFKTimeout</key> | 2364 | <key>AFKTimeout</key> |
2272 | <map> | 2365 | <map> |
2273 | <key>Comment</key> | 2366 | <key>Comment</key> |
@@ -3024,7 +3117,7 @@ | |||
3024 | <key>BrowserProxyAddress</key> | 3117 | <key>BrowserProxyAddress</key> |
3025 | <map> | 3118 | <map> |
3026 | <key>Comment</key> | 3119 | <key>Comment</key> |
3027 | <string>Address for the Web Proxy]</string> | 3120 | <string>Address for the Web Proxy</string> |
3028 | <key>Persist</key> | 3121 | <key>Persist</key> |
3029 | <integer>1</integer> | 3122 | <integer>1</integer> |
3030 | <key>Type</key> | 3123 | <key>Type</key> |
diff --git a/linden/indra/newview/llpanelnetwork.cpp b/linden/indra/newview/llpanelnetwork.cpp index 16b9a76..a371962 100644 --- a/linden/indra/newview/llpanelnetwork.cpp +++ b/linden/indra/newview/llpanelnetwork.cpp | |||
@@ -34,14 +34,18 @@ | |||
34 | 34 | ||
35 | //file include | 35 | //file include |
36 | #include "llpanelnetwork.h" | 36 | #include "llpanelnetwork.h" |
37 | #include "llstartup.h" | ||
37 | 38 | ||
38 | // project includes | 39 | // project includes |
39 | #include "llcheckboxctrl.h" | 40 | #include "llcheckboxctrl.h" |
41 | #include "llradiogroup.h" | ||
40 | #include "lldirpicker.h" | 42 | #include "lldirpicker.h" |
41 | #include "lluictrlfactory.h" | 43 | #include "lluictrlfactory.h" |
42 | #include "llviewercontrol.h" | 44 | #include "llviewercontrol.h" |
43 | #include "llviewerwindow.h" | 45 | #include "llviewerwindow.h" |
44 | 46 | ||
47 | bool LLPanelNetwork::sSocksSettingsChanged; | ||
48 | |||
45 | LLPanelNetwork::LLPanelNetwork() | 49 | LLPanelNetwork::LLPanelNetwork() |
46 | { | 50 | { |
47 | LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_network.xml"); | 51 | LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_network.xml"); |
@@ -72,6 +76,31 @@ BOOL LLPanelNetwork::postBuild() | |||
72 | childSetEnabled("xmlrpc_proxy_editor", gSavedSettings.getBOOL("XMLRPCProxyEnabled")); | 76 | childSetEnabled("xmlrpc_proxy_editor", gSavedSettings.getBOOL("XMLRPCProxyEnabled")); |
73 | childSetEnabled("xmlrpc_proxy_port", gSavedSettings.getBOOL("XMLRPCProxyEnabled")); | 77 | childSetEnabled("xmlrpc_proxy_port", gSavedSettings.getBOOL("XMLRPCProxyEnabled")); |
74 | 78 | ||
79 | // Socks 5 proxy settings, commit callbacks | ||
80 | childSetCommitCallback("socks5_proxy_enabled", onCommitSocks5ProxyEnabled, this); | ||
81 | childSetCommitCallback("socks5_auth", onSocksAuthChanged, this); | ||
82 | |||
83 | //Socks 5 proxy settings, saved data | ||
84 | childSetValue("socks5_proxy_enabled", gSavedSettings.getBOOL("Socks5ProxyEnabled")); | ||
85 | childSetValue("socks5_http_proxy_type", gSavedSettings.getString("Socks5HttpProxyType")); | ||
86 | |||
87 | childSetValue("socks5_proxy_host", gSavedSettings.getString("Socks5ProxyHost")); | ||
88 | childSetValue("socks5_proxy_port", (F32)gSavedSettings.getU32("Socks5ProxyPort")); | ||
89 | childSetValue("socks5_proxy_username", gSavedSettings.getString("Socks5Username")); | ||
90 | childSetValue("socks5_proxy_password", gSavedSettings.getString("Socks5Password")); | ||
91 | childSetValue("socks5_auth", gSavedSettings.getString("Socks5AuthType")); | ||
92 | |||
93 | // Socks 5 proxy settings, check if settings modified callbacks | ||
94 | childSetCommitCallback("socks5_proxy_host", onSocksSettingsModified,this); | ||
95 | childSetCommitCallback("socks5_proxy_port", onSocksSettingsModified,this); | ||
96 | childSetCommitCallback("socks5_proxy_username", onSocksSettingsModified,this); | ||
97 | childSetCommitCallback("socks5_proxy_password", onSocksSettingsModified,this); | ||
98 | |||
99 | // Socks 5 settings, Set all controls and labels enabled state | ||
100 | updateProxyEnabled(this, gSavedSettings.getBOOL("Socks5ProxyEnabled"), gSavedSettings.getString("Socks5AuthType")); | ||
101 | |||
102 | sSocksSettingsChanged = false; | ||
103 | |||
75 | return TRUE; | 104 | return TRUE; |
76 | } | 105 | } |
77 | 106 | ||
@@ -91,6 +120,28 @@ void LLPanelNetwork::apply() | |||
91 | gSavedSettings.setBOOL("XMLRPCProxyEnabled", childGetValue("xmlrpc_proxy_enabled")); | 120 | gSavedSettings.setBOOL("XMLRPCProxyEnabled", childGetValue("xmlrpc_proxy_enabled")); |
92 | gSavedSettings.setString("XMLRPCProxyAddress", childGetValue("xmlrpc_proxy_editor")); | 121 | gSavedSettings.setString("XMLRPCProxyAddress", childGetValue("xmlrpc_proxy_editor")); |
93 | gSavedSettings.setS32("XMLRPCProxyPort", childGetValue("xmlrpc_proxy_port")); | 122 | gSavedSettings.setS32("XMLRPCProxyPort", childGetValue("xmlrpc_proxy_port")); |
123 | |||
124 | gSavedSettings.setBOOL("Socks5ProxyEnabled", childGetValue("socks5_proxy_enabled")); | ||
125 | gSavedSettings.setString("Socks5HttpProxyType", childGetValue("socks5_http_proxy_type")); | ||
126 | gSavedSettings.setString("Socks5ProxyHost", childGetValue("socks5_proxy_host")); | ||
127 | gSavedSettings.setU32("Socks5ProxyPort", childGetValue("socks5_proxy_port").asInteger()); | ||
128 | |||
129 | gSavedSettings.setString("Socks5AuthType", childGetValue("socks5_auth")); | ||
130 | gSavedSettings.setString("Socks5Username", childGetValue("socks5_proxy_username")); | ||
131 | gSavedSettings.setString("Socks5Password", childGetValue("socks5_proxy_password")); | ||
132 | |||
133 | if (sSocksSettingsChanged) | ||
134 | { | ||
135 | if (LLStartUp::getStartupState() != STATE_LOGIN_WAIT) | ||
136 | { | ||
137 | LLNotifications::instance().add("ProxyNeedRestart"); | ||
138 | } | ||
139 | else | ||
140 | { | ||
141 | // Mark the socks class that it needs to update its connection | ||
142 | LLSocks::getInstance()->updated(); | ||
143 | } | ||
144 | } | ||
94 | } | 145 | } |
95 | 146 | ||
96 | void LLPanelNetwork::cancel() | 147 | void LLPanelNetwork::cancel() |
@@ -167,4 +218,77 @@ void LLPanelNetwork::onCommitXMLRPCProxyEnabled(LLUICtrl* ctrl, void* data) | |||
167 | self->childSetEnabled("xmlrpc_proxy_editor", check->get()); | 218 | self->childSetEnabled("xmlrpc_proxy_editor", check->get()); |
168 | self->childSetEnabled("xmlrpc_proxy_port", check->get()); | 219 | self->childSetEnabled("xmlrpc_proxy_port", check->get()); |
169 | self->childSetEnabled("xmlrpc_proxy_text_label", check->get()); | 220 | self->childSetEnabled("xmlrpc_proxy_text_label", check->get()); |
170 | } \ No newline at end of file | 221 | } |
222 | |||
223 | // static | ||
224 | void LLPanelNetwork::onCommitSocks5ProxyEnabled(LLUICtrl* ctrl, void* data) | ||
225 | { | ||
226 | LLPanelNetwork* self = (LLPanelNetwork*)data; | ||
227 | LLCheckBoxCtrl* check = (LLCheckBoxCtrl*)ctrl; | ||
228 | |||
229 | if (!self || !check) return; | ||
230 | |||
231 | sSocksSettingsChanged = true; | ||
232 | |||
233 | updateProxyEnabled(self, check->get(), self->childGetValue("socks5_auth")); | ||
234 | } | ||
235 | |||
236 | // static | ||
237 | void LLPanelNetwork::onSocksSettingsModified(LLUICtrl* ctrl, void* data) | ||
238 | { | ||
239 | sSocksSettingsChanged = true; | ||
240 | } | ||
241 | |||
242 | // static | ||
243 | void LLPanelNetwork::onSocksAuthChanged(LLUICtrl* ctrl, void* data) | ||
244 | { | ||
245 | LLRadioGroup* radio = static_cast<LLRadioGroup*>(ctrl); | ||
246 | LLPanelNetwork* self = static_cast<LLPanelNetwork*>(data); | ||
247 | |||
248 | sSocksSettingsChanged = true; | ||
249 | |||
250 | std::string selection = radio->getValue().asString(); | ||
251 | updateProxyEnabled(self, true, selection); | ||
252 | } | ||
253 | |||
254 | // static | ||
255 | void LLPanelNetwork::updateProxyEnabled(LLPanelNetwork * self, bool enabled, std::string authtype) | ||
256 | { | ||
257 | // Manage all the enable/disable of the socks5 options from this single function | ||
258 | // to avoid code duplication | ||
259 | |||
260 | // Update all socks labels and controls except auth specific ones | ||
261 | self->childSetEnabled("socks5_proxy_port", enabled); | ||
262 | self->childSetEnabled("socks5_proxy_host", enabled); | ||
263 | self->childSetEnabled("socks5_host_label", enabled); | ||
264 | self->childSetEnabled("socks5_proxy_label", enabled); | ||
265 | self->childSetEnabled("socks5_proxy_port", enabled); | ||
266 | self->childSetEnabled("socks5_auth_label", enabled); | ||
267 | self->childSetEnabled("socks5_auth", enabled); | ||
268 | |||
269 | // disable the web option if the web proxy has not been configured | ||
270 | // this is still not ideal as apply or ok is needed for this to be saved to the preferences | ||
271 | self->childSetEnabled("Web", gSavedSettings.getBOOL("BrowserProxyEnabled")); | ||
272 | |||
273 | self->childSetEnabled("Socks", enabled); | ||
274 | |||
275 | // Hide the auth specific lables if authtype is none or | ||
276 | // we are not enabled. | ||
277 | if ((authtype.compare("None") == 0) || (enabled == false)) | ||
278 | { | ||
279 | self->childSetEnabled("socks5_username_label", false); | ||
280 | self->childSetEnabled("socks5_password_label", false); | ||
281 | self->childSetEnabled("socks5_proxy_username", false); | ||
282 | self->childSetEnabled("socks5_proxy_password", false); | ||
283 | } | ||
284 | |||
285 | // Only show the username and password boxes if we are enabled | ||
286 | // and authtype is username pasword. | ||
287 | if ((authtype.compare("UserPass") == 0) && (enabled == true)) | ||
288 | { | ||
289 | self->childSetEnabled("socks5_username_label", true); | ||
290 | self->childSetEnabled("socks5_password_label", true); | ||
291 | self->childSetEnabled("socks5_proxy_username", true); | ||
292 | self->childSetEnabled("socks5_proxy_password", true); | ||
293 | } | ||
294 | } | ||
diff --git a/linden/indra/newview/llpanelnetwork.h b/linden/indra/newview/llpanelnetwork.h index 900158a..628f713 100644 --- a/linden/indra/newview/llpanelnetwork.h +++ b/linden/indra/newview/llpanelnetwork.h | |||
@@ -52,6 +52,14 @@ private: | |||
52 | static void onClickResetCache(void*); | 52 | static void onClickResetCache(void*); |
53 | static void onCommitPort(LLUICtrl* ctrl, void*); | 53 | static void onCommitPort(LLUICtrl* ctrl, void*); |
54 | static void onCommitXMLRPCProxyEnabled(LLUICtrl* ctrl, void* data); | 54 | static void onCommitXMLRPCProxyEnabled(LLUICtrl* ctrl, void* data); |
55 | static void onCommitSocks5ProxyEnabled(LLUICtrl* ctrl, void* data); | ||
56 | static void onClickTestProxy(void* user_data); | ||
57 | static void onSocksSettingsModified(LLUICtrl* ctrl, void* data); | ||
58 | static void onSocksAuthChanged(LLUICtrl* ctrl, void* data); | ||
59 | static void updateProxyEnabled(LLPanelNetwork * self, bool enabled, std::string authtype); | ||
60 | |||
61 | static bool sSocksSettingsChanged; | ||
62 | |||
55 | }; | 63 | }; |
56 | 64 | ||
57 | #endif | 65 | #endif |
diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 8e11d8c..80ddfa4 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp | |||
@@ -189,6 +189,7 @@ | |||
189 | #include "llwlparammanager.h" | 189 | #include "llwlparammanager.h" |
190 | #include "llwaterparammanager.h" | 190 | #include "llwaterparammanager.h" |
191 | #include "llagentlanguage.h" | 191 | #include "llagentlanguage.h" |
192 | #include "llsocks5.h" | ||
192 | #include "viewerversion.h" | 193 | #include "viewerversion.h" |
193 | 194 | ||
194 | #include "lgghunspell_wrapper.h" | 195 | #include "lgghunspell_wrapper.h" |
@@ -635,6 +636,15 @@ bool idle_startup() | |||
635 | LL_INFOS("AppInit") << "Message System Initialized." << LL_ENDL; | 636 | LL_INFOS("AppInit") << "Message System Initialized." << LL_ENDL; |
636 | 637 | ||
637 | //------------------------------------------------- | 638 | //------------------------------------------------- |
639 | // Init the socks 5 proxy and open the control TCP | ||
640 | // connection if the user is using SOCKS5 | ||
641 | // We need to do this early incase the user is using | ||
642 | // socks for http so we get the login screen via socks | ||
643 | //------------------------------------------------- | ||
644 | |||
645 | LLStartUp::handleSocksProxy(false); | ||
646 | |||
647 | //------------------------------------------------- | ||
638 | // Init audio, which may be needed for prefs dialog | 648 | // Init audio, which may be needed for prefs dialog |
639 | // or audio cues in connection UI. | 649 | // or audio cues in connection UI. |
640 | //------------------------------------------------- | 650 | //------------------------------------------------- |
@@ -890,8 +900,31 @@ bool idle_startup() | |||
890 | 900 | ||
891 | if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState()) | 901 | if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState()) |
892 | { | 902 | { |
893 | |||
894 | LL_DEBUGS("AppInitStartupState") << "STATE_LOGIN_CLEANUP" << LL_ENDL; | 903 | LL_DEBUGS("AppInitStartupState") << "STATE_LOGIN_CLEANUP" << LL_ENDL; |
904 | |||
905 | // Post login screen, we should see if any settings have changed that may | ||
906 | // require us to either start/stop or change the socks proxy. As various communications | ||
907 | // past this point may require the proxy to be up. | ||
908 | bool socks_enable_required = gSavedSettings.getBOOL("Socks5ProxyEnabled"); | ||
909 | if ((LLSocks::getInstance()->isEnabled() != socks_enable_required) || LLSocks::getInstance()->needsUpdate()) | ||
910 | { | ||
911 | if (socks_enable_required) | ||
912 | { | ||
913 | if (!LLStartUp::handleSocksProxy(false)) | ||
914 | { | ||
915 | // Proxy start up failed, we should now bail the state machine | ||
916 | // HandleSocksProxy() will have reported an error to the user | ||
917 | // already, so we just go back to the login screen. The user | ||
918 | // could then change the perferences to fix the issue. | ||
919 | LLStartUp::setStartupState(STATE_LOGIN_SHOW); | ||
920 | return FALSE; | ||
921 | } | ||
922 | } | ||
923 | else | ||
924 | { | ||
925 | LLSocks::getInstance()->stopProxy(); | ||
926 | } | ||
927 | } | ||
895 | 928 | ||
896 | gDisconnected = TRUE; | 929 | gDisconnected = TRUE; |
897 | 930 | ||
@@ -4022,3 +4055,93 @@ void apply_udp_blacklist(const std::string& csv) | |||
4022 | 4055 | ||
4023 | } | 4056 | } |
4024 | 4057 | ||
4058 | bool LLStartUp::handleSocksProxy(bool reportOK) | ||
4059 | { | ||
4060 | std::string httpProxyType = gSavedSettings.getString("Socks5HttpProxyType"); | ||
4061 | |||
4062 | // Determine the http proxy type (if any) | ||
4063 | if ((httpProxyType.compare("Web") == 0) && gSavedSettings.getBOOL("BrowserProxyEnabled")) | ||
4064 | { | ||
4065 | LLHost httpHost; | ||
4066 | httpHost.setHostByName(gSavedSettings.getString("BrowserProxyAddress")); | ||
4067 | httpHost.setPort(gSavedSettings.getS32("BrowserProxyPort")); | ||
4068 | LLSocks::getInstance()->EnableHttpProxy(httpHost,LLPROXY_HTTP); | ||
4069 | } | ||
4070 | else if ((httpProxyType.compare("Socks") == 0) && gSavedSettings.getBOOL("Socks5ProxyEnabled")) | ||
4071 | { | ||
4072 | LLHost httpHost; | ||
4073 | httpHost.setHostByName(gSavedSettings.getString("Socks5ProxyHost")); | ||
4074 | httpHost.setPort(gSavedSettings.getU32("Socks5ProxyPort")); | ||
4075 | LLSocks::getInstance()->EnableHttpProxy(httpHost,LLPROXY_SOCKS); | ||
4076 | } | ||
4077 | else | ||
4078 | { | ||
4079 | LLSocks::getInstance()->DisableHttpProxy(); | ||
4080 | } | ||
4081 | |||
4082 | bool use_socks_proxy = gSavedSettings.getBOOL("Socks5ProxyEnabled"); | ||
4083 | if (use_socks_proxy) | ||
4084 | { | ||
4085 | |||
4086 | // Determine and update LLSocks with the saved authentication system | ||
4087 | std::string auth_type = gSavedSettings.getString("Socks5AuthType"); | ||
4088 | |||
4089 | if (auth_type.compare("None") == 0) | ||
4090 | { | ||
4091 | LLSocks::getInstance()->setAuthNone(); | ||
4092 | } | ||
4093 | |||
4094 | if (auth_type.compare("UserPass") == 0) | ||
4095 | { | ||
4096 | LLSocks::getInstance()->setAuthPassword(gSavedSettings.getString("Socks5Username"),gSavedSettings.getString("Socks5Password")); | ||
4097 | } | ||
4098 | |||
4099 | // Start the proxy and check for errors | ||
4100 | int status = LLSocks::getInstance()->startProxy(gSavedSettings.getString("Socks5ProxyHost"), gSavedSettings.getU32("Socks5ProxyPort")); | ||
4101 | LLSD subs; | ||
4102 | subs["PROXY"] = gSavedSettings.getString("Socks5ProxyHost"); | ||
4103 | |||
4104 | switch(status) | ||
4105 | { | ||
4106 | case SOCKS_OK: | ||
4107 | if (reportOK == true) | ||
4108 | { | ||
4109 | LLNotifications::instance().add("SOCKS_CONNECT_OK", subs); | ||
4110 | } | ||
4111 | return true; | ||
4112 | break; | ||
4113 | |||
4114 | case SOCKS_CONNECT_ERROR: // TCP Fail | ||
4115 | LLNotifications::instance().add("SOCKS_CONNECT_ERROR", subs); | ||
4116 | break; | ||
4117 | |||
4118 | case SOCKS_NOT_PERMITTED: // Socks5 server rule set refused connection | ||
4119 | LLNotifications::instance().add("SOCKS_NOT_PERMITTED", subs); | ||
4120 | break; | ||
4121 | |||
4122 | case SOCKS_NOT_ACCEPTABLE: // Selected authentication is not acceptable to server | ||
4123 | LLNotifications::instance().add("SOCKS_NOT_ACCEPTABLE", subs); | ||
4124 | break; | ||
4125 | |||
4126 | case SOCKS_AUTH_FAIL: // Authentication failed | ||
4127 | LLNotifications::instance().add("SOCKS_AUTH_FAIL", subs); | ||
4128 | break; | ||
4129 | |||
4130 | case SOCKS_UDP_FWD_NOT_GRANTED: // UDP forward request failed | ||
4131 | LLNotifications::instance().add("SOCKS_UDP_FWD_NOT_GRANTED", subs); | ||
4132 | break; | ||
4133 | |||
4134 | case SOCKS_HOST_CONNECT_FAILED: // Failed to open a TCP channel to the socks server | ||
4135 | LLNotifications::instance().add("SOCKS_HOST_CONNECT_FAILED", subs); | ||
4136 | break; | ||
4137 | } | ||
4138 | |||
4139 | return false; | ||
4140 | } | ||
4141 | else | ||
4142 | { | ||
4143 | LLSocks::getInstance()->stopProxy(); //ensure no UDP proxy is running and its all cleaned up | ||
4144 | } | ||
4145 | |||
4146 | return true; | ||
4147 | } | ||
diff --git a/linden/indra/newview/llstartup.h b/linden/indra/newview/llstartup.h index 3fe8daa..6dc3946 100644 --- a/linden/indra/newview/llstartup.h +++ b/linden/indra/newview/llstartup.h | |||
@@ -123,6 +123,9 @@ public: | |||
123 | static std::string sSLURLCommand; | 123 | static std::string sSLURLCommand; |
124 | // *HACK: On startup, if we were passed a secondlife://app/do/foo | 124 | // *HACK: On startup, if we were passed a secondlife://app/do/foo |
125 | // command URL, store it for later processing. | 125 | // command URL, store it for later processing. |
126 | |||
127 | static bool handleSocksProxy(bool reportOK = true); | ||
128 | |||
126 | static bool shouldAutoLogin() { return mShouldAutoLogin; }; | 129 | static bool shouldAutoLogin() { return mShouldAutoLogin; }; |
127 | static void setShouldAutoLogin(bool value) { mShouldAutoLogin = value; }; | 130 | static void setShouldAutoLogin(bool value) { mShouldAutoLogin = value; }; |
128 | 131 | ||
diff --git a/linden/indra/newview/llxmlrpctransaction.cpp b/linden/indra/newview/llxmlrpctransaction.cpp index 675ba42..30b0249 100644 --- a/linden/indra/newview/llxmlrpctransaction.cpp +++ b/linden/indra/newview/llxmlrpctransaction.cpp | |||
@@ -236,6 +236,23 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip) | |||
236 | mCurlRequest->setopt(CURLOPT_PROXYPORT, port); | 236 | mCurlRequest->setopt(CURLOPT_PROXYPORT, port); |
237 | mCurlRequest->setopt(CURLOPT_PROXYTYPE, CURLPROXY_HTTP); | 237 | mCurlRequest->setopt(CURLOPT_PROXYTYPE, CURLPROXY_HTTP); |
238 | } | 238 | } |
239 | else if (LLSocks::getInstance()->isHttpProxyEnabled()) | ||
240 | { | ||
241 | std::string address = LLSocks::getInstance()->getHTTPProxy().getIPString(); | ||
242 | U16 port = LLSocks::getInstance()->getHTTPProxy().getPort(); | ||
243 | mCurlRequest->setoptString(CURLOPT_PROXY, address.c_str()); | ||
244 | mCurlRequest->setopt(CURLOPT_PROXYPORT, port); | ||
245 | if (LLSocks::getInstance()->getHttpProxyType() == LLPROXY_SOCKS) | ||
246 | { | ||
247 | mCurlRequest->setopt(CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); | ||
248 | if(LLSocks::getInstance()->getSelectedAuthMethod()==METHOD_PASSWORD) | ||
249 | mCurlRequest->setoptString(CURLOPT_PROXYUSERPWD,LLSocks::getInstance()->getProxyUserPwd()); | ||
250 | } | ||
251 | else | ||
252 | { | ||
253 | mCurlRequest->setopt(CURLOPT_PROXYTYPE, CURLPROXY_HTTP); | ||
254 | } | ||
255 | } | ||
239 | 256 | ||
240 | // mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // usefull for debugging | 257 | // mCurlRequest->setopt(CURLOPT_VERBOSE, 1); // usefull for debugging |
241 | mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1); | 258 | mCurlRequest->setopt(CURLOPT_NOSIGNAL, 1); |
diff --git a/linden/indra/newview/skins/default/xui/en-us/notifications.xml b/linden/indra/newview/skins/default/xui/en-us/notifications.xml index 306e3b8..ecfc523 100644 --- a/linden/indra/newview/skins/default/xui/en-us/notifications.xml +++ b/linden/indra/newview/skins/default/xui/en-us/notifications.xml | |||
@@ -7393,6 +7393,62 @@ Media/audio URL blocked for [DOMAIN] | |||
7393 | The media filters have been cleared | 7393 | The media filters have been cleared |
7394 | </notification> | 7394 | </notification> |
7395 | 7395 | ||
7396 | <notification | ||
7397 | icon="alertmodal.tga" | ||
7398 | name="ProxyNeedRestart" | ||
7399 | type="alertmodal"> | ||
7400 | Socks proxy settings will take effect after you restart [VIEWER_NAME]. | ||
7401 | </notification> | ||
7402 | |||
7403 | <notification | ||
7404 | icon="alertmodal.tga" | ||
7405 | name="SOCKS_CONNECT_OK" | ||
7406 | type="alertmodal"> | ||
7407 | Connection to Socks5 proxy [PROXY] was successful. | ||
7408 | </notification> | ||
7409 | |||
7410 | <notification | ||
7411 | icon="alertmodal.tga" | ||
7412 | name="SOCKS_NOT_PERMITTED" | ||
7413 | type="alertmodal"> | ||
7414 | The Socks5 proxy "[PROXY]" refused the connection, not allowed by rule set | ||
7415 | </notification> | ||
7416 | |||
7417 | <notification | ||
7418 | icon="alertmodal.tga" | ||
7419 | name="SOCKS_CONNECT_ERROR" | ||
7420 | type="alertmodal"> | ||
7421 | The Socks5 proxy "[PROXY]" refused the connection, could not open TCP channel | ||
7422 | </notification> | ||
7423 | |||
7424 | <notification | ||
7425 | icon="alertmodal.tga" | ||
7426 | name="SOCKS_NOT_ACCEPTABLE" | ||
7427 | type="alertmodal"> | ||
7428 | The Socks5 proxy "[PROXY]" refused the selected authentication system | ||
7429 | </notification> | ||
7430 | |||
7431 | <notification | ||
7432 | icon="alertmodal.tga" | ||
7433 | name="SOCKS_AUTH_FAIL" | ||
7434 | type="alertmodal"> | ||
7435 | The Socks5 proxy "[PROXY]" reported your credentials are invalid | ||
7436 | </notification> | ||
7437 | |||
7438 | <notification | ||
7439 | icon="alertmodal.tga" | ||
7440 | name="SOCKS_UDP_FWD_NOT_GRANTED" | ||
7441 | type="alertmodal"> | ||
7442 | The Socks5 proxy "[PROXY]" refused the UDP associate request | ||
7443 | </notification> | ||
7444 | |||
7445 | <notification | ||
7446 | icon="alertmodal.tga" | ||
7447 | name="SOCKS_HOST_CONNECT_FAILED" | ||
7448 | type="alertmodal"> | ||
7449 | Could not connect to Socks5 proxy server "[PROXY]" | ||
7450 | </notification> | ||
7451 | |||
7396 | <!--End Imprudence notifications--> | 7452 | <!--End Imprudence notifications--> |
7397 | <!-- [KITTY VIEWER] --> | 7453 | <!-- [KITTY VIEWER] --> |
7398 | <notification | 7454 | <notification |
diff --git a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_network.xml b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_network.xml index 7d26ff5..c3f0c22 100644 --- a/linden/indra/newview/skins/default/xui/en-us/panel_preferences_network.xml +++ b/linden/indra/newview/skins/default/xui/en-us/panel_preferences_network.xml | |||
@@ -63,32 +63,115 @@ | |||
63 | decimal_digits="0" enabled="true" follows="left|top" height="16" | 63 | decimal_digits="0" enabled="true" follows="left|top" height="16" |
64 | increment="1" initial_val="13000" label="Port number:" label_width="75" | 64 | increment="1" initial_val="13000" label="Port number:" label_width="75" |
65 | left_delta="20" max_val="13050" min_val="13000" mouse_opaque="true" | 65 | left_delta="20" max_val="13050" min_val="13000" mouse_opaque="true" |
66 | name="connection_port" width="150" /> | 66 | name="connection_port" width="140" /> |
67 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | 67 | |
68 | bottom_delta="-24" drop_shadow_visible="true" enabled="true" | 68 | <!-- XMLRPC PROXY --> |
69 | follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" | 69 | |
70 | height="10" left="15" mouse_opaque="false" name="proxy_label" v_pad="0" | 70 | <check_box bottom_delta="-25" enabled="true" |
71 | width="300"> | ||
72 | XMLRPC Proxy (Login, Land- and Money purchase): | ||
73 | </text> | ||
74 | <check_box bottom_delta="-25" enabled="true" | ||
75 | follows="left|top" font="SansSerifSmall" height="16" initial_value="false" | 71 | follows="left|top" font="SansSerifSmall" height="16" initial_value="false" |
76 | label="Enable XMLRPC proxy" left_delta="199" mouse_opaque="true" | 72 | label="Enable XMLRPC proxy (Login, Land, and Money purchases)" left="15" mouse_opaque="true" |
77 | name="xmlrpc_proxy_enabled" radio_style="false" width="256" /> | 73 | name="xmlrpc_proxy_enabled" radio_style="false" width="300" /> |
78 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | 74 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" |
79 | bottom_delta="-25" drop_shadow_visible="true" enabled="true" | 75 | bottom_delta="-18" drop_shadow_visible="true" enabled="true" |
80 | follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" | 76 | follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" |
81 | height="10" left="140" mouse_opaque="false" name="xmlrpc_proxy_text_label" | 77 | height="10" left_delta="20" mouse_opaque="false" name="xmlrpc_proxy_text_label" |
82 | v_pad="0" width="128"> | 78 | v_pad="0" width="128"> |
83 | Address: | 79 | Address: |
84 | </text> | 80 | </text> |
85 | <line_editor bottom_delta="-8" enabled="true" follows="left|top" font="SansSerif" | 81 | <line_editor bottom_delta="-8" enabled="true" follows="left|top" font="SansSerif" |
86 | height="20" left="217" name="xmlrpc_proxy_editor" | 82 | height="20" left="112" name="xmlrpc_proxy_editor" |
87 | tool_tip="The name or IP address of the proxy you would like to use" | 83 | tool_tip="The name or IP address of the proxy you would like to use" |
88 | width="200" /> | 84 | width="200" /> |
89 | <spinner bottom_delta="-25" decimal_digits="0" | 85 | <spinner bottom_delta="-20" decimal_digits="0" |
90 | enabled="true" follows="left|top" height="16" increment="1" | 86 | enabled="true" follows="left|top" height="16" increment="1" |
91 | initial_val="80" label="Port number:" label_width="75" left="140" | 87 | initial_val="80" label="Port number:" label_width="75" left="35" |
92 | max_val="12000" min_val="10" mouse_opaque="true" name="xmlrpc_proxy_port" | 88 | max_val="12000" min_val="10" mouse_opaque="true" name="xmlrpc_proxy_port" |
93 | width="140" /> | 89 | width="140" /> |
90 | |||
91 | <!-- SOCKS 5 PROXY --> | ||
92 | |||
93 | <check_box bottom_delta="-24" enabled="true" | ||
94 | follows="left|top" font="SansSerifSmall" height="16" initial_value="false" | ||
95 | label="Enable SOCKS 5 proxy" left="15" mouse_opaque="true" | ||
96 | name="socks5_proxy_enabled" radio_style="false" width="256" /> | ||
97 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
98 | bottom_delta="-18" drop_shadow_visible="true" enabled="true" | ||
99 | follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" | ||
100 | height="10" left="35" mouse_opaque="false" name="socks5_host_label" | ||
101 | v_pad="0" width="128"> | ||
102 | Socks 5 host: | ||
103 | </text> | ||
104 | <line_editor bottom_delta="-6" enabled="true" follows="left|top" font="SansSerif" | ||
105 | height="20" left="113" name="socks5_proxy_host" | ||
106 | tool_tip="The name or IP address of the SOCKS5 proxy you would like to use" | ||
107 | width="200" /> | ||
108 | <spinner bottom_delta="-20" decimal_digits="0" | ||
109 | enabled="true" follows="left|top" height="16" increment="1" | ||
110 | initial_val="80" label="Port number:" label_width="75" left="35" | ||
111 | max_val="12000" min_val="10" mouse_opaque="true" name="socks5_proxy_port" | ||
112 | width="140" /> | ||
113 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
114 | bottom_delta="-20" drop_shadow_visible="true" enabled="true" | ||
115 | follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" | ||
116 | height="10" left="35" mouse_opaque="false" name="socks5_auth_label" | ||
117 | v_pad="0" width="128"> | ||
118 | Socks5 authentication: | ||
119 | </text> | ||
120 | <radio_group bottom_delta="-6" draw_border="false" follows="left|top" height="20" left="35" | ||
121 | name="socks5_auth" width="420"> | ||
122 | <radio_item bottom="0" height="20" left_delta="80" name="None" width="50" | ||
123 | tool_tip="No authentication"> | ||
124 | None | ||
125 | </radio_item> | ||
126 | <radio_item bottom="0" height="20" left_delta="50" name="UserPass" width="50" | ||
127 | tool_tip="Username / Password authentication"> | ||
128 | Username / Password | ||
129 | </radio_item> | ||
130 | </radio_group> | ||
131 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
132 | bottom_delta="-16" drop_shadow_visible="true" enabled="true" | ||
133 | follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" | ||
134 | height="10" left="122" mouse_opaque="false" name="socks5_username_label" | ||
135 | v_pad="0" width="128"> | ||
136 | Username: | ||
137 | </text> | ||
138 | <line_editor bottom_delta="-8" enabled="true" follows="left|top" font="SansSerif" | ||
139 | height="20" left="200" name="socks5_proxy_username" | ||
140 | tool_tip="Username for the Socks5 proxy" | ||
141 | width="200" /> | ||
142 | |||
143 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
144 | bottom_delta="-14" drop_shadow_visible="true" enabled="true" | ||
145 | follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" | ||
146 | height="10" left="122" mouse_opaque="false" name="socks5_password_label" | ||
147 | v_pad="0" width="128"> | ||
148 | Password: | ||
149 | </text> | ||
150 | <line_editor bottom_delta="-8" enabled="true" follows="left|top" font="SansSerif" | ||
151 | height="20" left="200" name="socks5_proxy_password" | ||
152 | tool_tip="Password for the Socks5 proxy" | ||
153 | width="200" /> | ||
154 | |||
155 | <text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false" | ||
156 | bottom_delta="-20" drop_shadow_visible="true" enabled="true" | ||
157 | follows="left|top" font="SansSerifSmall" h_pad="0" halign="left" | ||
158 | height="10" left="35" mouse_opaque="false" name="socks5_auth_label" | ||
159 | v_pad="0" width="128"> | ||
160 | HTTP proxy: | ||
161 | </text> | ||
162 | <radio_group bottom_delta="-8" draw_border="false" follows="left|top" height="20" left="35" | ||
163 | name="socks5_http_proxy_type" width="380" > | ||
164 | <radio_item height="20" bottom="0" left="100" name="None" width="50" | ||
165 | tool_tip="No HTTP proxy"> | ||
166 | None | ||
167 | </radio_item> | ||
168 | <radio_item height="20" bottom="0" left="170" name="Socks" width="50" | ||
169 | tool_tip="Use Socks for HTTP proxy"> | ||
170 | Socks | ||
171 | </radio_item> | ||
172 | <radio_item height="20" bottom="0" left="250" name="Web" width="50" | ||
173 | tool_tip="Use web proxy for HTTP proxy"> | ||
174 | Web | ||
175 | </radio_item> | ||
176 | </radio_group> | ||
94 | </panel> | 177 | </panel> |