[mod_verto] Add enable-chat-api-proto to gate the api chat proto (#3136)

A client message can select which chat proto handles it, and the `api` proto
runs the address as a FreeSWITCH API command. That route does not pass through
`verto.fsapi`, so the per-user fsapi permission does not apply to it. The new
per-profile `enable-chat-api-proto` param controls the route and is off unless
set; a message selecting the proto without it is refused and logged.

The proto compare is case-insensitive, matching the chat interface registry,
which is created with `switch_core_hash_init_nocase()`.

Only the `api` proto is gated. A message carrying no proto selector, or one
naming any other chat proto, routes exactly as before.

The param ships commented out in both vanilla verto profiles.
This commit is contained in:
Dmitry Verenitsin
2026-08-26 18:35:31 +03:00
committed by GitHub
parent 7015f6a73a
commit f390069308
3 changed files with 23 additions and 0 deletions
@@ -21,6 +21,11 @@
<param name="userauth" value="true"/>
<!-- setting this to true will allow anyone to register even with no account so use with care -->
<param name="blind-reg" value="false"/>
<!-- lets a client message to api+<command> run FreeSWITCH API commands. Not
recommended: it is all or nothing and bypasses the per-user fsapi permission.
Prefer the fsapi method with jsonrpc-allowed-fsapi, which allow-lists commands
per user. This param is here for clients that already use api+<command>. -->
<!-- <param name="enable-chat-api-proto" value="true"/> -->
<param name="mcast-ip" value="224.1.1.1"/>
<param name="mcast-port" value="1337"/>
<param name="rtp-ip" value="$${local_ip_v4}"/>
@@ -46,6 +51,7 @@
<param name="userauth" value="true"/>
<!-- setting this to true will allow anyone to register even with no account so use with care -->
<param name="blind-reg" value="false"/>
<!-- <param name="enable-chat-api-proto" value="true"/> -->
<param name="rtp-ip" value="$${local_ip_v6}"/>
<!-- <param name="ext-rtp-ip" value=""/> -->
<param name="outbound-codec-string" value="opus,h264,vp8"/>
+16
View File
@@ -3986,6 +3986,20 @@ static switch_bool_t verto__info_func(const char *method, cJSON *params, jsock_t
}
}
if (!strcasecmp(proto, "api") && !jsock->profile->enable_chat_api_proto) {
/* Truncate: the rest of "to" comes straight from the client JSON and has no length bound. */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Profile [%s] rejected a message from %s (%s) addressed to the 'api' chat proto [%.256s]. "
"Set enable-chat-api-proto=true on the profile to permit it.\n",
jsock->profile->name, switch_str_nil(jsock->uid), switch_str_nil(jsock->name), switch_str_nil(to));
cJSON_AddItemToObject(*response, "message", cJSON_CreateString("The api chat proto is not permitted on this profile"));
switch_safe_free(pproto);
r = SWITCH_FALSE;
goto cleanup;
}
if (!zstr(to) && !zstr(body) && switch_event_create(&event, SWITCH_EVENT_MESSAGE) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", VERTO_CHAT_PROTO);
@@ -5343,6 +5357,8 @@ static switch_status_t parse_config(const char *cf)
profile->jb_msec = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "blind-reg") && !zstr(val)) {
profile->blind_reg = switch_true(val);
} else if (!strcasecmp(var, "enable-chat-api-proto") && !zstr(val)) {
profile->enable_chat_api_proto = switch_true(val);
} else if (!strcasecmp(var, "userauth") && !zstr(val)) {
profile->userauth = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "chop-domain") && !zstr(val)) {
+1
View File
@@ -247,6 +247,7 @@ struct verto_profile_s {
int in_thread;
int blind_reg;
int enable_chat_api_proto;
char *userauth;
char *root_passwd;