Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix auth when both (token, secret) modes are enabled #2581

Merged
merged 1 commit into from
Mar 22, 2021

Conversation

deep9
Copy link
Contributor

@deep9 deep9 commented Mar 16, 2021

Fix for #2580

Copy link
Member

@lminiero lminiero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, added some notes inline.

@@ -919,7 +919,7 @@ static int janus_request_check_secret(janus_request *request, guint64 session_id
}
}
/* We consider a request authorized if either the proper API secret or a valid token has been provided */
if(!secret_authorized && !token_authorized)
if(!(api_secret != NULL && secret_authorized) && !(janus_auth_is_enabled() && token_authorized))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that's needed. It's easier to change the defaults above, e.g.:

gboolean secret_authorized = (api_secret == NULL), token_authorized = !janus_auth_is_enabled();

This way the checks are simplified, because what's disabled automatically resolves to TRUE. This would also allow us to remove the Nothing to check branch entirely and only do something if either mechanism is needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this will not work, because the problem is in the function is_api_secret_valid - if it is disabled, it will return TRUE and we are back where we were before.

So the code might look like this:

	gboolean secret_authorized = (api_secret == NULL), token_authorized = !janus_auth_is_enabled();
	if(secret_authorized && token_authorized) {
		/* Nothing to check */
	} else {
		json_t *root = request->message;
		if(!secret_authorized) {
			/* There's an API secret, check that the client provided it */
			json_t *secret = json_object_get(root, "apisecret");
			if(secret && json_is_string(secret) && janus_strcmp_const_time(json_string_value(secret), api_secret)) {
				secret_authorized = TRUE;
			}
		}
		if(!token_authorized) {
			/* The token based authentication mechanism is enabled, check that the client provided it */
			json_t *token = json_object_get(root, "token");
			if(token && json_is_string(token) && janus_auth_check_token(json_string_value(token))) {
				token_authorized = TRUE;
			}
		}
		/* We consider a request authorized if either the proper API secret or a valid token has been provided */
		if(!secret_authorized && !token_authorized)
			return JANUS_ERROR_UNAUTHORIZED;
	}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, makes sense 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, thinking about it my notes were just wrong... the defaults should NOT be TRUE, because it means that if only one mechanism is enabled, it will always be bypassed by the TRUE on the other, disabled, mechanism (e.g., tokens in use but no API secret, wrong token still passes the check thanks to secret_authorized being TRUE).

I think that was the key reason why we did that change in #2524.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I did not think about that much when implementing the notes :) The previous solution works fine, even though it is a bit more complicated.

if(!gateway->is_api_secret_needed(&janus_http_transport) && !gateway->is_auth_token_needed(&janus_http_transport)) {
gboolean is_api_secret_needed = gateway->is_api_secret_needed(&janus_http_transport);
gboolean is_auth_token_needed = gateway->is_auth_token_needed(&janus_http_transport);
if(!is_api_secret_needed && !is_auth_token_needed) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here: if defaults for secret_authorized and token_authorized are set to TRUE if the related mechanism is disabled, then the checks are simpler. In this case, I agree the check below must get back to an && rather than an || as in the core.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the code based on the suggestion might look like

		gboolean secret_authorized = !gateway->is_api_secret_needed(&janus_http_transport), token_authorized = gateway->is_auth_token_needed(&janus_http_transport);
		if(secret_authorized && token_authorized) {
			/* Nothing to check */
		} else {
			if(!secret_authorized && gateway->is_api_secret_valid(&janus_http_transport, secret)) {
				/* API secret is valid or disabled */
				secret_authorized = TRUE;
			}
			if(!token_authorized && gateway->is_auth_token_valid(&janus_http_transport, token)) {
				/* Token is valid or disabled */
				token_authorized = TRUE;
			}
			/* We consider a request authorized if either the proper API secret or a valid token has been provided */
			if(!secret_authorized && !token_authorized) {
				response = MHD_create_response_from_buffer(0, NULL, MHD_RESPMEM_PERSISTENT);
				janus_http_add_cors_headers(msg, response);
				ret = MHD_queue_response(connection, MHD_HTTP_FORBIDDEN, response);
				MHD_destroy_response(response);
				goto done;
			}
		}

@deep9 deep9 force-pushed the hotfix/token-secret-auth branch 2 times, most recently from ec85112 to 7d5877b Compare March 16, 2021 14:52
@deep9 deep9 force-pushed the hotfix/token-secret-auth branch from 7d5877b to ef089a1 Compare March 16, 2021 15:43
@lminiero
Copy link
Member

Thanks for the additional fixes! I just restarted the automated checks, as they failed for your build due to issues unrelated to the code. I'll make a few tests to see if they work in the different configurations.

@lminiero
Copy link
Member

Seems to be working fine 👍
@deep9, can you sign our CLA? Apparently the bot didn't ask you for some reason (hope it didn't break), but I don't see your ID in the list. That's a prerequisite for merging, thanks!

@lminiero
Copy link
Member

Ok, I see the signature now: merging then, thanks!

@lminiero lminiero merged commit 3a5b318 into meetecho:master Mar 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants