res/ari/config.c File Reference

Config framework stuffz for ARI. More...

#include "asterisk.h"
#include "asterisk/config_options.h"
#include "asterisk/http_websocket.h"
#include "internal.h"

Include dependency graph for res/ari/config.c:

Go to the source code of this file.

Defines

#define CONF_FILENAME   "ari.conf"

Functions

static AO2_GLOBAL_OBJ_STATIC (confs)
 Locking container for safe configuration access.
void ast_ari_config_destroy (void)
 Destroy the ARI configuration.
struct ast_ari_confast_ari_config_get (void)
 Get the current ARI configuration.
int ast_ari_config_init (void)
 Initialize the ARI configuration.
int ast_ari_config_reload (void)
 Reload the ARI configuration.
struct ast_ari_conf_userast_ari_config_validate_user (const char *username, const char *password)
 Validated a user's credentials.
static void * conf_alloc (void)
 Allocate an ast_ari_conf for config parsing.
static void conf_destructor (void *obj)
 ast_ari_conf destructor.
 CONFIG_INFO_STANDARD (cfg_info, confs, conf_alloc,.files=ACO_FILES(&conf_file))
static int encoding_format_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Encoding format handler converts from boolean to enum.
static int password_format_handler (const struct aco_option *opt, struct ast_variable *var, void *obj)
 Parses the ast_ari_password_format enum from a config file.
static int process_config (int reload)
 Load (or reload) configuration.
static void * user_alloc (const char *cat)
 Allocate an ast_ari_conf_user for config parsing.
static void user_dtor (void *obj)
 Destructor for ast_ari_conf_user.
static void * user_find (struct ao2_container *tmp_container, const char *cat)
 aco_type item_find function
static int user_sort_cmp (const void *obj_left, const void *obj_right, int flags)
 Sorting function for use with red/black tree.
static int validate_user_cb (void *obj, void *arg, int flags)
 Callback to validate a user object.

Variables

static struct aco_file conf_file
 The conf file that's processed for the module.
static struct aco_type general_option
 Mapping of the ARI conf struct's globals to the general context in the config file.
static struct aco_typegeneral_options [] = ACO_TYPES(&general_option)
static struct aco_typeuser [] = ACO_TYPES(&user_option)
static struct aco_type user_option


Detailed Description

Config framework stuffz for ARI.

Author:
David M. Lee, II <dlee@digium.com>

Definition in file res/ari/config.c.


Define Documentation

#define CONF_FILENAME   "ari.conf"

Definition at line 198 of file res/ari/config.c.

Referenced by ast_ari_config_get().


Function Documentation

static AO2_GLOBAL_OBJ_STATIC ( confs   )  [static]

Locking container for safe configuration access.

void ast_ari_config_destroy ( void   ) 

Destroy the ARI configuration.

Definition at line 347 of file res/ari/config.c.

References aco_info_destroy(), and ao2_global_obj_release.

Referenced by unload_module().

00348 {
00349    aco_info_destroy(&cfg_info);
00350    ao2_global_obj_release(confs);
00351 }

struct ast_ari_conf* ast_ari_config_get ( void   )  [read]

Get the current ARI configuration.

This is an immutable object, so don't modify it. It is AO2 managed, so ao2_cleanup() when you're done with it.

Returns:
ARI configuration object.

NULL on error.

Definition at line 211 of file res/ari/config.c.

References ao2_global_obj_ref, ast_log, CONF_FILENAME, and LOG_ERROR.

Referenced by ari_show(), ari_show_user(), ari_show_users(), ast_ari_callback(), ast_ari_config_validate_user(), ast_ari_json_format(), ast_ari_websocket_session_create(), complete_ari_user(), is_enabled(), origin_allowed(), and process_config().

00212 {
00213    struct ast_ari_conf *res = ao2_global_obj_ref(confs);
00214    if (!res) {
00215       ast_log(LOG_ERROR,
00216          "Error obtaining config from " CONF_FILENAME "\n");
00217    }
00218    return res;
00219 }

int ast_ari_config_init ( void   ) 

Initialize the ARI configuration.

Definition at line 305 of file res/ari/config.c.

References ACO_EXACT, aco_info_destroy(), aco_info_init(), aco_option_register, aco_option_register_custom, ARI_AUTH_REALM_LEN, ARI_PASSWORD_LEN, AST_DEFAULT_WEBSOCKET_WRITE_TIMEOUT_STR, enabled, encoding_format_handler(), FLDSET, NULL, OPT_BOOL_T, OPT_CHAR_ARRAY_T, OPT_INT_T, OPT_NOOP_T, OPT_STRINGFIELD_T, PARSE_IN_RANGE, password, password_format_handler(), process_config(), ast_ari_conf_user::read_only, and STRFLDSET.

Referenced by load_module().

00306 {
00307    if (aco_info_init(&cfg_info)) {
00308       aco_info_destroy(&cfg_info);
00309       return -1;
00310    }
00311 
00312    aco_option_register(&cfg_info, "enabled", ACO_EXACT, general_options,
00313       "yes", OPT_BOOL_T, 1,
00314       FLDSET(struct ast_ari_conf_general, enabled));
00315    aco_option_register_custom(&cfg_info, "pretty", ACO_EXACT,
00316       general_options, "no",  encoding_format_handler, 0);
00317    aco_option_register(&cfg_info, "auth_realm", ACO_EXACT, general_options,
00318       "Asterisk REST Interface", OPT_CHAR_ARRAY_T, 0,
00319       FLDSET(struct ast_ari_conf_general, auth_realm),
00320       ARI_AUTH_REALM_LEN);
00321    aco_option_register(&cfg_info, "allowed_origins", ACO_EXACT, general_options,
00322       "", OPT_STRINGFIELD_T, 0,
00323       STRFLDSET(struct ast_ari_conf_general, allowed_origins));
00324    aco_option_register(&cfg_info, "websocket_write_timeout", ACO_EXACT, general_options,
00325       AST_DEFAULT_WEBSOCKET_WRITE_TIMEOUT_STR, OPT_INT_T, PARSE_IN_RANGE,
00326       FLDSET(struct ast_ari_conf_general, write_timeout), 1, INT_MAX);
00327 
00328    aco_option_register(&cfg_info, "type", ACO_EXACT, user, NULL,
00329       OPT_NOOP_T, 0, 0);
00330    aco_option_register(&cfg_info, "read_only", ACO_EXACT, user,
00331       "no", OPT_BOOL_T, 1,
00332       FLDSET(struct ast_ari_conf_user, read_only));
00333    aco_option_register(&cfg_info, "password", ACO_EXACT, user,
00334       "", OPT_CHAR_ARRAY_T, 0,
00335       FLDSET(struct ast_ari_conf_user, password), ARI_PASSWORD_LEN);
00336    aco_option_register_custom(&cfg_info, "password_format", ACO_EXACT,
00337       user, "plain",  password_format_handler, 0);
00338 
00339    return process_config(0);
00340 }

int ast_ari_config_reload ( void   ) 

Reload the ARI configuration.

Definition at line 342 of file res/ari/config.c.

References process_config().

Referenced by reload_module().

00343 {
00344    return process_config(1);
00345 }

struct ast_ari_conf_user* ast_ari_config_validate_user ( const char *  username,
const char *  password 
) [read]

Validated a user's credentials.

Parameters:
username Name of the user.
password User's password.
Returns:
User object.

NULL if username or password is invalid.

Definition at line 221 of file res/ari/config.c.

References ao2_cleanup, ao2_find, ao2_ref, ARI_PASSWORD_FORMAT_CRYPT, ARI_PASSWORD_FORMAT_PLAIN, ast_ari_config_get(), ast_crypt_validate(), ast_log, ast_strlen_zero, LOG_WARNING, NULL, OBJ_KEY, and RAII_VAR.

Referenced by authenticate_api_key(), and authenticate_user().

00223 {
00224    RAII_VAR(struct ast_ari_conf *, conf, NULL, ao2_cleanup);
00225    RAII_VAR(struct ast_ari_conf_user *, user, NULL, ao2_cleanup);
00226    int is_valid = 0;
00227 
00228    conf = ast_ari_config_get();
00229    if (!conf) {
00230       return NULL;
00231    }
00232 
00233    user = ao2_find(conf->users, username, OBJ_KEY);
00234    if (!user) {
00235       return NULL;
00236    }
00237 
00238    if (ast_strlen_zero(user->password)) {
00239       ast_log(LOG_WARNING,
00240          "User '%s' missing password; authentication failed\n",
00241          user->username);
00242       return NULL;
00243    }
00244 
00245    switch (user->password_format) {
00246    case ARI_PASSWORD_FORMAT_PLAIN:
00247       is_valid = strcmp(password, user->password) == 0;
00248       break;
00249    case ARI_PASSWORD_FORMAT_CRYPT:
00250       is_valid = ast_crypt_validate(password, user->password);
00251       break;
00252    }
00253 
00254    if (!is_valid) {
00255       return NULL;
00256    }
00257 
00258    ao2_ref(user, +1);
00259    return user;
00260 }

static void* conf_alloc ( void   )  [static]

Allocate an ast_ari_conf for config parsing.

Definition at line 170 of file res/ari/config.c.

References aco_set_defaults(), AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, ao2_container_alloc_rbtree, ao2_ref, ast_string_field_init, conf_destructor(), NULL, RAII_VAR, and user_sort_cmp().

00171 {
00172    RAII_VAR(struct ast_ari_conf *, cfg, NULL, ao2_cleanup);
00173 
00174    cfg = ao2_alloc_options(sizeof(*cfg), conf_destructor,
00175       AO2_ALLOC_OPT_LOCK_NOLOCK);
00176    if (!cfg) {
00177       return NULL;
00178    }
00179 
00180    cfg->general = ao2_alloc_options(sizeof(*cfg->general), NULL,
00181       AO2_ALLOC_OPT_LOCK_NOLOCK);
00182    if (!cfg->general) {
00183       return NULL;
00184    }
00185    aco_set_defaults(&general_option, "general", cfg->general);
00186 
00187    if (ast_string_field_init(cfg->general, 64)) {
00188       return NULL;
00189    }
00190 
00191    cfg->users = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK,
00192       AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, user_sort_cmp, NULL);
00193 
00194    ao2_ref(cfg, +1);
00195    return cfg;
00196 }

static void conf_destructor ( void *  obj  )  [static]

ast_ari_conf destructor.

Definition at line 159 of file res/ari/config.c.

References ao2_cleanup, ast_string_field_free_memory, ast_ari_conf::general, and ast_ari_conf::users.

Referenced by conf_alloc().

00160 {
00161    struct ast_ari_conf *cfg = obj;
00162 
00163    ast_string_field_free_memory(cfg->general);
00164 
00165    ao2_cleanup(cfg->general);
00166    ao2_cleanup(cfg->users);
00167 }

CONFIG_INFO_STANDARD ( cfg_info  ,
confs  ,
conf_alloc  ,
files = ACO_FILES(&conf_file) 
)

static int encoding_format_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
) [static]

Encoding format handler converts from boolean to enum.

Definition at line 49 of file res/ari/config.c.

References AST_JSON_COMPACT, AST_JSON_PRETTY, ast_true(), ast_ari_conf_general::format, ast_variable::name, and ast_variable::value.

Referenced by ast_ari_config_init().

00051 {
00052    struct ast_ari_conf_general *general = obj;
00053 
00054    if (!strcasecmp(var->name, "pretty")) {
00055       general->format = ast_true(var->value) ?
00056          AST_JSON_PRETTY : AST_JSON_COMPACT;
00057    } else {
00058       return -1;
00059    }
00060 
00061    return 0;
00062 }

static int password_format_handler ( const struct aco_option opt,
struct ast_variable var,
void *  obj 
) [static]

Parses the ast_ari_password_format enum from a config file.

Definition at line 65 of file res/ari/config.c.

References ARI_PASSWORD_FORMAT_CRYPT, ARI_PASSWORD_FORMAT_PLAIN, ast_ari_conf_user::password_format, and ast_variable::value.

Referenced by ast_ari_config_init().

00067 {
00068    struct ast_ari_conf_user *user = obj;
00069 
00070    if (strcasecmp(var->value, "plain") == 0) {
00071       user->password_format = ARI_PASSWORD_FORMAT_PLAIN;
00072    } else if (strcasecmp(var->value, "crypt") == 0) {
00073       user->password_format = ARI_PASSWORD_FORMAT_CRYPT;
00074    } else {
00075       return -1;
00076    }
00077 
00078    return 0;
00079 }

static int process_config ( int  reload  )  [static]

Load (or reload) configuration.

Definition at line 276 of file res/ari/config.c.

References aco_process_config(), ACO_PROCESS_ERROR, ACO_PROCESS_OK, ACO_PROCESS_UNCHANGED, ao2_callback, ao2_cleanup, ao2_container_count(), ast_ari_config_get(), ast_assert, ast_log, LOG_ERROR, NULL, OBJ_NODATA, RAII_VAR, and validate_user_cb().

00277 {
00278    RAII_VAR(struct ast_ari_conf *, conf, NULL, ao2_cleanup);
00279 
00280    switch (aco_process_config(&cfg_info, reload)) {
00281    case ACO_PROCESS_ERROR:
00282       return -1;
00283    case ACO_PROCESS_OK:
00284    case ACO_PROCESS_UNCHANGED:
00285       break;
00286    }
00287 
00288    conf = ast_ari_config_get();
00289    if (!conf) {
00290       ast_assert(0); /* We just configured; it should be there */
00291       return -1;
00292    }
00293 
00294    if (conf->general->enabled) {
00295       if (ao2_container_count(conf->users) == 0) {
00296          ast_log(LOG_ERROR, "No configured users for ARI\n");
00297       } else {
00298          ao2_callback(conf->users, OBJ_NODATA, validate_user_cb, NULL);
00299       }
00300    }
00301 
00302    return 0;
00303 }

static void* user_alloc ( const char *  cat  )  [static]

Allocate an ast_ari_conf_user for config parsing.

Definition at line 90 of file res/ari/config.c.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ao2_cleanup, ao2_ref, ast_debug, ast_strdup, NULL, RAII_VAR, and user_dtor().

00091 {
00092    RAII_VAR(struct ast_ari_conf_user *, user, NULL, ao2_cleanup);
00093 
00094    if (!cat) {
00095       return NULL;
00096    }
00097 
00098    ast_debug(3, "Allocating user %s\n", cat);
00099 
00100    user = ao2_alloc_options(sizeof(*user), user_dtor,
00101       AO2_ALLOC_OPT_LOCK_NOLOCK);
00102    if (!user) {
00103       return NULL;
00104    }
00105 
00106    user->username = ast_strdup(cat);
00107    if (!user->username) {
00108       return NULL;
00109    }
00110 
00111    ao2_ref(user, +1);
00112    return user;
00113 }

static void user_dtor ( void *  obj  )  [static]

Destructor for ast_ari_conf_user.

Definition at line 82 of file res/ari/config.c.

References ast_debug, ast_free, and ast_ari_conf_user::username.

Referenced by user_alloc().

00083 {
00084    struct ast_ari_conf_user *user = obj;
00085    ast_debug(3, "Disposing of user %s\n", user->username);
00086    ast_free(user->username);
00087 }

static void* user_find ( struct ao2_container tmp_container,
const char *  cat 
) [static]

aco_type item_find function

Definition at line 135 of file res/ari/config.c.

References ao2_find, NULL, and OBJ_KEY.

00136 {
00137    if (!cat) {
00138       return NULL;
00139    }
00140 
00141    return ao2_find(tmp_container, cat, OBJ_KEY);
00142 }

static int user_sort_cmp ( const void *  obj_left,
const void *  obj_right,
int  flags 
) [static]

Sorting function for use with red/black tree.

Definition at line 116 of file res/ari/config.c.

References OBJ_KEY, OBJ_PARTIAL_KEY, and ast_ari_conf_user::username.

Referenced by conf_alloc().

00117 {
00118    const struct ast_ari_conf_user *user_left = obj_left;
00119 
00120    if (flags & OBJ_PARTIAL_KEY) {
00121       const char *key_right = obj_right;
00122       return strncasecmp(user_left->username, key_right,
00123          strlen(key_right));
00124    } else if (flags & OBJ_KEY) {
00125       const char *key_right = obj_right;
00126       return strcasecmp(user_left->username, key_right);
00127    } else {
00128       const struct ast_ari_conf_user *user_right = obj_right;
00129       const char *key_right = user_right->username;
00130       return strcasecmp(user_left->username, key_right);
00131    }
00132 }

static int validate_user_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Callback to validate a user object.

Definition at line 263 of file res/ari/config.c.

References ast_log, ast_strlen_zero, LOG_WARNING, ast_ari_conf_user::password, and ast_ari_conf_user::username.

Referenced by process_config().

00264 {
00265    struct ast_ari_conf_user *user = obj;
00266 
00267    if (ast_strlen_zero(user->password)) {
00268       ast_log(LOG_WARNING, "User '%s' missing password\n",
00269          user->username);
00270    }
00271 
00272    return 0;
00273 }


Variable Documentation

struct aco_file conf_file [static]

The conf file that's processed for the module.

Definition at line 201 of file res/ari/config.c.

struct aco_type general_option [static]

Mapping of the ARI conf struct's globals to the general context in the config file.

Definition at line 38 of file res/ari/config.c.

struct aco_type* general_options[] = ACO_TYPES(&general_option) [static]

Definition at line 46 of file res/ari/config.c.

struct aco_type* user[] = ACO_TYPES(&user_option) [static]

Definition at line 156 of file res/ari/config.c.

struct aco_type user_option [static]

Definition at line 144 of file res/ari/config.c.


Generated on Thu Apr 16 06:30:25 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6