diff options
author | Logan Dethrow <log@lindenlab.com> | 2011-07-29 15:38:20 -0400 |
---|---|---|
committer | Logan Dethrow <log@lindenlab.com> | 2011-07-29 15:38:20 -0400 |
commit | d2c72cb7e92896cb414e357ef262d91b0498a6b7 (patch) | |
tree | 6fec31cc40456a9ffe7fcbf626555418199d425e | |
parent | f15d28a636da7b6d2784d9301e7a030b5bd38a8c (diff) |
STORM-1112 Input sanitization of proxy options.
-rw-r--r-- | indra/llmessage/llproxy.cpp | 79 | ||||
-rw-r--r-- | indra/llmessage/llproxy.h | 18 | ||||
-rwxr-xr-x | indra/newview/llfloaterpreference.cpp | 10 | ||||
-rw-r--r-- | indra/newview/llstartup.cpp | 54 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 44 |
5 files changed, 163 insertions, 42 deletions
diff --git a/indra/llmessage/llproxy.cpp b/indra/llmessage/llproxy.cpp index e1970f1368..381308fb2a 100644 --- a/indra/llmessage/llproxy.cpp +++ b/indra/llmessage/llproxy.cpp @@ -68,7 +68,7 @@ LLProxy::LLProxy(): LLProxy::~LLProxy() { - stopProxy(); + stopSOCKSProxy(); sUDPProxyEnabled = false; sHTTPProxyEnabled = false; @@ -95,14 +95,14 @@ S32 LLProxy::proxyHandshake(LLHost proxy, U32 message_port) if (result != 0) { LL_WARNS("Proxy") << "SOCKS authentication request failed, error on TCP control channel : " << result << LL_ENDL; - stopProxy(); + stopSOCKSProxy(); return SOCKS_CONNECT_ERROR; } if (socks_auth_response.method == AUTH_NOT_ACCEPTABLE) { LL_WARNS("Proxy") << "SOCKS 5 server refused all our authentication methods" << LL_ENDL; - stopProxy(); + stopSOCKSProxy(); return SOCKS_NOT_ACCEPTABLE; } @@ -126,14 +126,14 @@ S32 LLProxy::proxyHandshake(LLHost proxy, U32 message_port) if (result != 0) { LL_WARNS("Proxy") << "SOCKS authentication failed, error on TCP control channel : " << result << LL_ENDL; - stopProxy(); + stopSOCKSProxy(); return SOCKS_CONNECT_ERROR; } if (password_reply.status != AUTH_SUCCESS) { LL_WARNS("Proxy") << "SOCKS authentication failed" << LL_ENDL; - stopProxy(); + stopSOCKSProxy(); return SOCKS_AUTH_FAIL; } } @@ -156,14 +156,14 @@ S32 LLProxy::proxyHandshake(LLHost proxy, U32 message_port) if (result != 0) { LL_WARNS("Proxy") << "SOCKS connect request failed, error on TCP control channel : " << result << LL_ENDL; - stopProxy(); + stopSOCKSProxy(); return SOCKS_CONNECT_ERROR; } if (connect_reply.reply != REPLY_REQUEST_GRANTED) { LL_WARNS("Proxy") << "Connection to SOCKS 5 server failed, UDP forward request not granted" << LL_ENDL; - stopProxy(); + stopSOCKSProxy(); return SOCKS_UDP_FWD_NOT_GRANTED; } @@ -174,37 +174,49 @@ S32 LLProxy::proxyHandshake(LLHost proxy, U32 message_port) return SOCKS_OK; } -S32 LLProxy::startProxy(std::string host, U32 port) +S32 LLProxy::startSOCKSProxy(LLHost host) { - mTCPProxy.setHostByName(host); - mTCPProxy.setPort(port); + S32 status = SOCKS_OK; - S32 status; + if (host.isOk()) + { + mTCPProxy = host; + } + else + { + status = SOCKS_INVALID_HOST; + } - if (mProxyControlChannel) + if (mProxyControlChannel && status == SOCKS_OK) { tcp_close_channel(&mProxyControlChannel); } - mProxyControlChannel = tcp_open_channel(mPool, mTCPProxy); - if (!mProxyControlChannel) + if (status == SOCKS_OK) + { + mProxyControlChannel = tcp_open_channel(mPool, mTCPProxy); + if (!mProxyControlChannel) + { + status = SOCKS_HOST_CONNECT_FAILED; + } + } + + if (status == SOCKS_OK) { - return SOCKS_HOST_CONNECT_FAILED; + status = proxyHandshake(mTCPProxy, (U32)gMessageSystem->mPort); } - status = proxyHandshake(mTCPProxy, (U32)gMessageSystem->mPort); if (status == SOCKS_OK) { sUDPProxyEnabled = true; } else { - stopProxy(); + stopSOCKSProxy(); } return status; - } -void LLProxy::stopProxy() +void LLProxy::stopSOCKSProxy() { sUDPProxyEnabled = false; @@ -228,8 +240,15 @@ void LLProxy::setAuthNone() mAuthMethodSelected = METHOD_NOAUTH; } -void LLProxy::setAuthPassword(const std::string &username, const std::string &password) +bool LLProxy::setAuthPassword(const std::string &username, const std::string &password) { + if (username.length() > SOCKSMAXUSERNAMELEN || password.length() > SOCKSMAXPASSWORDLEN || + username.length() < SOCKSMINUSERNAMELEN || password.length() < SOCKSMINPASSWORDLEN) + { + LL_WARNS("Proxy") << "Invalid SOCKS 5 password or username length." << LL_ENDL; + return false; + } + mAuthMethodSelected = METHOD_PASSWORD; mSocksUsername = username; mSocksPassword = password; @@ -240,10 +259,18 @@ void LLProxy::setAuthPassword(const std::string &username, const std::string &pa LLMutexLock lock(&mProxyMutex); mSOCKSAuthStrings.push_back(curl_auth_string); + + return true; } -void LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type) -{ +bool LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type) +{ + if (httpHost.isOk()) + { + LL_WARNS("Proxy") << "Invalid SOCKS 5 Server" << LL_ENDL; + return false; + } + LLMutexLock lock(&mProxyMutex); sHTTPProxyEnabled = true; @@ -254,13 +281,17 @@ void LLProxy::enableHTTPProxy(LLHost httpHost, LLHttpProxyType type) char* http_addr_string = new char[size]; strncpy(http_addr_string, httpHost.getIPString().c_str(), size); mHTTPProxyAddrStrings.push_back(http_addr_string); + + return true; } -void LLProxy::enableHTTPProxy() +bool LLProxy::enableHTTPProxy() { LLMutexLock lock(&mProxyMutex); sHTTPProxyEnabled = true; + + return true; } void LLProxy::disableHTTPProxy() @@ -273,7 +304,7 @@ void LLProxy::disableHTTPProxy() //static void LLProxy::cleanupClass() { - getInstance()->stopProxy(); + getInstance()->stopSOCKSProxy(); deleteSingleton(); } diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h index df1ec9121e..ce5bdec5ad 100644 --- a/indra/llmessage/llproxy.h +++ b/indra/llmessage/llproxy.h @@ -44,11 +44,19 @@ #define SOCKS_AUTH_FAIL (-4) #define SOCKS_UDP_FWD_NOT_GRANTED (-5) #define SOCKS_HOST_CONNECT_FAILED (-6) +#define SOCKS_INVALID_HOST (-7) + #ifndef MAXHOSTNAMELEN #define MAXHOSTNAMELEN (255 + 1) /* socks5: 255, +1 for len. */ #endif +#define SOCKSMAXUSERNAMELEN 255 +#define SOCKSMAXPASSWORDLEN 255 + +#define SOCKSMINUSERNAMELEN 1 +#define SOCKSMINPASSWORDLEN 1 + #define SOCKS_VERSION 0x05 // we are using SOCKS 5 #define SOCKS_HEADER_SIZE 10 @@ -165,16 +173,16 @@ public: ~LLProxy(); // Start a connection to the SOCKS 5 proxy - S32 startProxy(std::string host, U32 port); + S32 startSOCKSProxy(LLHost host); // Disconnect and clean up any connection to the SOCKS 5 proxy - void stopProxy(); + void stopSOCKSProxy(); // Delete LLProxy singleton, destroying the APR pool used by the control channel. static void cleanupClass(); // Set up to use Password auth when connecting to the SOCKS proxy - void setAuthPassword(const std::string &username, const std::string &password); + bool setAuthPassword(const std::string &username, const std::string &password); // Set up to use No Auth when connecting to the SOCKS proxy void setAuthNone(); @@ -190,8 +198,8 @@ public: // Proxy HTTP packets via httpHost, which can be a SOCKS 5 or a HTTP proxy // as specified in type - void enableHTTPProxy(LLHost httpHost, LLHttpProxyType type); - void enableHTTPProxy(); + bool enableHTTPProxy(LLHost httpHost, LLHttpProxyType type); + bool enableHTTPProxy(); // Stop proxying HTTP packets void disableHTTPProxy(); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 84547ec38a..b01dc616a3 100755 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -618,10 +618,10 @@ void LLFloaterPreference::cancel() updateDoubleClickControls(); mDoubleClickActionDirty = false; } - LLFloaterPreferenceProxy * advanced_socks_settings = LLFloaterReg::findTypedInstance<LLFloaterPreferenceProxy>("prefs_socks5_advanced"); - if (advanced_socks_settings) + LLFloaterPreferenceProxy * advanced_proxy_settings = LLFloaterReg::findTypedInstance<LLFloaterPreferenceProxy>("prefs_proxy"); + if (advanced_proxy_settings) { - advanced_socks_settings->cancel(); + advanced_proxy_settings->cancel(); } } @@ -1937,6 +1937,10 @@ LLFloaterPreferenceProxy::~LLFloaterPreferenceProxy() BOOL LLFloaterPreferenceProxy::postBuild() { LLRadioGroup* socksAuth = getChild<LLRadioGroup>("socks5_auth_type"); + if (!socksAuth) + { + return FALSE; + } if (socksAuth->getSelectedValue().asString() == "None") { getChild<LLLineEditor>("socks5_username")->setEnabled(false); diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index eca3e5439e..c934ff9f1b 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -825,7 +825,7 @@ bool idle_startup() if (!LLStartUp::handleSocksProxy()) { // Proxy start up failed, we should now bail the state machine - // HandleSocksProxy() will have reported an error to the user + // 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); @@ -834,11 +834,11 @@ bool idle_startup() } else { - LLProxy::getInstance()->stopProxy(); + LLProxy::getInstance()->stopSOCKSProxy(); } - //reset the values that could have come in from a slurl + // 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 // to overwrite valid values with empty strings. @@ -2779,20 +2779,40 @@ bool LLStartUp::handleSocksProxy() LLHost http_host; http_host.setHostByName(gSavedSettings.getString("BrowserProxyAddress")); http_host.setPort(gSavedSettings.getS32("BrowserProxyPort")); - LLProxy::getInstance()->enableHTTPProxy(http_host, LLPROXY_HTTP); + if (!LLProxy::getInstance()->enableHTTPProxy(http_host, LLPROXY_HTTP)) + { + LLSD subs; + subs["HOST"] = http_host.getIPString(); + subs["PORT"] = (S32)http_host.getPort(); + LLNotificationsUtil::add("PROXY_INVALID_HTTP_HOST", subs); + } } else if ((httpProxyType.compare("Socks") == 0) && gSavedSettings.getBOOL("Socks5ProxyEnabled")) { LLHost socks_host; socks_host.setHostByName(gSavedSettings.getString("Socks5ProxyHost")); socks_host.setPort(gSavedSettings.getU32("Socks5ProxyPort")); - LLProxy::getInstance()->enableHTTPProxy(socks_host, LLPROXY_SOCKS); + if (!LLProxy::getInstance()->enableHTTPProxy(socks_host, LLPROXY_SOCKS)) + { + LLSD subs; + subs["HOST"] = socks_host.getIPString(); + subs["PORT"] = (S32)socks_host.getPort(); + LLNotificationsUtil::add("PROXY_INVALID_SOCKS_HOST", subs); + } + + + } + else if (httpProxyType.compare("None") == 0) + { + LLProxy::getInstance()->disableHTTPProxy(); } else { + LL_WARNS("Proxy") << "Invalid HTTP proxy configuration."<< LL_ENDL; + gSavedSettings.setString("Socks5HttpProxyType", "None"); LLProxy::getInstance()->disableHTTPProxy(); } - + // Set up SOCKS proxy (if needed) if (gSavedSettings.getBOOL("Socks5ProxyEnabled")) { @@ -2805,7 +2825,14 @@ bool LLStartUp::handleSocksProxy() LLPointer<LLCredential> socks_cred = gSecAPIHandler->loadCredential("SOCKS5"); std::string socks_user = socks_cred->getIdentifier()["username"].asString(); std::string socks_password = socks_cred->getAuthenticator()["creds"].asString(); - LLProxy::getInstance()->setAuthPassword(socks_user, socks_password); + + bool ok; + ok = LLProxy::getInstance()->setAuthPassword(socks_user, socks_password); + if (!ok) + { + LLNotificationsUtil::add("SOCKS_BAD_CREDS"); + } + } else if (auth_type.compare("None") == 0) { @@ -2824,8 +2851,11 @@ bool LLStartUp::handleSocksProxy() } // Start the proxy and check for errors - // If status != SOCKS_OK, stopProxy() will already have been called when startProxy() returns. - int status = LLProxy::getInstance()->startProxy(gSavedSettings.getString("Socks5ProxyHost"), gSavedSettings.getU32("Socks5ProxyPort")); + // If status != SOCKS_OK, stopSOCKSProxy() will already have been called when startSOCKSProxy() returns. + LLHost socks_host; + socks_host.setHostByName(gSavedSettings.getString("Socks5ProxyHost")); + socks_host.setPort(gSavedSettings.getU32("Socks5ProxyPort")); + int status = LLProxy::getInstance()->startSOCKSProxy(socks_host); if (status == SOCKS_OK) { @@ -2865,6 +2895,10 @@ bool LLStartUp::handleSocksProxy() error_string = "SOCKS_HOST_CONNECT_FAILED"; break; + case SOCKS_INVALID_HOST: // Improperly formatted host address or port. + error_string = "SOCKS_INVALID_HOST"; + break; + default: error_string = "SOCKS_UNKNOWN_STATUS"; // Something strange happened, LL_WARNS("Proxy") << "Unknown return from LLProxy::startProxy(): " << status << LL_ENDL; @@ -2877,7 +2911,7 @@ bool LLStartUp::handleSocksProxy() } else { - LLProxy::getInstance()->stopProxy(); // ensure no UDP proxy is running and it's all cleaned up + LLProxy::getInstance()->stopSOCKSProxy(); // ensure no UDP proxy is running and it's all cleaned up } return true; diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 8b7e6d8c4e..ccc678d942 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -7218,6 +7218,50 @@ Click and drag anywhere on the world to rotate your view name="okbutton" yestext="OK"/> </notification> + + <notification + icon="alertmodal.tga" + name="SOCKS_INVALID_HOST" + type="alertmodal"> + Invalid SOCKS proxy address or port "[HOST]:[PORT]". + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="SOCKS_BAD_CREDS" + type="alertmodal"> + Invalid SOCKS 5 username or password. + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="PROXY_INVALID_HTTP_HOST" + type="alertmodal"> + Invalid HTTP proxy address or port "[HOST]:[PORT]". + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> + + <notification + icon="alertmodal.tga" + name="PROXY_INVALID_SOCKS_HOST" + type="alertmodal"> + Invalid SOCKS proxy address or port "[HOST]:[PORT]". + <tag>fail</tag> + <usetemplate + name="okbutton" + yestext="OK"/> + </notification> <notification icon="alertmodal.tga" |