[asterisk-commits] jrose: branch jrose/nacl_branch r368457 - /team/jrose/nacl_branch/main/nacl.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Jun 4 15:40:41 CDT 2012
Author: jrose
Date: Mon Jun 4 15:40:40 2012
New Revision: 368457
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=368457
Log:
Oops, forgot to add nacl.c
Added:
team/jrose/nacl_branch/main/nacl.c (with props)
Added: team/jrose/nacl_branch/main/nacl.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/nacl_branch/main/nacl.c?view=auto&rev=368457
==============================================================================
--- team/jrose/nacl_branch/main/nacl.c (added)
+++ team/jrose/nacl_branch/main/nacl.c Mon Jun 4 15:40:40 2012
@@ -1,0 +1,288 @@
+/*
+ * Asterisk -- A telephony toolkit for Linux.
+ *
+ * Copyright (C) 1999-2012, Digium, Inc.
+ *
+ * Jonathan Rose <jrose at digium.com> - Named ACL coder
+ * Olle E. Johanson <oej at something> - Named ACL concepts
+ * Mark Spencer <markster at digium.com> - Asterisk Author
+ *
+ * v1.0 - (XX-XX-12)
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/config.h"
+#include "asterisk/utils.h"
+#include "asterisk/module.h"
+#include "asterisk/cli.h"
+#include "asterisk/acl.h"
+#include "asterisk/astobj2.h"
+
+#define NACL_CONFIG "nacl.conf"
+
+#define NAME_LENGTH 80
+
+static struct ao2_container *nacl_list;
+
+struct nacl {
+ struct ast_ha *ha;
+ char name[NAME_LENGTH]; /* Same max length as a configuration category */
+};
+
+static void destroy_nacl(void *obj)
+{
+ struct nacl *nacl = obj;
+ ast_free_ha(nacl->ha);
+}
+
+static void add_nacl_from_config(char *name, struct ast_variable *input)
+{
+ struct nacl tmp;
+ struct nacl *nacl;
+ struct ast_variable *var = input;
+
+ ast_copy_string(tmp.name, name, sizeof(tmp.name));
+
+ nacl = ao2_find(nacl_list, &tmp, OBJ_POINTER);
+
+ if (nacl) {
+ ast_log(LOG_ERROR, "Multiple definitions present for nacl: %s\n", name);
+ ao2_ref(nacl, -1);
+ return;
+ }
+
+ nacl = ao2_alloc(sizeof(*nacl), destroy_nacl);
+
+ if (!nacl) {
+ ast_log(LOG_ERROR, "Failed to allocate ao2 object for nacl.\n");
+ return;
+ }
+
+ nacl->ha = NULL;
+ ast_copy_string(nacl->name, name, sizeof(nacl->name));
+
+ while(var) {
+ if (!strcasecmp(var->name, "permit") || !strcasecmp(var->name, "deny")) {
+ int ha_error = 0;
+ nacl->ha = ast_append_ha(var->name, var->value, nacl->ha, &ha_error);
+ if (ha_error) {
+ ast_log(LOG_ERROR, "Bad ACL entry in nacl configuration line %d : %s\n", var->lineno, var->value);
+ }
+ }
+ var = var->next;
+ }
+ ao2_link(nacl_list, nacl);
+ ao2_ref(nacl, -1);
+
+
+}
+
+static int nacl_hash_fn(const void *obj, const int flags)
+{
+ const struct nacl *entry = obj;
+ return ast_str_hash(entry->name);
+}
+
+static int nacl_cmp_fn(void *obj, void *arg, const int flags)
+{
+ struct nacl *entry1 = obj;
+ struct nacl *entry2 = arg;
+
+ return (!strcmp(entry1->name, entry2->name)) ? (CMP_MATCH | CMP_STOP) : 0;
+}
+
+static void nacl_list_scrub(void)
+{
+ struct ao2_iterator i;
+ void *o;
+
+ i = ao2_iterator_init(nacl_list, 0);
+
+ while ((o = ao2_iterator_next(&i))) {
+ ao2_unlink(nacl_list, o);
+ ao2_ref(o, -1);
+ }
+
+ ao2_iterator_destroy(&i);
+}
+
+static int load_nacl_config(int reload)
+{
+ static char *cat = NULL;
+ struct ast_config *cfg = NULL;
+ struct ast_variable *var = NULL;
+ struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
+
+ if ((cfg = ast_config_load(NACL_CONFIG, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
+ return -1;
+ }
+
+ if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
+ ast_log(LOG_WARNING, "No such configuration file %s\n", NACL_CONFIG);
+ return 0;
+ }
+
+ /* We need to lock the list since we'll be wiping it and repopulating it. */
+ ao2_lock(nacl_list);
+
+ /* If reloading, clean the list. Otherwise, we need to create the list. */
+ if (reload) {
+ /* scrub the nacl entries */
+ nacl_list_scrub();
+ } else {
+ nacl_list = ao2_container_alloc(37, nacl_hash_fn, nacl_cmp_fn);
+ }
+
+
+ cat = ast_category_browse(cfg, NULL);
+ while (cat) {
+ if (strcasecmp(cat, "general")) {
+ var = ast_variable_browse(cfg, cat);
+ add_nacl_from_config(cat, var);
+ }
+ cat = ast_category_browse(cfg, cat);
+ }
+
+ /* It's safe to unlock the list now. */
+ ao2_unlock(nacl_list);
+
+ ast_config_destroy(cfg);
+ return 1;
+}
+
+struct ast_ha *ast_append_nacl(struct ast_ha *ha, const char *name)
+{
+ struct nacl tmp;
+ struct nacl *nacl;
+
+ ast_copy_string(tmp.name, name, sizeof(tmp.name));
+
+ nacl = ao2_find(nacl_list, &tmp, OBJ_POINTER);
+
+ if (!nacl) {
+ ast_log(LOG_ERROR, "nacl '%s' does not exist. Could not apply nacl.\n", name);
+ return ha;
+ }
+
+ /* Apply Staples! */
+ ha = ast_duplicate_and_append_ha(ha, nacl->ha);
+
+ ao2_ref(nacl, -1);
+
+ return ha;
+}
+
+static void reload_nacl(int fd)
+{
+ ast_cli(fd, "Reloading nacl configuration...\n");
+ if (load_nacl_config(1) == 1) {
+ ast_cli(fd, "Any modules using statically defined ACLs which were using existing nacls will need to be reloaded for changes to take effect.\n");
+ }
+}
+
+static void cli_display_nacl(int fd, const char *name)
+{
+ struct nacl tmp;
+ struct nacl *nacl;
+ struct ast_ha *ha;
+
+ ast_copy_string(tmp.name, name, sizeof(tmp.name));
+
+ nacl = ao2_find(nacl_list, &tmp, OBJ_POINTER);
+
+ if (!nacl) {
+ /* nacl not found message */
+ ast_cli(fd, "\nCould not find acl named '%s'\n", name);
+ return;
+ }
+
+ ast_cli(fd, "\n%s\n--------------------------------------------------\n", name);
+ for (ha = nacl->ha; ha; ha = ha->next) {
+ char *output = ast_sockaddr_stringify(&ha->addr);
+ ast_cli(fd, "%s - %s\n", ha->sense == AST_SENSE_ALLOW ? "allow" : " deny", output);
+ }
+
+ ao2_ref(nacl, -1);
+}
+
+static void cli_display_nacl_list(int fd)
+{
+ struct ao2_iterator i;
+ void *o;
+
+ i = ao2_iterator_init(nacl_list, 0);
+
+ ast_cli(fd, "\nnacl\n----\n");
+
+ while ((o = ao2_iterator_next(&i))) {
+ struct nacl *nacl = o;
+
+ ast_cli(fd, "%s\n", nacl->name);
+
+ ao2_ref(o, -1);
+ }
+
+ ao2_iterator_destroy(&i);
+}
+
+static char *handle_nacl_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "nacl reload";
+ e->usage =
+ "Usage: nacl reload\n"
+ " Reloads the nacl configuration.\n";
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if (a->argc > 2) {
+ return CLI_SHOWUSAGE;
+ }
+
+ reload_nacl(a->fd);
+ return CLI_SUCCESS;
+}
+
+static char *handle_show_nacl_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "nacl show";
+ e->usage =
+ "Usage: nacl show <name>\n"
+ " Shows a list of named ACLs or lists all entries in a given named ACL.\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if (a->argc == 2) {
+ cli_display_nacl_list(a->fd);
+ return CLI_SUCCESS;
+ }
+
+ if (a->argc == 3) {
+ cli_display_nacl(a->fd, a->argv[2]);
+ return CLI_SUCCESS;
+ }
+
+
+ return CLI_SHOWUSAGE;
+}
+
+static struct ast_cli_entry cli_nacl[] = {
+ AST_CLI_DEFINE(handle_nacl_reload, "Reload nacl configurations"),
+ AST_CLI_DEFINE(handle_show_nacl_cmd, "Show a named ACL or list all named ACLs"),
+};
+
+int init_nacl()
+{
+ load_nacl_config(0);
+ ast_cli_register_multiple(cli_nacl, ARRAY_LEN(cli_nacl));
+ return 0;
+}
Propchange: team/jrose/nacl_branch/main/nacl.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/jrose/nacl_branch/main/nacl.c
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Rev URL"
Propchange: team/jrose/nacl_branch/main/nacl.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
More information about the asterisk-commits
mailing list