Skip to content

Commit

Permalink
Allow VideoRoom to choose whether signed tokens should be used (#2825)
Browse files Browse the repository at this point in the history
  • Loading branch information
lminiero committed Dec 7, 2021
1 parent d38e579 commit f9906da
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 4 deletions.
6 changes: 6 additions & 0 deletions auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ gboolean janus_auth_is_stored_mode(void) {
return auth_enabled && tokens != NULL;
}

gboolean janus_auth_is_signed_mode(void) {
return auth_enabled && auth_secret != NULL;
}

void janus_auth_deinit(void) {
janus_mutex_lock(&mutex);
if(tokens != NULL)
Expand Down Expand Up @@ -124,6 +128,8 @@ gboolean janus_auth_check_signature_contains(const char *token, const char *real
if (!auth_enabled || auth_secret == NULL) {
return TRUE;
}
if(token == NULL)
return FALSE;
gchar **parts = g_strsplit(token, ":", 2);
gchar **data = NULL;
/* Token should have exactly one data and one hash part */
Expand Down
2 changes: 2 additions & 0 deletions auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ void janus_auth_init(gboolean enabled, const char *secret);
gboolean janus_auth_is_enabled(void);
/*! \brief Method to check whether the mechanism is in stored-token mode or not */
gboolean janus_auth_is_stored_mode(void);
/*! \brief Method to check whether the mechanism is in signed-token mode or not */
gboolean janus_auth_is_signed_mode(void);
/*! \brief Method to de-initialize the mechanism */
void janus_auth_deinit(void);

Expand Down
2 changes: 2 additions & 0 deletions conf/janus.plugin.videoroom.jcfg.sample
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
# pin = <optional password needed for joining the room>
# require_pvtid = true|false (whether subscriptions are required to provide a valid private_id
# to associate with a publisher, default=false)
# signed_tokens = true|false (whether access to the room requires signed tokens; default=false,
only works if signed tokens are used in the core as well)
# publishers = <max number of concurrent senders> (e.g., 6 for a video
# conference or 1 for a webinar)
# bitrate = <max video bitrate for senders> (e.g., 128000)
Expand Down
6 changes: 6 additions & 0 deletions janus.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,7 @@ void janus_plugin_send_remb(janus_plugin_session *plugin_session, uint32_t bitra
void janus_plugin_close_pc(janus_plugin_session *plugin_session);
void janus_plugin_end_session(janus_plugin_session *plugin_session);
void janus_plugin_notify_event(janus_plugin *plugin, janus_plugin_session *plugin_session, json_t *event);
gboolean janus_plugin_auth_is_signed(void);
gboolean janus_plugin_auth_is_signature_valid(janus_plugin *plugin, const char *token);
gboolean janus_plugin_auth_signature_contains(janus_plugin *plugin, const char *token, const char *desc);
static janus_callbacks janus_handler_plugin =
Expand All @@ -621,6 +622,7 @@ static janus_callbacks janus_handler_plugin =
.end_session = janus_plugin_end_session,
.events_is_enabled = janus_events_is_enabled,
.notify_event = janus_plugin_notify_event,
.auth_is_signed = janus_plugin_auth_is_signed,
.auth_is_signature_valid = janus_plugin_auth_is_signature_valid,
.auth_signature_contains = janus_plugin_auth_signature_contains,
};
Expand Down Expand Up @@ -4102,6 +4104,10 @@ void janus_plugin_notify_event(janus_plugin *plugin, janus_plugin_session *plugi
}
}

gboolean janus_plugin_auth_is_signed() {
return janus_auth_is_signed_mode();
}

gboolean janus_plugin_auth_is_signature_valid(janus_plugin *plugin, const char *token) {
return janus_auth_check_signature(token, plugin->get_package());
}
Expand Down
26 changes: 23 additions & 3 deletions plugins/janus_videoroom.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ room-<unique room ID>: {
pin = <optional password needed for joining the room>
require_pvtid = true|false (whether subscriptions are required to provide a valid private_id
to associate with a publisher, default=false)
signed_tokens = true|false (whether access to the room requires signed tokens; default=false,
only works if signed tokens are used in the core as well)
publishers = <max number of concurrent senders> (e.g., 6 for a video
conference or 1 for a webinar, default=3)
bitrate = <max video bitrate for senders> (e.g., 128000)
Expand Down Expand Up @@ -1260,6 +1262,7 @@ static struct janus_json_parameter create_parameters[] = {
{"secret", JSON_STRING, 0},
{"pin", JSON_STRING, 0},
{"require_pvtid", JANUS_JSON_BOOL, 0},
{"signed_tokens", JANUS_JSON_BOOL, 0},
{"bitrate", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
{"bitrate_cap", JANUS_JSON_BOOL, 0},
{"fir_freq", JSON_INTEGER, JANUS_JSON_PARAM_POSITIVE},
Expand Down Expand Up @@ -1484,6 +1487,7 @@ typedef struct janus_videoroom {
gchar *room_pin; /* Password needed to join this room, if any */
gboolean is_private; /* Whether this room is 'private' (as in hidden) or not */
gboolean require_pvtid; /* Whether subscriptions in this room require a private_id */
gboolean signed_tokens; /* Whether signed tokens are required (assuming they're enabled in the core) */
gboolean require_e2ee; /* Whether end-to-end encrypted publishers are required */
int max_publishers; /* Maximum number of concurrent publishers */
uint32_t bitrate; /* Global bitrate limit */
Expand Down Expand Up @@ -2250,6 +2254,7 @@ int janus_videoroom_init(janus_callbacks *callback, const char *config_path) {
janus_config_item *secret = janus_config_get(config, cat, janus_config_type_item, "secret");
janus_config_item *pin = janus_config_get(config, cat, janus_config_type_item, "pin");
janus_config_item *req_pvtid = janus_config_get(config, cat, janus_config_type_item, "require_pvtid");
janus_config_item *signed_tokens = janus_config_get(config, cat, janus_config_type_item, "signed_tokens");
janus_config_item *bitrate = janus_config_get(config, cat, janus_config_type_item, "bitrate");
janus_config_item *bitrate_cap = janus_config_get(config, cat, janus_config_type_item, "bitrate_cap");
janus_config_item *maxp = janus_config_get(config, cat, janus_config_type_item, "publishers");
Expand Down Expand Up @@ -2322,6 +2327,13 @@ int janus_videoroom_init(janus_callbacks *callback, const char *config_path) {
}
videoroom->is_private = priv && priv->value && janus_is_true(priv->value);
videoroom->require_pvtid = req_pvtid && req_pvtid->value && janus_is_true(req_pvtid->value);
if(signed_tokens && signed_tokens->value && janus_is_true(signed_tokens->value)) {
if(!gateway->auth_is_signed()) {
JANUS_LOG(LOG_WARN, "Can't enforce signed tokens for this room, signed-mode not in use in the core\n");
} else {
videoroom->signed_tokens = TRUE;
}
}
videoroom->require_e2ee = req_e2ee && req_e2ee->value && janus_is_true(req_e2ee->value);
videoroom->max_publishers = 3; /* FIXME How should we choose a default? */
if(maxp != NULL && maxp->value != NULL)
Expand Down Expand Up @@ -2994,9 +3006,9 @@ static int janus_videoroom_access_room(json_t *root, gboolean check_modify, gboo
}
if(check_join) {
char error_cause2[100];
/* signed tokens bypass pin validation */
json_t *token = json_object_get(root, "token");
if(token) {
/* Signed tokens are enforced, so they precede any pin validation */
if(gateway->auth_is_signed() && (*videoroom)->signed_tokens) {
json_t *token = json_object_get(root, "token");
char room_descriptor[100];
g_snprintf(room_descriptor, sizeof(room_descriptor), "room=%s", room_id_str);
if(!gateway->auth_signature_contains(&janus_videoroom_plugin, json_string_value(token), room_descriptor)) {
Expand Down Expand Up @@ -3061,6 +3073,7 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi
json_t *desc = json_object_get(root, "description");
json_t *is_private = json_object_get(root, "is_private");
json_t *req_pvtid = json_object_get(root, "require_pvtid");
json_t *signed_tokens = json_object_get(root, "signed_tokens");
json_t *req_e2ee = json_object_get(root, "require_e2ee");
json_t *secret = json_object_get(root, "secret");
json_t *pin = json_object_get(root, "pin");
Expand Down Expand Up @@ -3223,6 +3236,13 @@ static json_t *janus_videoroom_process_synchronous_request(janus_videoroom_sessi
videoroom->room_name = description;
videoroom->is_private = is_private ? json_is_true(is_private) : FALSE;
videoroom->require_pvtid = req_pvtid ? json_is_true(req_pvtid) : FALSE;
if(signed_tokens && json_is_true(signed_tokens)) {
if(!gateway->auth_is_signed()) {
JANUS_LOG(LOG_WARN, "Can't enforce signed tokens for this room, signed-mode not in use in the core\n");
} else {
videoroom->signed_tokens = TRUE;
}
}
videoroom->require_e2ee = req_e2ee ? json_is_true(req_e2ee) : FALSE;
if(secret)
videoroom->room_secret = g_strdup(json_string_value(secret));
Expand Down
5 changes: 4 additions & 1 deletion plugins/plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ janus_plugin *create(void) {
* Janus instance or it will crash.
*
*/
#define JANUS_PLUGIN_API_VERSION 15
#define JANUS_PLUGIN_API_VERSION 16

/*! \brief Initialization of all plugin properties to NULL
*
Expand Down Expand Up @@ -412,6 +412,9 @@ struct janus_callbacks {
* @param[in] event The event to notify as a Jansson json_t object */
void (* const notify_event)(janus_plugin *plugin, janus_plugin_session *handle, json_t *event);

/*! \brief Method to check whether the core is using signed tokens
* @returns TRUE if signed tokens are in use, FALSE otherwise */
gboolean (* const auth_is_signed)(void);
/*! \brief Method to check whether a signed token is valid
* \note accepts only tokens with the plugin identifier as realm
* @param[in] token The token to validate
Expand Down

0 comments on commit f9906da

Please sign in to comment.