[asterisk-commits] dlee: branch dlee/ari-authn r392883 - in /team/dlee/ari-authn: configs/ res/ ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jun 25 15:13:19 CDT 2013


Author: dlee
Date: Tue Jun 25 15:13:17 2013
New Revision: 392883

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=392883
Log:
?api_key validation works. Surprisingly.

Modified:
    team/dlee/ari-authn/configs/stasis_http.conf.sample
    team/dlee/ari-authn/res/res_stasis_http.c
    team/dlee/ari-authn/res/stasis_http/config.c
    team/dlee/ari-authn/res/stasis_http/internal.h

Modified: team/dlee/ari-authn/configs/stasis_http.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-authn/configs/stasis_http.conf.sample?view=diff&rev=392883&r1=392882&r2=392883
==============================================================================
--- team/dlee/ari-authn/configs/stasis_http.conf.sample (original)
+++ team/dlee/ari-authn/configs/stasis_http.conf.sample Tue Jun 25 15:13:17 2013
@@ -11,7 +11,7 @@
 ;			; read-only requests
 ;
 ;allow_api_key = no	; When set to yes, user may authenticate by appending
-;			; ?api_key=username+password to their requests.
+;			; ?api_key=username:password to their requests.
 ;
 ;password =		; Crypted or plaintext password (see password_format)
 ;

Modified: team/dlee/ari-authn/res/res_stasis_http.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-authn/res/res_stasis_http.c?view=diff&rev=392883&r1=392882&r2=392883
==============================================================================
--- team/dlee/ari-authn/res/res_stasis_http.c (original)
+++ team/dlee/ari-authn/res/res_stasis_http.c Tue Jun 25 15:13:17 2013
@@ -663,6 +663,43 @@
 	 */
 }
 
+/*!
+ * \brief Authenticate an HTTP request.
+ *
+ * \param get_params GET parameters of the request.
+ * \param header HTTP headers.
+ * \return User object for the authenticated user.
+ * \return \c NULL if authentication failed.
+ */
+static struct ari_conf_user *authenticate_user(struct ast_variable *get_params,
+	struct ast_variable *headers)
+{
+	struct ast_variable *v;
+
+	for (v = get_params; v; v = v->next) {
+		if (strcasecmp("api_key", v->name) == 0) {
+			RAII_VAR(char *, username, NULL, ast_free);
+			char *colon;
+			char *password;
+
+			username = ast_strdup(v->value);
+			if (!username) {
+				return NULL;
+			}
+
+			colon = strchr(username, ':');
+			if (!colon) {
+				return NULL;
+			}
+
+			*colon = '\0';
+			password = colon + 1;
+			return ari_config_validate_user(username, password);
+		}
+	}
+
+	return NULL;
+}
 
 /*!
  * \internal
@@ -687,6 +724,7 @@
 {
 	RAII_VAR(struct ast_str *, response_headers, ast_str_create(40), ast_free);
 	RAII_VAR(struct ast_str *, response_body, ast_str_create(256), ast_free);
+	RAII_VAR(struct ari_conf_user *, user, NULL, ao2_cleanup);
 	struct stasis_http_response response = {};
 	int ret = 0;
 
@@ -698,7 +736,20 @@
 
 	process_cors_request(headers, &response);
 
-	if (ast_ends_with(uri, "/")) {
+	user = authenticate_user(get_params, headers);
+	if (!user) {
+		response.message = ast_json_pack("{s: s}",
+			"error", "Authentication required");
+		response.response_code = 401;
+		response.response_text = "Unauthorized";
+		ast_str_append(&response.headers, 0,
+			"WWW-Authenticate: Basic realm=\"Asterisk\"");
+	} else if (user->read_only && method != AST_HTTP_GET && method != AST_HTTP_OPTIONS) {
+		response.message = ast_json_pack("{s: s}",
+			"error", "Write access denied");
+		response.response_code = 403;
+		response.response_text = "Forbidden";
+	} else if (ast_ends_with(uri, "/")) {
 		remove_trailing_slash(uri, &response);
 	} else if (ast_begins_with(uri, "api-docs/")) {
 		/* Serving up API docs */

Modified: team/dlee/ari-authn/res/stasis_http/config.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-authn/res/stasis_http/config.c?view=diff&rev=392883&r1=392882&r2=392883
==============================================================================
--- team/dlee/ari-authn/res/stasis_http/config.c (original)
+++ team/dlee/ari-authn/res/stasis_http/config.c Tue Jun 25 15:13:17 2013
@@ -221,6 +221,60 @@
 CONFIG_INFO_STANDARD(cfg_info, confs, conf_alloc,
 		     .files = ACO_FILES(&conf_file));
 
+struct ari_conf *ari_config_get(void)
+{
+	return ao2_global_obj_ref(confs);
+}
+
+AST_MUTEX_DEFINE_STATIC(crypt_mutex);
+
+static int ari_crypt_validate(const char *password, const char *expected)
+{
+	SCOPED_MUTEX(lock, &crypt_mutex);
+	return strcmp(expected, crypt(password, expected)) == 0;
+}
+
+struct ari_conf_user *ari_config_validate_user(const char *username,
+	const char *password)
+{
+	RAII_VAR(struct ari_conf *, conf, NULL, ao2_cleanup);
+	RAII_VAR(struct ari_conf_user *, user, NULL, ao2_cleanup);
+	int is_valid = 0;
+
+	conf = ari_config_get();
+	if (!conf) {
+		return NULL;
+	}
+
+	user = ao2_find(conf->users, username, OBJ_KEY);
+	if (!user) {
+		return NULL;
+	}
+
+	if (ast_strlen_zero(user->password)) {
+		ast_log(LOG_ERROR,
+			"User '%s' missing password; authentication failed\n",
+			user->username);
+		return NULL;
+	}
+
+	switch (user->password_format) {
+	case ARI_PASSWORD_FORMAT_PLAIN:
+		is_valid = strcmp(password, user->password) == 0;
+		break;
+	case ARI_PASSWORD_FORMAT_CRYPT:
+		is_valid = ari_crypt_validate(password, user->password);
+		break;
+	}
+
+	if (!is_valid) {
+		return NULL;
+	}
+
+	ao2_ref(user, +1);
+	return user;
+}
+
 int ari_config_init(void)
 {
 	if (aco_info_init(&cfg_info)) {
@@ -242,7 +296,7 @@
 		FLDSET(struct ari_conf_user, allow_api_key));
 	aco_option_register(&cfg_info, "password", ACO_EXACT, user,
 		"", OPT_CHAR_ARRAY_T, 0,
-		FLDSET(struct ari_conf_user, password));
+		FLDSET(struct ari_conf_user, password), 256);
 	aco_option_register_custom(&cfg_info, "password_format", ACO_EXACT,
 		user, "plain",  password_format_handler, 0);
 
@@ -272,9 +326,3 @@
 	aco_info_destroy(&cfg_info);
 	ao2_global_obj_release(confs);
 }
-
-struct ari_conf *ari_config_get(void)
-{
-	return ao2_global_obj_ref(confs);
-}
-

Modified: team/dlee/ari-authn/res/stasis_http/internal.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-authn/res/stasis_http/internal.h?view=diff&rev=392883&r1=392882&r2=392883
==============================================================================
--- team/dlee/ari-authn/res/stasis_http/internal.h (original)
+++ team/dlee/ari-authn/res/stasis_http/internal.h Tue Jun 25 15:13:17 2013
@@ -113,6 +113,17 @@
  */
 struct ari_conf *ari_config_get(void);
 
+/*!
+ * \brief Validated a user's credentials.
+ *
+ * \param username Name of the user.
+ * \param password User's password.
+ * \return User object.
+ * \return \c NULL if username or password is invalid.
+ */
+struct ari_conf_user *ari_config_validate_user(const char *username,
+	const char *password);
+
 /*! @} */
 
 




More information about the asterisk-commits mailing list