summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLogan Dethrow <log@lindenlab.com>2011-07-29 15:38:20 -0400
committerLogan Dethrow <log@lindenlab.com>2011-07-29 15:38:20 -0400
commitd2c72cb7e92896cb414e357ef262d91b0498a6b7 (patch)
tree6fec31cc40456a9ffe7fcbf626555418199d425e
parentf15d28a636da7b6d2784d9301e7a030b5bd38a8c (diff)
STORM-1112 Input sanitization of proxy options.
-rw-r--r--indra/llmessage/llproxy.cpp79
-rw-r--r--indra/llmessage/llproxy.h18
-rwxr-xr-xindra/newview/llfloaterpreference.cpp10
-rw-r--r--indra/newview/llstartup.cpp54
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml44
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"