Author: dlee
Date: Thu Jun 27 13:59:06 2013
New Revision: 393061

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=393061
Log:
Clean ups; removed allow_api_key option, because it was silly to have in the 
first place

Modified:
    team/dlee/ari-authn/configs/stasis_http.conf.sample
    team/dlee/ari-authn/main/features_config.c
    team/dlee/ari-authn/main/http.c
    team/dlee/ari-authn/res/res_stasis_http.c
    team/dlee/ari-authn/res/stasis_http/cli.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=393061&r1=393060&r2=393061
==============================================================================
--- team/dlee/ari-authn/configs/stasis_http.conf.sample (original)
+++ team/dlee/ari-authn/configs/stasis_http.conf.sample Thu Jun 27 13:59:06 2013
@@ -12,9 +12,6 @@
 ;read_only = no                ; When set to yes, user is only authorized for
 ;                      ; read-only requests.
 ;
-;allow_api_key = no    ; When set to yes, user may authenticate by appending
-;                      ; ?api_key=username:password to their requests.
-;
 ;password =            ; Crypted or plaintext password (see password_format).
 ;
 ; password_format may be set to plain (the default) or crypt. When set to 
crypt,

Modified: team/dlee/ari-authn/main/features_config.c
URL: 
http://svnview.digium.com/svn/asterisk/team/dlee/ari-authn/main/features_config.c?view=diff&rev=393061&r1=393060&r2=393061
==============================================================================
--- team/dlee/ari-authn/main/features_config.c (original)
+++ team/dlee/ari-authn/main/features_config.c Thu Jun 27 13:59:06 2013
@@ -1792,26 +1792,23 @@
        ast_custom_function_unregister(&featuremap_function);
        ast_custom_function_unregister(&feature_function);
        ast_cli_unregister_multiple(cli_features_config, 
ARRAY_LEN(cli_features_config));
-       //aco_info_destroy(&cfg_info);
+       aco_info_destroy(&cfg_info);
        ao2_global_obj_release(globals);
 }
 
 int ast_features_config_reload(void)
 {
-       //if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
-       //      return -1;
-       //}
+       if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
+               return -1;
+       }
        return 0;
 }
 
-static int (*nowarn)(void);
-
 int ast_features_config_init(void)
 {
-       int res = 0;
-
-       //res = load_config();
-       nowarn = load_config;
+       int res;
+
+       res = load_config();
        res |= __ast_custom_function_register(&feature_function, NULL);
        res |= __ast_custom_function_register(&featuremap_function, NULL);
        res |= ast_cli_register_multiple(cli_features_config, 
ARRAY_LEN(cli_features_config));

Modified: team/dlee/ari-authn/main/http.c
URL: 
http://svnview.digium.com/svn/asterisk/team/dlee/ari-authn/main/http.c?view=diff&rev=393061&r1=393060&r2=393061
==============================================================================
--- team/dlee/ari-authn/main/http.c (original)
+++ team/dlee/ari-authn/main/http.c Thu Jun 27 13:59:06 2013
@@ -900,7 +900,8 @@
        return auth;
 }
 
-#define BASIC_LEN 6 /*!< "Basic " */
+#define BASIC_PREFIX "Basic "
+#define BASIC_LEN 6 /*!< strlen(BASIC_PREFIX) */
 
 struct ast_http_auth *ast_http_get_auth(struct ast_variable *headers)
 {
@@ -908,7 +909,7 @@
 
        for (v = headers; v; v = v->next) {
                const char *base64;
-               char decoded[256];
+               char decoded[256] = {};
                int cnt;
                char *colon;
 
@@ -916,18 +917,30 @@
                        continue;
                }
 
-               if (strncasecmp("Basic ", v->value, BASIC_LEN) != 0) {
-                       ast_log(LOG_WARNING, "Unsuppored Authorization 
scheme\n");
+               if (!ast_begins_with(v->value, BASIC_PREFIX)) {
+                       ast_log(LOG_DEBUG,
+                               "Unsupported Authorization scheme\n");
                        continue;
                }
 
+               /* Basic auth header parsing. RFC 2617, section 2.
+                *   credentials = "Basic" basic-credentials
+                *   basic-credentials = base64-user-pass
+                *   base64-user-pass  = <base64 encoding of user-pass,
+                *                        except not limited to 76 char/line>
+                *   user-pass   = userid ":" password
+                */
+
                base64 = v->value + BASIC_LEN;
 
+               /* This will truncate "userid:password" lines to
+                * sizeof(decoded). The array is long enough that this shouldn't
+                * be a problem */
                cnt = ast_base64decode((unsigned char*)decoded, base64,
                        sizeof(decoded) - 1);
                ast_assert(cnt < sizeof(decoded));
-               decoded[cnt] = '\0';
-
+
+               /* Split the string at the colon */
                colon = strchr(decoded, ':');
                if (!colon) {
                        ast_log(LOG_WARNING, "Invalid Authorization header\n");

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=393061&r1=393060&r2=393061
==============================================================================
--- team/dlee/ari-authn/res/res_stasis_http.c (original)
+++ team/dlee/ari-authn/res/res_stasis_http.c Thu Jun 27 13:59:06 2013
@@ -97,9 +97,6 @@
                                <configOption name="read_only">
                                        <synopsis>When set to yes, user is only 
authorized for read-only requests</synopsis>
                                </configOption>
-                               <configOption name="allow_api_key">
-                                       <synopsis>When set to yes, user may 
authenticate by appending ?api_key=username+password to their 
requests.</synopsis>
-                               </configOption>
                                <configOption name="password">
                                        <synopsis>Crypted or plaintext password 
(see password_format)</synopsis>
                                </configOption>
@@ -129,13 +126,7 @@
 static int is_enabled(void)
 {
        RAII_VAR(struct ari_conf *, cfg, ari_config_get(), ao2_cleanup);
-       return cfg->general->enabled;
-}
-
-static enum ast_json_encoding_format json_format(void)
-{
-       RAII_VAR(struct ari_conf *, cfg, ari_config_get(), ao2_cleanup);
-       return cfg->general->format;
+       return cfg && cfg->general && cfg->general->enabled;
 }
 
 /*! Lock for \ref root_handler */
@@ -700,6 +691,37 @@
 }
 
 /*!
+ * \brief Authenticate a <code>?api_key=userid:password</code>
+ *
+ * \param api_key API key query parameter
+ * \return User object for the authenticated user.
+ * \return \c NULL if authentication failed.
+ */
+static struct ari_conf_user *authenticate_api_key(const char *api_key)
+{
+       RAII_VAR(char *, username, NULL, ast_free);
+       RAII_VAR(struct ari_conf_user *, user, NULL, ao2_cleanup);
+       char *colon;
+
+       username = ast_strdup(api_key);
+       if (!username) {
+               return NULL;
+       }
+
+       /* Split the string */
+       colon = strchr(username, ':');
+       if (!colon) {
+               return NULL;
+       }
+       *colon = '\0';
+
+       user = ari_config_validate_user(username, colon + 1);
+
+       ao2_ref(user, +1);
+       return user;
+}
+
+/*!
  * \brief Authenticate an HTTP request.
  *
  * \param get_params GET parameters of the request.
@@ -723,21 +745,7 @@
        /* ?api_key authentication */
        for (v = get_params; v; v = v->next) {
                if (strcasecmp("api_key", v->name) == 0) {
-                       RAII_VAR(char *, username, NULL, ast_free);
-                       char *colon;
-
-                       username = ast_strdup(v->value);
-                       if (!username) {
-                               return NULL;
-                       }
-
-                       colon = strchr(username, ':');
-                       if (!colon) {
-                               return NULL;
-                       }
-
-                       *colon = '\0';
-                       return ari_config_validate_user(username, colon + 1);
+                       return authenticate_api_key(v->value);
                }
        }
 
@@ -782,7 +790,7 @@
        }
 
        conf = ari_config_get();
-       if (!conf) {
+       if (!conf || !conf->general) {
                return -1;
        }
 
@@ -790,13 +798,26 @@
 
        user = authenticate_user(get_params, headers);
        if (!user) {
-               response.message = ast_json_pack("{s: s}",
-                       "error", "Authentication required");
+               /* Per RFC 2617, section 1.2: The 401 (Unauthorized) response
+                * message is used by an origin server to challenge the
+                * authorization of a user agent. This response MUST include a
+                * WWW-Authenticate header field containing at least one
+                * challenge applicable to the requested resource.
+                */
                response.response_code = 401;
                response.response_text = "Unauthorized";
+
+               /* Section 1.2:
+                *   realm       = "realm" "=" realm-value
+                *   realm-value = quoted-string
+                * Section 2:
+                *   challenge   = "Basic" realm
+                */
                ast_str_append(&response.headers, 0,
                        "WWW-Authenticate: Basic realm=\"%s\"\r\n",
                        conf->general->auth_realm);
+               response.message = ast_json_pack("{s: s}",
+                       "error", "Authentication required");
        } else if (user->read_only && method != AST_HTTP_GET && method != 
AST_HTTP_OPTIONS) {
                response.message = ast_json_pack("{s: s}",
                        "error", "Write access denied");
@@ -837,7 +858,7 @@
                ast_str_append(&response_headers, 0,
                               "Content-type: application/json\r\n");
                if (ast_json_dump_str_format(response.message, &response_body, 
-                               json_format()) != 0) {
+                               conf->general->format) != 0) {
                        /* Error encoding response */
                        response.response_code = 500;
                        response.response_text = "Internal Server Error";

Modified: team/dlee/ari-authn/res/stasis_http/cli.c
URL: 
http://svnview.digium.com/svn/asterisk/team/dlee/ari-authn/res/stasis_http/cli.c?view=diff&rev=393061&r1=393060&r2=393061
==============================================================================
--- team/dlee/ari-authn/res/stasis_http/cli.c (original)
+++ team/dlee/ari-authn/res/stasis_http/cli.c Thu Jun 27 13:59:06 2013
@@ -80,9 +80,8 @@
        struct ari_conf_user *user = obj;
        struct ast_cli_args *a = arg;
 
-       ast_cli(a->fd, "%-*s  %-*s  %s\n",
-               4, AST_CLI_YESNO(user->read_only),
-               7, AST_CLI_YESNO(user->allow_api_key),
+       ast_cli(a->fd, "%-4s  %s\n",
+               AST_CLI_YESNO(user->read_only),
                user->username);
        return 0;
 }
@@ -115,8 +114,8 @@
                return CLI_FAILURE;
        }
 
-       ast_cli(a->fd, "r/o?  API key  Username\n");
-       ast_cli(a->fd, "----  -------  --------\n");
+       ast_cli(a->fd, "r/o?  Username\n");
+       ast_cli(a->fd, "----  --------\n");
 
        ao2_callback(conf->users, OBJ_NODATA, show_users_cb, a);
 
@@ -208,8 +207,6 @@
 
        ast_cli(a->fd, "Username: %s\n", user->username);
        ast_cli(a->fd, "Read only?: %s\n", AST_CLI_YESNO(user->read_only));
-       ast_cli(a->fd, "Allow api_key?: %s\n",
-               AST_CLI_YESNO(user->allow_api_key));
 
        return CLI_SUCCESS;
 }
@@ -241,6 +238,8 @@
                return CLI_FAILURE;
        }
 
+       ast_cli(a->fd,
+               "; Copy the following two lines into stasis_http.conf\n");
        ast_cli(a->fd, "password_format = crypt\n");
        ast_cli(a->fd, "password = %s\n", crypted);
 

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=393061&r1=393060&r2=393061
==============================================================================
--- team/dlee/ari-authn/res/stasis_http/config.c (original)
+++ team/dlee/ari-authn/res/stasis_http/config.c Thu Jun 27 13:59:06 2013
@@ -77,6 +77,7 @@
        return 0;
 }
 
+/*! \brief Destructor for \ref ari_conf_user */
 static void user_dtor(void *obj)
 {
        struct ari_conf_user *user = obj;
@@ -84,10 +85,17 @@
        ast_free(user->username);
 }
 
+/*! \brief Allocate an \ref ari_conf_user for config parsing */
 static void *user_alloc(const char *cat)
 {
        RAII_VAR(struct ari_conf_user *, user, NULL, ao2_cleanup);
-       const char *username = strchr(cat, '-') + 1;
+       const char *username;
+
+       if (!cat) {
+               return NULL;
+       }
+
+       username = strchr(cat, '-') + 1;
 
        if (!username) {
                ast_log(LOG_ERROR, "Invalid user category '%s'\n", cat);
@@ -110,6 +118,7 @@
        return user;
 }
 
+/*! \brief Sorting function for use with red/black tree */
 static int user_sort_cmp(const void *obj_left, const void *obj_right, int 
flags)
 {
        const struct ari_conf_user *user_left = obj_left;
@@ -128,10 +137,17 @@
        }
 }
 
-static void *user_find(struct ao2_container *tmp_container,
-       const char *category)
-{
-       return ao2_find(tmp_container, category, OBJ_KEY);
+/*! \brief \ref aco_type item_find function */
+static void *user_find(struct ao2_container *tmp_container, const char *cat)
+{
+       const char *username;
+
+       if (!cat) {
+               return NULL;
+       }
+
+       username = strchr(cat, '-') + 1;
+       return ao2_find(tmp_container, username, OBJ_KEY);
 }
 
 static struct aco_type user_option = {
@@ -146,7 +162,7 @@
 
 static struct aco_type *user[] = ACO_TYPES(&user_option);
 
-/*! \brief Disposes of the stasis http conf object */
+/*! \brief \ref ari_conf destructor. */
 static void conf_destructor(void *obj)
 {
        struct ari_conf *cfg = obj;
@@ -154,7 +170,7 @@
        ao2_cleanup(cfg->users);
 }
 
-/*! \brief Creates the statis http conf object. */
+/*! \brief Allocate an \ref ari_conf for config parsing */
 static void *conf_alloc(void)
 {
        RAII_VAR(struct ari_conf *, cfg, NULL, ao2_cleanup);
@@ -189,7 +205,11 @@
 
 struct ari_conf *ari_config_get(void)
 {
-       return ao2_global_obj_ref(confs);
+       struct ari_conf *res = ao2_global_obj_ref(confs);
+       if (!res) {
+               ast_log(LOG_ERROR, "Error accessing configuration\n");
+       }
+       return res;
 }
 
 struct ari_conf_user *ari_config_validate_user(const char *username,
@@ -233,7 +253,8 @@
        return user;
 }
 
-static int check_passwords_cb(void *obj, void *arg, int flags)
+/*! \brief Callback to validate a user object */
+static int validate_user_cb(void *obj, void *arg, int flags)
 {
        struct ari_conf_user *user = obj;
 
@@ -245,6 +266,7 @@
        return 0;
 }
 
+/*! \brief Load (or reload) configuration. */
 static int process_config(int reload)
 {
        RAII_VAR(struct ari_conf *, conf, NULL, ao2_cleanup);
@@ -267,7 +289,7 @@
                ast_log(LOG_ERROR, "No configured users for ARI\n");
        }
 
-       ao2_callback(conf->users, OBJ_NODATA, check_passwords_cb, NULL);
+       ao2_callback(conf->users, OBJ_NODATA, validate_user_cb, NULL);
 
        return 0;
 }
@@ -292,9 +314,6 @@
        aco_option_register(&cfg_info, "read_only", ACO_EXACT, user,
                "no", OPT_BOOL_T, 1,
                FLDSET(struct ari_conf_user, read_only));
-       aco_option_register(&cfg_info, "allow_api_key", ACO_EXACT, user,
-               "no", OPT_BOOL_T, 1,
-               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), ARI_PASSWORD_LEN);

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=393061&r1=393060&r2=393061
==============================================================================
--- team/dlee/ari-authn/res/stasis_http/internal.h (original)
+++ team/dlee/ari-authn/res/stasis_http/internal.h Thu Jun 27 13:59:06 2013
@@ -94,8 +94,6 @@
        enum ari_password_format password_format;
        /*! If true, user cannot execute change operations */
        int read_only;
-       /*! If true, user allowed to authenticate with ?api_key=user+password */
-       int allow_api_key;
 };
 
 /*!


--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to