Skip to content

Commit 693f7dc

Browse files
authored
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.
1 parent 67b62fb commit 693f7dc

1 file changed

Lines changed: 27 additions & 11 deletions

File tree

src/mod/endpoints/mod_verto/mod_verto.c

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,10 +1272,11 @@ static jsock_t *get_jsock(const char *uuid)
12721272

12731273
static void tech_reattach(verto_pvt_t *tech_pvt, jsock_t *jsock);
12741274

1275-
static void attach_jsock(jsock_t *jsock)
1275+
static switch_bool_t attach_jsock(jsock_t *jsock)
12761276
{
12771277
jsock_t *jp;
12781278
int proceed = 1;
1279+
switch_bool_t result = SWITCH_TRUE;
12791280

12801281
switch_mutex_lock(verto_globals.jsock_mutex);
12811282

@@ -1284,6 +1285,17 @@ static void attach_jsock(jsock_t *jsock)
12841285
if ((jp = switch_core_hash_find(verto_globals.jsock_hash, jsock->uuid_str))) {
12851286
if (jp == jsock) {
12861287
proceed = 0;
1288+
} else if (!zstr(jp->uid) && !zstr(jsock->uid) && strcmp(jp->uid, jsock->uid)) {
1289+
/* Refuse cross-identity takeover when both jsocks are authenticated under different uids.
1290+
* Clear uuid_str and set nodelete to prevent any uuid_str-keyed teardown
1291+
* (detach_jsock, del_jsock, detach_calls) from touching jp. */
1292+
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
1293+
"User %s blocked from taking over session %s owned by %s\n",
1294+
jsock->uid, jsock->uuid_str, jp->uid);
1295+
jsock->nodelete = 1;
1296+
jsock->uuid_str[0] = '\0';
1297+
proceed = 0;
1298+
result = SWITCH_FALSE;
12871299
} else {
12881300
cJSON *params = NULL;
12891301
cJSON *msg = NULL;
@@ -1304,6 +1316,7 @@ static void attach_jsock(jsock_t *jsock)
13041316
}
13051317

13061318
switch_mutex_unlock(verto_globals.jsock_mutex);
1319+
return result;
13071320
}
13081321

13091322
static void detach_jsock(jsock_t *jsock)
@@ -1482,10 +1495,8 @@ static void process_jrpc_response(jsock_t *jsock, cJSON *json)
14821495
{
14831496
}
14841497

1485-
static void set_session_id(jsock_t *jsock, const char *uuid)
1498+
static switch_bool_t set_session_id(jsock_t *jsock, const char *uuid)
14861499
{
1487-
//cJSON *params, *msg = jrpc_new(0);
1488-
14891500
if (!zstr(uuid)) {
14901501
switch_set_string(jsock->uuid_str, uuid);
14911502
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)
14941505
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s new RPC session %s\n", jsock->name, jsock->uuid_str);
14951506
}
14961507

1497-
attach_jsock(jsock);
1498-
1508+
return attach_jsock(jsock);
14991509
}
15001510

15011511
static cJSON *process_jrpc(jsock_t *jsock, cJSON *json)
@@ -1515,11 +1525,6 @@ static cJSON *process_jrpc(jsock_t *jsock, cJSON *json)
15151525
sessid = cJSON_GetObjectCstr(params, "sessid");
15161526
}
15171527

1518-
if (!switch_test_flag(jsock, JPFLAG_INIT)) {
1519-
set_session_id(jsock, sessid);
1520-
switch_set_flag(jsock, JPFLAG_INIT);
1521-
}
1522-
15231528
if (zstr(version) || strcmp(version, "2.0")) {
15241529
reply = jrpc_new(0);
15251530
jrpc_add_error(reply, CODE_INVALID, "Invalid message", id);
@@ -1546,6 +1551,17 @@ static cJSON *process_jrpc(jsock_t *jsock, cJSON *json)
15461551
switch_set_flag(jsock, JPFLAG_AUTHED);
15471552
}
15481553

1554+
/* Bind only after the auth gate — attach_jsock()'s eviction
1555+
* must not be reachable pre-auth. */
1556+
if (!switch_test_flag(jsock, JPFLAG_INIT)) {
1557+
if (!set_session_id(jsock, sessid)) {
1558+
jrpc_add_error(reply, CODE_AUTH_FAILED, "Session in use", id);
1559+
jsock->drop = 1;
1560+
goto end;
1561+
}
1562+
switch_set_flag(jsock, JPFLAG_INIT);
1563+
}
1564+
15491565
if (!method || !(func = jrpc_get_func(jsock, method))) {
15501566
jrpc_add_error(reply, -32601, "Invalid Method, Missing Method or Permission Denied", id);
15511567
} else {

0 commit comments

Comments
 (0)