summaryrefslogtreecommitdiff
path: root/indra/newview/llscripteditorws.cpp
diff options
context:
space:
mode:
authorRider Linden <rider@lindenlab.com>2025-09-29 15:12:14 -0700
committerRider Linden <rider@lindenlab.com>2025-10-07 09:19:40 -0700
commit26268f714dc799f94a8e7f3adc66e2d4c1260d65 (patch)
tree0c4336f55621e430ad04bee4126f205319b7e02b /indra/newview/llscripteditorws.cpp
parente750c58a0e73c9363f649e42a47ad430f65c169b (diff)
Implemented simple challenge on handshake, fixed issue with closing a connection.
Diffstat (limited to 'indra/newview/llscripteditorws.cpp')
-rw-r--r--indra/newview/llscripteditorws.cpp75
1 files changed, 73 insertions, 2 deletions
diff --git a/indra/newview/llscripteditorws.cpp b/indra/newview/llscripteditorws.cpp
index 9f829f430e..2df4c73cd9 100644
--- a/indra/newview/llscripteditorws.cpp
+++ b/indra/newview/llscripteditorws.cpp
@@ -134,6 +134,18 @@ void LLScriptEditorWSServer::unsubscribeEditor(const std::string &script_id)
if (it != mSubscriptions.end())
{
mSubscriptions.erase(it);
+ S32 connection_id = it->second.mConnectionID;
+ ptrdiff_t count = std::count_if(mSubscriptions.begin(), mSubscriptions.end(), [connection_id](const auto& pair) {
+ return pair.second.mConnectionID == connection_id;
+ });
+ auto connection = it->second.mConnection.lock();
+ if (connection && !count)
+ { // We have removed the last subscription, close the connection
+ LL_DEBUGS("ScriptEditorWS") << "Closing connection ID " << it->second.mConnectionID <<
+ " as last subscription was removed" << LL_ENDL;
+ connection->sendDisconnect(LLScriptEditorWSConnection::REASON_EDITOR_CLOSED, "Editor closed");
+ }
+
}
}
@@ -512,7 +524,11 @@ void LLScriptEditorWSConnection::onOpen()
handshake["agent_id"] = gAgent.getID();
handshake["agent_name"] = "todo";
- // handshake["challenge"] = ... TODO: simple challenge, write to a file and have the client echo it back?
+ std::string challenge_file = generateChallenge();
+ if (!challenge_file.empty())
+ {
+ handshake["challenge"] = challenge_file;
+ }
LLSD languages = LLSD::emptyArray();
languages.append("lsl");
@@ -564,6 +580,16 @@ void LLScriptEditorWSConnection::onClose()
mFeatures.clear();
}
+void LLScriptEditorWSConnection::sendDisconnect(S32 reason, const std::string& message)
+{
+ LL_INFOS("ScriptEditorWS") << "Sending disconnect to client: " << message << LL_ENDL;
+ LLSD params;
+ params["reason"] = reason;
+ params["message"] = message;
+ notify("session.disconnect", params);
+ closeConnection(1000, message);
+}
+
void LLScriptEditorWSConnection::handleHandshakeResponse(const LLSD& result)
{
LL_INFOS("ScriptEditorWS") << "Processing handshake response from client" << LL_ENDL;
@@ -573,7 +599,23 @@ void LLScriptEditorWSConnection::handleHandshakeResponse(const LLSD& result)
mClientVersion = result["client_version"].asString();
mProtocolVersion = result["protocol_version"].asString();
- // TODO: Validate challenge_response if implemented
+ if (mChallenge.notNull())
+ {
+ // Validate challenge response
+ bool valid_response = (result.has("challenge_response") &&
+ (result["challenge_response"].asUUID() == mChallenge));
+
+ LLFile::remove(mChallengeFile);
+ mChallengeFile.clear();
+ mChallenge.setNull();
+ if (!valid_response)
+ {
+ LL_WARNS("ScriptEditorWS") << "Invalid or missing challenge response from client" << LL_ENDL;
+ sendDisconnect(REASON_PROTOCOL_ERROR, "Invalid challenge response");
+ return;
+ }
+ }
+ LLUUID challenge_response = result["challenge_response"].asUUID();
// Validate protocol compatibility
if (mProtocolVersion != "1.0")
@@ -603,7 +645,36 @@ void LLScriptEditorWSConnection::handleHandshakeResponse(const LLSD& result)
}
}
+ if (mChallenge.notNull())
+ {
+ // Remove temporary challenge file
+ LLFile::remove(mChallengeFile);
+ mChallenge.setNull();
+ mChallengeFile.clear();
+ }
+
notify("session.ok");
LL_INFOS("ScriptEditorWS") << "Handshake completed successfully." << LL_ENDL;
}
+
+std::string LLScriptEditorWSConnection::generateChallenge()
+{
+ mChallenge.generate();
+
+ mChallengeFile = std::string(LLFile::tmpdir()) + "sl_script_challenge.tmp";
+
+ llofstream file(mChallengeFile.c_str());
+ if (!file.is_open())
+ {
+ LL_WARNS() << "Unable to open challenge file: " << mChallengeFile << LL_ENDL;
+ mChallenge.setNull();
+ mChallengeFile.clear();
+ return std::string();
+ }
+
+ file << mChallenge;
+ file.close();
+
+ return mChallengeFile;
+}