[asterisk-commits] dlee: branch dlee/ari-authn r392852 - in /team/dlee/ari-authn: configs/ main/...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jun 25 11:22:52 CDT 2013
Author: dlee
Date: Tue Jun 25 11:22:50 2013
New Revision: 392852
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=392852
Log:
User config parsing
Modified:
team/dlee/ari-authn/configs/stasis_http.conf.sample
team/dlee/ari-authn/main/features_config.c
team/dlee/ari-authn/res/res_stasis_http.c
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=392852&r1=392851&r2=392852
==============================================================================
--- team/dlee/ari-authn/configs/stasis_http.conf.sample (original)
+++ team/dlee/ari-authn/configs/stasis_http.conf.sample Tue Jun 25 11:22:50 2013
@@ -11,15 +11,14 @@
; ; read-only requests
;
;allow_api_key = no ; When set to yes, user may authenticate by appending
-; ; ?api_key=username+password. Otherwise, the user may
-; ; use only HTTP basic authentication.
+; ; ?api_key=username+password to their requests.
;
-;password = ; Crypted or plaintext password (see crypt_password)
+;password = ; Crypted or plaintext password (see password_format)
;
-; crypt_password may be set to crypt (the default) or plain. When set to crypt,
-; crypt(3) is used to encrypt the password. A crypted password can be generated
+; password_format may be set to plain (the default) or crypt. When set to crypt,
+; crypt(3) is used to validate the password. A crypted password can be generated
; using mkpasswd -m sha-512.
;
; When set to plain, the password is in plaintext
;
-;crypt_password = plain
+;password_format = plain
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=392852&r1=392851&r2=392852
==============================================================================
--- team/dlee/ari-authn/main/features_config.c (original)
+++ team/dlee/ari-authn/main/features_config.c Tue Jun 25 11:22:50 2013
@@ -1792,23 +1792,26 @@
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;
-
- res = load_config();
+ int res = 0;
+
+ //res = load_config();
+ nowarn = 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/res/res_stasis_http.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-authn/res/res_stasis_http.c?view=diff&rev=392852&r1=392851&r2=392852
==============================================================================
--- team/dlee/ari-authn/res/res_stasis_http.c (original)
+++ team/dlee/ari-authn/res/res_stasis_http.c Tue Jun 25 11:22:50 2013
@@ -88,6 +88,22 @@
<synopsis>Responses from stasis-http are formatted to be human readable</synopsis>
</configOption>
</configObject>
+
+ <configObject name="user">
+ <synopsis>Per-user configuration settings</synopsis>
+ <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>
+ <configOption name="password_format">
+ <synopsis>password_format may be set to plain (the default) or crypt. When set to crypt, crypt(3) is used to validate the password. A crypted password can be generated using mkpasswd -m sha-512. When set to plain, the password is in plaintext</synopsis>
+ </configOption>
+ </configObject>
</configFile>
</configInfo>
***/
@@ -108,15 +124,83 @@
/*! \brief Global configuration options for stasis http. */
struct conf_global_options {
/*! Enabled by default, disabled if false. */
- int enabled:1;
+ int enabled;
/*! Encoding format used during output (default compact). */
enum ast_json_encoding_format format;
};
+
+/*! \brief Password format */
+enum password_format {
+ /*! \brief Plaintext password */
+ PASSWORD_FORMAT_PLAIN,
+ /*! crypt(3) password */
+ PASSWORD_FORMAT_CRYPT,
+};
+
+struct conf_user_options {
+ /*! Username for authentication */
+ char username[128];
+ /*! User's password. If 256 seems like a lot, a crypt SHA-512 has over
+ * 100 characters */
+ char password[256];
+ /*! Format for the password field */
+ enum 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;
+};
+
+static void user_dtor(void *obj)
+{
+ struct conf_user_options *user = obj;
+
+ ast_debug(3, "Disposing of user %s", user->username);
+}
+
+static void *user_alloc(const char *cat)
+{
+ RAII_VAR(struct conf_user_options *, user, NULL, ao2_cleanup);
+ const char *username = strchr(cat, '-') + 1;
+
+ if (!username) {
+ ast_log(LOG_ERROR, "Invalid user category '%s'\n", cat);
+ return NULL;
+ }
+
+ ast_debug(3, "Allocating user %s\n", cat);
+
+ user = ao2_alloc(sizeof(*user), user_dtor);
+ if (!user) {
+ return NULL;
+ }
+
+ ao2_ref(user, +1);
+ return user;
+}
+
+static int user_sort_cmp(const void *obj_left, const void *obj_right, int flags)
+{
+ const struct conf_user_options *user_left = obj_left;
+ const struct conf_user_options *user_right = obj_right;
+ const char *right_key =
+ (flags & OBJ_KEY) ? obj_right : user_right->username;
+
+ return strcmp(user_left->username, right_key);
+}
+
+static void *user_find(struct ao2_container *tmp_container,
+ const char *category)
+{
+ return ao2_find(tmp_container, category, OBJ_KEY);
+}
/*! \brief All configuration options for stasis http. */
struct conf {
/*! The general section configuration options. */
struct conf_global_options *global;
+ /*! Configured users */
+ struct ao2_container *users;
};
/*! \brief Locking container for safe configuration access. */
@@ -129,32 +213,50 @@
.name = "global",
.item_offset = offsetof(struct conf, global),
.category = "^general$",
- .category_match = ACO_WHITELIST
+ .category_match = ACO_WHITELIST,
};
static struct aco_type *global_options[] = ACO_TYPES(&global_option);
+
+static struct aco_type user_option = {
+ .type = ACO_ITEM,
+ .name = "user",
+ .category_match = ACO_WHITELIST,
+ .category = "^user-.+$",
+ .item_alloc = user_alloc,
+ .item_find = user_find,
+ .item_offset = offsetof(struct conf, users),
+};
+
+static struct aco_type *user_options[] = ACO_TYPES(&user_option);
/*! \brief Disposes of the stasis http conf object */
static void conf_destructor(void *obj)
{
- struct conf *cfg = obj;
- ao2_cleanup(cfg->global);
+ struct conf *cfg = obj;
+ ao2_cleanup(cfg->global);
}
/*! \brief Creates the statis http conf object. */
static void *conf_alloc(void)
{
- struct conf *cfg;
-
- if (!(cfg = ao2_alloc(sizeof(*cfg), conf_destructor))) {
- return NULL;
- }
-
- if (!(cfg->global = ao2_alloc(sizeof(*cfg->global), NULL))) {
- ao2_ref(cfg, -1);
- return NULL;
- }
- return cfg;
+ RAII_VAR(struct conf *, cfg, NULL, ao2_cleanup);
+
+ cfg = ao2_alloc(sizeof(*cfg), conf_destructor);
+ if (!cfg) {
+ return NULL;
+ }
+
+ cfg->global = ao2_alloc(sizeof(*cfg->global), NULL);
+ if (!cfg->global) {
+ return NULL;
+ }
+
+ cfg->users = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK,
+ AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, user_sort_cmp, NULL);
+
+ ao2_ref(cfg, +1);
+ return cfg;
}
/*! \brief The conf file that's processed for the module. */
@@ -162,19 +264,19 @@
/*! The config file name. */
.filename = "stasis_http.conf",
/*! The mapping object types to be processed. */
- .types = ACO_TYPES(&global_option),
+ .types = ACO_TYPES(&global_option, &user_option),
};
CONFIG_INFO_STANDARD(cfg_info, confs, conf_alloc,
.files = ACO_FILES(&conf_file));
-/*! \brief Bitfield handler since it is not possible to take address. */
-static int conf_bitfield_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+/*! \brief Encoding format handler converts from boolean to enum. */
+static int encoding_format_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
{
struct conf_global_options *global = obj;
- if (!strcasecmp(var->name, "enabled")) {
- global->enabled = ast_true(var->value);
+ if (!strcasecmp(var->name, "pretty")) {
+ global->format = ast_true(var->value) ? AST_JSON_PRETTY : AST_JSON_COMPACT;
} else {
return -1;
}
@@ -182,13 +284,14 @@
return 0;
}
-/*! \brief Encoding format handler converts from boolean to enum. */
-static int encoding_format_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
-{
- struct conf_global_options *global = obj;
-
- if (!strcasecmp(var->name, "pretty")) {
- global->format = ast_true(var->value) ? AST_JSON_PRETTY : AST_JSON_COMPACT;
+static int password_format_handler(const struct aco_option *opt, struct ast_variable *var, void *obj)
+{
+ struct conf_user_options *user = obj;
+
+ if (strcasecmp(var->value, "plain") == 0) {
+ user->password_format = PASSWORD_FORMAT_PLAIN;
+ } else if (strcasecmp(var->value, "crypt") == 0) {
+ user->password_format = PASSWORD_FORMAT_CRYPT;
} else {
return -1;
}
@@ -881,10 +984,23 @@
return AST_MODULE_LOAD_DECLINE;
}
- aco_option_register_custom(&cfg_info, "enabled", ACO_EXACT, global_options,
- "yes", conf_bitfield_handler, 0);
- aco_option_register_custom(&cfg_info, "pretty", ACO_EXACT, global_options,
- "no", encoding_format_handler, 0);
+ aco_option_register(&cfg_info, "enabled", ACO_EXACT, global_options,
+ "yes", OPT_BOOL_T, 1,
+ FLDSET(struct conf_global_options, enabled));
+ aco_option_register_custom(&cfg_info, "pretty", ACO_EXACT,
+ global_options, "no", encoding_format_handler, 0);
+
+ aco_option_register(&cfg_info, "read_only", ACO_EXACT, user_options,
+ "no", OPT_BOOL_T, 1,
+ FLDSET(struct conf_user_options, read_only));
+ aco_option_register(&cfg_info, "allow_api_key", ACO_EXACT, user_options,
+ "no", OPT_BOOL_T, 1,
+ FLDSET(struct conf_user_options, allow_api_key));
+ aco_option_register(&cfg_info, "password", ACO_EXACT, user_options,
+ "", OPT_CHAR_ARRAY_T, 0,
+ FLDSET(struct conf_user_options, password));
+ aco_option_register_custom(&cfg_info, "password_format", ACO_EXACT,
+ user_options, "plain", password_format_handler, 0);
if (aco_process_config(&cfg_info, 0)) {
aco_info_destroy(&cfg_info);
@@ -895,7 +1011,10 @@
"{s: s}", "message", "Allocation failed");
if (is_enabled()) {
+ ast_debug(3, "ARI enabled\n");
ast_http_uri_link(&http_uri);
+ } else {
+ ast_debug(3, "ARI disabled\n");
}
return AST_MODULE_LOAD_SUCCESS;
@@ -907,6 +1026,7 @@
alloc_failed_message = NULL;
if (is_enabled()) {
+ ast_debug(3, "Disabling ARI\n");
ast_http_uri_unlink(&http_uri);
}
@@ -929,8 +1049,10 @@
}
if (was_enabled && !is_enabled()) {
+ ast_debug(3, "Disabling ARI\n");
ast_http_uri_unlink(&http_uri);
} else if (!was_enabled && is_enabled()) {
+ ast_debug(3, "Enabling ARI\n");
ast_http_uri_link(&http_uri);
}
More information about the asterisk-commits
mailing list