Files
freeswitch/conf
ea74c0acb8 Merge commit from fork
* [Core, mod_commands] Interface allowlist (#3086)

* [core] Add interface allowlist to gate module app/api registration

Adds an optional, presence-activated allowlist in switch.conf.xml that
controls which modules may register application / api / json_api /
chat-application interfaces. With no <interface-allowlist> configured
nothing is enforced; when at least one <allow> entry is present, only
listed interfaces register at load time and all others are refused (the
module still loads and switch_loadable_module_process still returns
SUCCESS -- the blocked interface is simply never exposed).

Entries match at three levels of precision:
  mod_commands            - whole module
  mod_commands.system     - any interface named "system"
  mod_commands.system.api - a specific type (app|api|json_api|chat_app)

Enforcement lives in switch_loadable_module_process() so every module, at
boot and at runtime `load`, is subject to the same policy. This gives
operators a way to disable the "system"/"spawn" shell-exec API commands
(and equivalents) system-wide.

Also adds the `interface_allowlist_dump [modules] [plain]` API, which
walks the loaded modules and prints their interfaces in the allowlist key
format so the current state can be captured and pruned offline into config.

* [mod_commands] Add tests for the interface allowlist

New test_interface_allowlist boots the core with an active
<interface-allowlist> (conf_interface_allowlist/) that permits only a
couple of mod_commands interfaces, then loads mod_commands and verifies:

- listed commands register and run (status, version) while unlisted and
  shell-exec commands are refused (system, spawn, uptime) -- refusal
  surfaces as switch_api_execute returning FALSE / command-not-found,
  with the command function never invoked;
- a "module.name.type" entry gates by type: the API "status" loads while
  the JSON API of the same name stays blocked;
- interface_allowlist_dump prints the config format in its xml, modules
  and plain variants, and reflects module capabilities (system appears in
  the dump even though it was blocked from registering).

* [config] Fix interior -- in interface-allowlist comment breaking XML parse

The explanatory comment used -- as em-dash pairs. The XML parser treats
-- inside a comment as the comment close, causing an "unclosed <!--"
error that prevents the whole freeswitch.xml from parsing (boot and
reloadxml both fail). Replace the -- pairs with ordinary punctuation.

* update .gitignore

* [core] Warn when interface-allowlist section is present but parses no entries

Co-authored-by: Chris Rienzo <chris@signalwire.com>

* Merge commit from fork

Add `switch_stun_packet_verify_integrity()`, an HMAC-SHA1
MESSAGE-INTEGRITY verifier that is const and non-mutating: it runs
over a private copy of the pristine network-order packet, so the
caller's buffer and byte order stay untouched, and walks attributes
with its own unsigned bounded helper `stun_wire_attr_bounds()`
instead of the host-order iterator macros. A trailing
MESSAGE-INTEGRITY-SHA256 or FINGERPRINT after MESSAGE-INTEGRITY is
tolerated; any other trailing attribute is rejected.

Gate it in `handle_ice()` behind `ice->verify_integrity`: verify
before any ICE state is touched, keyed by message type (local
`ice->pass` for a request, remote `ice->rpass` for a response or
error response), and drop on failure. Keepalive indications carry no
MESSAGE-INTEGRITY and are ignored.

`ice->verify_integrity` is read from the `ice_verify_message_integrity`
channel variable in `switch_rtp_activate_ice()` and defaults off, so
receive-path behavior is unchanged unless it is enabled. Adds unit
tests in `tests/unit/switch_stun.c`.

* Merge commit from fork

* [core] Verify DTLS client cert against SDP fingerprint (server role)

Add opt-in verification of the client certificate when FreeSWITCH is
the DTLS server, mirroring the binding the client role already performs
on the server certificate: match the peer certificate against the SDP
`a=fingerprint` in `dtls_state_setup()`.

Selected per call by the `rtp_dtls_client_cert_verify_mode` channel
variable (`dtls_client_cert_verify_t`). An unset variable keeps the
default `DTLS_CLIENT_CERT_VERIFY_NONE`, so existing behavior is
unchanged:

- `none`: the server does not request a client certificate.
- `fingerprint`: request it (`SSL_VERIFY_PEER` + `dtls_accept_any_cert`)
  and require its fingerprint to match the SDP value; a self-signed
  certificate is accepted at the TLS layer and the match provides
  authenticity.
- `full`: additionally let OpenSSL enforce the certificate chain.

An unrecognized mode string falls back to `fingerprint` (fail closed)
with a warning.

The mode is set per `SSL` object in `switch_rtp_add_dtls()`. Verification
fails (`DS_FAIL`, no SRTP keys derived) when the client presents no
certificate, its fingerprint does not match, or the peer advertised no
usable `a=fingerprint`: `get_evp_by_name()` returns `NULL` for a missing
or empty hash type and `switch_core_cert_extract_fingerprint()` rejects a
`NULL` algorithm rather than passing it to `X509_digest()`.

`conf/vanilla/vars.xml` documents the knob as a disabled example. Tests
in `tests/unit/switch_rtp.c` cover matching, mismatched, absent-cert,
absent-fingerprint, `none`, and unrecognized-mode cases.

---------

Co-authored-by: Andrey Volk <andywolk@gmail.com>
Co-authored-by: Chris Rienzo <chris@signalwire.com>
2026-08-08 18:14:08 +03:00
..
2025-01-11 02:36:12 +03:00
2025-03-31 18:49:17 +03:00
2025-01-13 23:24:50 +03:00
2026-08-08 18:14:08 +03:00