[asterisk-commits] qwell: trunk r394189 - in /trunk/res: ./ stasis_http/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Jul 12 12:52:54 CDT 2013


Author: qwell
Date: Fri Jul 12 12:52:52 2013
New Revision: 394189

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394189
Log:
ARI: Add support for Cross-Origin Resource Sharing (CORS), origin headers

This rejects requests from any unknown origins.

(closes issue ASTERISK-21278)

Review: https://reviewboard.asterisk.org/r/2667/

Modified:
    trunk/res/res_stasis_http.c
    trunk/res/stasis_http/cli.c
    trunk/res/stasis_http/config.c
    trunk/res/stasis_http/internal.h

Modified: trunk/res/res_stasis_http.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_stasis_http.c?view=diff&rev=394189&r1=394188&r2=394189
==============================================================================
--- trunk/res/res_stasis_http.c (original)
+++ trunk/res/res_stasis_http.c Fri Jul 12 12:52:52 2013
@@ -293,6 +293,26 @@
 	ast_str_append(&response->headers, 0, "\r\n");
 }
 
+static int origin_allowed(const char *origin)
+{
+	RAII_VAR(struct ari_conf *, cfg, ari_config_get(), ao2_cleanup);
+
+	char *allowed = ast_strdupa(cfg->general->allowed_origins);
+	char *current;
+
+	while ((current = strsep(&allowed, ","))) {
+		if (!strcmp(current, "*")) {
+			return 1;
+		}
+
+		if (!strcmp(current, origin)) {
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
 #define ACR_METHOD "Access-Control-Request-Method"
 #define ACR_HEADERS "Access-Control-Request-Headers"
 #define ACA_METHODS "Access-Control-Allow-Methods"
@@ -333,7 +353,7 @@
 	}
 
 	/* CORS 6.2, #1 - "If the Origin header is not present terminate this
-	 * set of steps.
+	 * set of steps."
 	 */
 	if (origin == NULL) {
 		return;
@@ -343,14 +363,16 @@
 	 * case-sensitive match for any of the values in list of origins do not
 	 * set any additional headers and terminate this set of steps.
 	 *
-	 * "Always matching is acceptable since the list of origins can be
+	 * Always matching is acceptable since the list of origins can be
 	 * unbounded.
 	 *
-	 * "The Origin header can only contain a single origin as the user agent
-	 * will not follow redirects.
-	 *
-	 * TODO - pull list of allowed origins from config
-	 */
+	 * The Origin header can only contain a single origin as the user agent
+	 * will not follow redirects."
+	 */
+	if (!origin_allowed(origin)) {
+		ast_log(LOG_NOTICE, "Origin header '%s' does not match an allowed origin.\n", origin);
+		return;
+	}
 
 	/* CORS 6.2, #3 - "If there is no Access-Control-Request-Method header
 	 * or if parsing failed, do not set any additional headers and terminate
@@ -397,7 +419,7 @@
 	 * case-insensitive match for any of the values in list of headers do
 	 * not set any additional headers and terminate this set of steps.
 	 *
-	 * "Note: Always matching is acceptable since the list of headers can be
+	 * Note: Always matching is acceptable since the list of headers can be
 	 * unbounded."
 	 */
 
@@ -423,7 +445,7 @@
 	/* CORS 6.2, #10 - "Add one or more Access-Control-Allow-Headers headers
 	 * consisting of (a subset of) the list of headers.
 	 *
-	 * "Since the list of headers can be unbounded simply returning headers
+	 * Since the list of headers can be unbounded simply returning headers
 	 * can be enough."
 	 */
 	if (!ast_strlen_zero(acr_headers)) {
@@ -700,25 +722,26 @@
 	 * case-sensitive match for any of the values in list of origins, do not
 	 * set any additional headers and terminate this set of steps.
 	 *
-	 * "Note: Always matching is acceptable since the list of origins can be
+	 * Note: Always matching is acceptable since the list of origins can be
 	 * unbounded."
-	 *
-	 * TODO - pull list of allowed origins from config
-	 */
+	 */
+	if (!origin_allowed(origin)) {
+		ast_log(LOG_NOTICE, "Origin header '%s' does not match an allowed origin.\n", origin);
+		return;
+	}
 
 	/* CORS 6.1, #3 - "If the resource supports credentials add a single
 	 * Access-Control-Allow-Origin header, with the value of the Origin
 	 * header as value, and add a single Access-Control-Allow-Credentials
 	 * header with the case-sensitive string "true" as value.
 	 *
-	 * "Otherwise, add a single Access-Control-Allow-Origin header, with
+	 * Otherwise, add a single Access-Control-Allow-Origin header, with
 	 * either the value of the Origin header or the string "*" as value."
-	 *
-	 * TODO - when we add authentication, this will change to
-	 * Access-Control-Allow-Credentials.
 	 */
 	ast_str_append(&response->headers, 0,
 		       "Access-Control-Allow-Origin: %s\r\n", origin);
+	ast_str_append(&response->headers, 0,
+		       "Access-Control-Allow-Credentials: true\r\n");
 
 	/* CORS 6.1, #4 - "If the list of exposed headers is not empty add one
 	 * or more Access-Control-Expose-Headers headers, with as values the

Modified: trunk/res/stasis_http/cli.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/stasis_http/cli.c?view=diff&rev=394189&r1=394188&r2=394189
==============================================================================
--- trunk/res/stasis_http/cli.c (original)
+++ trunk/res/stasis_http/cli.c Fri Jul 12 12:52:52 2013
@@ -71,6 +71,7 @@
 	}
 	ast_cli(a->fd, "\n");
 	ast_cli(a->fd, "Auth realm: %s\n", conf->general->auth_realm);
+	ast_cli(a->fd, "Allowed Origins: %s\n", conf->general->allowed_origins);
 	ast_cli(a->fd, "User count: %d\n", ao2_container_count(conf->users));
 	return CLI_SUCCESS;
 }

Modified: trunk/res/stasis_http/config.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/stasis_http/config.c?view=diff&rev=394189&r1=394188&r2=394189
==============================================================================
--- trunk/res/stasis_http/config.c (original)
+++ trunk/res/stasis_http/config.c Fri Jul 12 12:52:52 2013
@@ -158,6 +158,9 @@
 static void conf_destructor(void *obj)
 {
 	struct ari_conf *cfg = obj;
+
+	ast_string_field_free_memory(cfg->general);
+
 	ao2_cleanup(cfg->general);
 	ao2_cleanup(cfg->users);
 }
@@ -179,6 +182,10 @@
 		return NULL;
 	}
 	aco_set_defaults(&general_option, "general", cfg->general);
+
+	if (ast_string_field_init(cfg->general, 64)) {
+		return NULL;
+	}
 
 	cfg->users = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK,
 		AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, user_sort_cmp, NULL);
@@ -308,6 +315,9 @@
 		"Asterisk REST Interface", OPT_CHAR_ARRAY_T, 0,
 		FLDSET(struct ari_conf_general, auth_realm),
 		ARI_AUTH_REALM_LEN);
+	aco_option_register(&cfg_info, "allowed_origins", ACO_EXACT, general_options,
+		"", OPT_STRINGFIELD_T, 0,
+		STRFLDSET(struct ari_conf_general, allowed_origins));
 
 	aco_option_register(&cfg_info, "type", ACO_EXACT, user, NULL,
 		OPT_NOOP_T, 0, 0);

Modified: trunk/res/stasis_http/internal.h
URL: http://svnview.digium.com/svn/asterisk/trunk/res/stasis_http/internal.h?view=diff&rev=394189&r1=394188&r2=394189
==============================================================================
--- trunk/res/stasis_http/internal.h (original)
+++ trunk/res/stasis_http/internal.h Fri Jul 12 12:52:52 2013
@@ -67,6 +67,10 @@
 	enum ast_json_encoding_format format;
 	/*! Authentication realm */
 	char auth_realm[ARI_AUTH_REALM_LEN];
+
+	AST_DECLARE_STRING_FIELDS(
+		AST_STRING_FIELD(allowed_origins);
+	);
 };
 
 /*! \brief Password format */




More information about the asterisk-commits mailing list