From: Dmitry Verenitsin Date: Tue, 26 May 2026 19:24:48 +0000 (+0500) Subject: Merge commit from fork X-Git-Tag: v1.11.1^2~5 X-Git-Url: http://git.ipfire.org/gitweb/index.cgi?a=commitdiff_plain;h=693f7dc6aad2f2c17499571806da99ec63ce0a79;p=thirdparty%2Ffreeswitch.git Merge commit from fork `process_jrpc()` called `set_session_id()` before `check_auth()`, so an unauthenticated client could insert its jsock into `jsock_hash` under a foreign `sessid` and have `attach_jsock()` evict the prior owner (`verto.punt` + `detach_calls()` + `drop=1`) with no identity check. Move the bind past the auth gate; `JPFLAG_INIT` now means "jsock is bound", not "first frame seen". Additionally, `attach_jsock()` refuses the bind when prior and new jsock are authed under different `uid`s, replying `CODE_AUTH_FAILED` "Session in use". Same-uid reconnect and no-auth profile binds are unchanged. --- diff --git a/src/mod/endpoints/mod_verto/mod_verto.c b/src/mod/endpoints/mod_verto/mod_verto.c index c2464d9023..f2233df73a 100644 --- a/src/mod/endpoints/mod_verto/mod_verto.c +++ b/src/mod/endpoints/mod_verto/mod_verto.c @@ -1272,10 +1272,11 @@ static jsock_t *get_jsock(const char *uuid) static void tech_reattach(verto_pvt_t *tech_pvt, jsock_t *jsock); -static void attach_jsock(jsock_t *jsock) +static switch_bool_t attach_jsock(jsock_t *jsock) { jsock_t *jp; int proceed = 1; + switch_bool_t result = SWITCH_TRUE; switch_mutex_lock(verto_globals.jsock_mutex); @@ -1284,6 +1285,17 @@ static void attach_jsock(jsock_t *jsock) if ((jp = switch_core_hash_find(verto_globals.jsock_hash, jsock->uuid_str))) { if (jp == jsock) { proceed = 0; + } else if (!zstr(jp->uid) && !zstr(jsock->uid) && strcmp(jp->uid, jsock->uid)) { + /* Refuse cross-identity takeover when both jsocks are authenticated under different uids. + * Clear uuid_str and set nodelete to prevent any uuid_str-keyed teardown + * (detach_jsock, del_jsock, detach_calls) from touching jp. */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, + "User %s blocked from taking over session %s owned by %s\n", + jsock->uid, jsock->uuid_str, jp->uid); + jsock->nodelete = 1; + jsock->uuid_str[0] = '\0'; + proceed = 0; + result = SWITCH_FALSE; } else { cJSON *params = NULL; cJSON *msg = NULL; @@ -1304,6 +1316,7 @@ static void attach_jsock(jsock_t *jsock) } switch_mutex_unlock(verto_globals.jsock_mutex); + return result; } static void detach_jsock(jsock_t *jsock) @@ -1482,10 +1495,8 @@ static void process_jrpc_response(jsock_t *jsock, cJSON *json) { } -static void set_session_id(jsock_t *jsock, const char *uuid) +static switch_bool_t set_session_id(jsock_t *jsock, const char *uuid) { - //cJSON *params, *msg = jrpc_new(0); - if (!zstr(uuid)) { switch_set_string(jsock->uuid_str, uuid); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s re-connecting session %s\n", jsock->name, jsock->uuid_str); @@ -1494,8 +1505,7 @@ static void set_session_id(jsock_t *jsock, const char *uuid) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s new RPC session %s\n", jsock->name, jsock->uuid_str); } - attach_jsock(jsock); - + return attach_jsock(jsock); } static cJSON *process_jrpc(jsock_t *jsock, cJSON *json) @@ -1515,11 +1525,6 @@ static cJSON *process_jrpc(jsock_t *jsock, cJSON *json) sessid = cJSON_GetObjectCstr(params, "sessid"); } - if (!switch_test_flag(jsock, JPFLAG_INIT)) { - set_session_id(jsock, sessid); - switch_set_flag(jsock, JPFLAG_INIT); - } - if (zstr(version) || strcmp(version, "2.0")) { reply = jrpc_new(0); jrpc_add_error(reply, CODE_INVALID, "Invalid message", id); @@ -1546,6 +1551,17 @@ static cJSON *process_jrpc(jsock_t *jsock, cJSON *json) switch_set_flag(jsock, JPFLAG_AUTHED); } + /* Bind only after the auth gate — attach_jsock()'s eviction + * must not be reachable pre-auth. */ + if (!switch_test_flag(jsock, JPFLAG_INIT)) { + if (!set_session_id(jsock, sessid)) { + jrpc_add_error(reply, CODE_AUTH_FAILED, "Session in use", id); + jsock->drop = 1; + goto end; + } + switch_set_flag(jsock, JPFLAG_INIT); + } + if (!method || !(func = jrpc_get_func(jsock, method))) { jrpc_add_error(reply, -32601, "Invalid Method, Missing Method or Permission Denied", id); } else {