[asterisk-commits] oej: branch oej/deluxepine-1.4 r237089 - /team/oej/deluxepine-1.4/main/nacl.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Dec 30 17:23:21 CST 2009
Author: oej
Date: Wed Dec 30 17:23:19 2009
New Revision: 237089
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=237089
Log:
Adding CLI commands for manipulating NACLs. Next up is manager...
Modified:
team/oej/deluxepine-1.4/main/nacl.c
Modified: team/oej/deluxepine-1.4/main/nacl.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/deluxepine-1.4/main/nacl.c?view=diff&rev=237089&r1=237088&r2=237089
==============================================================================
--- team/oej/deluxepine-1.4/main/nacl.c (original)
+++ team/oej/deluxepine-1.4/main/nacl.c Wed Dec 30 17:23:19 2009
@@ -61,6 +61,7 @@
char tag[MAXHOSTNAMELEN]; /*!< Name of this ACL */
struct ast_ha *acl; /*!< The actual ACL */
int rules; /*!< Number of ACL rules */
+ int manipulated; /*!< Manipulated by CLI or manager */
char owner[20]; /*!< Owner (module) */
char desc[80]; /*!< Description */
};
@@ -196,58 +197,219 @@
ASTOBJ_UNREF(nacl, nacl_destroy);
}
+/*! \brief Update a HA list by inserting or deleting a row at a specific position
+ if inser is false, it means delete
+*/
+static struct ast_ha *ha_update(struct ast_ha *ha, int line, int insert, struct ast_ha *new)
+{
+ struct ast_ha *next = ha;
+ struct ast_ha *temp = NULL;
+ int rule = 0;
+
+ /* IF we have nothing to insert, just give up */
+ if (insert && !new) {
+ return ha;
+ }
+
+ /* If there's no existing ha we have nothing to delete */
+ if (!insert && !ha) {
+ return NULL;
+ }
+ ast_log(LOG_DEBUG, "--- Operation %s requested line %d\n", insert?"insert":"delete", line);
+
+ /* Insert or delete at top */
+ if (line <= 1) {
+ if (insert) {
+ if (next == NULL) {
+ return new;
+ }
+ ast_log(LOG_DEBUG, "--- inserting at start\n");
+ new->next = next;
+ return new;
+ } else { /* Delete first rule */
+ temp = next->next;
+ ast_log(LOG_DEBUG, "--- deleting first line\n");
+ free(next);
+ return temp;
+ }
+ }
+
+ for (rule=1; (rule <= line && next != NULL); rule++) {
+ ast_log(LOG_DEBUG, "\n--- Rule %d ", rule);
+ if (rule == line) {
+ /* Ok, we are here */
+ if (insert) {
+ ast_log(LOG_DEBUG, "--- inserting\n");
+ /* Insert */
+ new->next = temp->next;
+ temp->next = new;
+ } else {
+ ast_log(LOG_DEBUG, "--- deleting\n");
+ /* Delete */
+ temp->next = next->next; /* The one to delete */
+ free(next);
+ }
+ return ha;
+ }
+ temp = next; /* The previous NACL */
+ next = next->next;
+ }
+ /* If we are here, the line number was greater than the number of lines available */
+ if (insert) {
+ ast_log(LOG_DEBUG, "--- inserting\n");
+ temp->next = new;
+ }
+ return ha;
+
+}
+
+/*! \brief Print ha list to CLI */
+static void ha_list(int fd, struct ast_ha *ha, const int rules)
+{
+ char iabuf[INET_ADDRSTRLEN];
+ char iabuf2[INET_ADDRSTRLEN];
+ int rulesfound = 0;
+
+ while (ha) {
+ rulesfound++;
+ ast_copy_string(iabuf2, ast_inet_ntoa(ha->netaddr), sizeof(iabuf2));
+ ast_copy_string(iabuf, ast_inet_ntoa(ha->netmask), sizeof(iabuf));
+ ast_cli(fd," %-3.3d: %s: %s mask %s\n", rulesfound, (ha->sense == AST_SENSE_ALLOW) ? "permit" : "deny ", iabuf2, iabuf);
+ ha = ha->next;
+ }
+ /* Rules is only used for configuration based nacls */
+ if (rules != 0 && rulesfound != rules) {
+ ast_cli(fd, " NOTE: Number of rules doesn't match configuration. Please check.\n");
+ }
+}
+
+/*! \brief CLI command to list named ACLs */
+static int cli_show_nacls(int fd, int argc, char *argv[])
+{
+#define FORMAT "%-40.40s %-20.20s %5d %5d %7s\n"
+#define FORMAT2 "%-40.40s %-20.20s %-5.5s %-5.5s %7s\n"
+
+ ast_cli(fd, FORMAT2, "ACL name:", "Set by", "#rules", "Usage", "Flags");
+ ASTOBJ_CONTAINER_TRAVERSE(&nacl_list, 1, {
+ ASTOBJ_RDLOCK(iterator);
+ ast_cli(fd, FORMAT, iterator->name,
+ S_OR(iterator->owner, "-"),
+ iterator->rules,
+ iterator->refcount,
+ iterator->manipulated ? "M" : "");
+ ha_list(fd, iterator->acl, iterator->rules);
+ ASTOBJ_UNLOCK(iterator);
+ } );
+ ast_cli(fd, "\nFlag M = Modified by AMI or CLI\n");
+ return RESULT_SUCCESS;
+}
+#undef FORMAT
+#undef FORMAT2
+
+/*! \brief Update NACL (or create it if it doesn't exist) */
+static int nacl_update(int fd, const char *command, const char *name, int rule, char *operation, const char *target, const char *owner)
+{
+ struct named_acl *nacl;
+ struct ast_ha *newha = NULL;
+ int insert = !strcasecmp(command, "add");
+
+ nacl = ast_nacl_find(name);
+ if (!nacl) {
+ if (insert) {
+ nacl = ast_nacl_add(name, owner);
+ /* Add a ref so that both existing and new NACLs has an extra ref after nacl_find or nacl_add */
+ ast_cli(fd, "Successfully added new NACL %s\n", name);
+ ASTOBJ_REF(nacl);
+ } else {
+ ast_cli(fd, "No such NACL: %s\n", name);
+ return RESULT_SUCCESS;
+ }
+ }
+ ASTOBJ_WRLOCK(nacl);
+ if (insert) {
+ newha = ast_append_ha(operation, target, NULL);
+ }
+ nacl->acl = ha_update(nacl->acl, rule, insert, newha);
+ if (insert) {
+ nacl->rules++;
+ } else {
+ nacl->rules--;
+ }
+ nacl->manipulated = TRUE;
+ ASTOBJ_UNLOCK(nacl);
+ ASTOBJ_UNREF(nacl, nacl_destroy);
+ return RESULT_SUCCESS;
+}
+
static char show_nacls_usage[] =
"Usage: nacl show\n"
" Lists all configured named ACLs.\n"
" Named ACLs can be used in many configuration files as well as internally\n"
" by Asterisk.\n";
-/*! \brief Print ha list to CLI */
-static void ha_list(int fd, struct ast_ha *ha, const int rules)
-{
- char iabuf[INET_ADDRSTRLEN];
- char iabuf2[INET_ADDRSTRLEN];
- int rulesfound = 0;
-
- while (ha) {
- rulesfound++;
- ast_copy_string(iabuf2, ast_inet_ntoa(ha->netaddr), sizeof(iabuf2));
- ast_copy_string(iabuf, ast_inet_ntoa(ha->netmask), sizeof(iabuf));
- ast_cli(fd," %s: %s mask %s\n", (ha->sense == AST_SENSE_ALLOW) ? "permit" : "deny ", iabuf2, iabuf);
- ha = ha->next;
- }
- /* Rules is only used for configuration based nacls */
- if (rules != 0 && rulesfound != rules) {
- ast_cli(fd, " NOTE: Number of rules doesn't match configuration. Please check.\n");
- }
-}
-
-/*! \brief CLI command to list named ACLs */
-static int cli_show_nacls(int fd, int argc, char *argv[])
-{
-#define FORMAT "%-40.40s %-20.20s %5d %5d \n"
-#define FORMAT2 "%-40.40s %-20.20s %-5.5s %-5.5s\n"
-
- ast_cli(fd, FORMAT2, "ACL name:", "Set by", "#rules", "Usage");
- ASTOBJ_CONTAINER_TRAVERSE(&nacl_list, 1, {
- ASTOBJ_RDLOCK(iterator);
- ast_cli(fd, FORMAT, iterator->name,
- S_OR(iterator->owner, "-"),
- iterator->rules,
- iterator->refcount);
- ha_list(fd, iterator->acl, iterator->rules);
- ASTOBJ_UNLOCK(iterator);
- } );
- ast_cli(fd, "\n");
- return RESULT_SUCCESS;
-}
-#undef FORMAT
-#undef FORMAT2
-
static struct ast_cli_entry cli_nacl = {
{ "nacl", "show", NULL },
cli_show_nacls, "List configured named ACLs.",
show_nacls_usage };
+
+/*! \brief CLI command to add named ACLs */
+static int cli_nacl_add(int fd, int argc, char *argv[])
+{
+
+ if (argc != 6) {
+ return RESULT_SHOWUSAGE;
+ }
+ if (option_debug >= 2) {
+ ast_cli(fd, "--- Command: %s %s\n", argv[0], argv[1]);
+ ast_cli(fd, "--- NACL Name: %s Operation %s\n", argv[2], argv[4]);
+ ast_cli(fd, "--- NACL line: %s Address %s\n", argv[3], argv[5]);
+ }
+ if (strcasecmp(argv[4], "permit") && strcasecmp(argv[4], "deny")) {
+ ast_cli(fd, "Error: Illegal operand %s\n", argv[4]);
+ return RESULT_SHOWUSAGE;
+ }
+ return nacl_update(fd, argv[1], argv[2], atoi(argv[3]), argv[4], argv[5], "cli");
+}
+
+/*! \brief CLI command to delete rules in named ACLs */
+static int cli_nacl_delete(int fd, int argc, char *argv[])
+{
+ if (argc != 4) {
+ return RESULT_SHOWUSAGE;
+ }
+ ast_cli(fd, "--- Command: %s %s\n", argv[0], argv[1]);
+ ast_cli(fd, "--- NACL Name: %s Line %s\n", argv[2], argv[3]);
+ return nacl_update(fd, argv[1], argv[2], atoi(argv[3]), NULL, NULL, "cli");
+}
+
+static char nacl_delete_usage[] =
+"Usage: nacl delete <name> <number>\n"
+" Delete a rule from a NACL.\n"
+" The NACL will still remain in memory, even if there are no active rules\n"
+" Please note that changes to ACLs are not stored in configuration, thuse are not\n"
+" persistant between Asterisk restarts.\n"
+"\n";
+
+static char nacl_add_usage[] =
+"Usage: nacl add <name> <number> [permit|deny] <address>\n"
+" Add a rule to a specific NACL.\n"
+" If the NACL doesn't exist, it's created. If there is an existing rule with the given\n"
+" number, the new rule is inserted before.\n"
+" Address is given as <ipaddress>/<netmask> or <ipaddress>/<maskbytes> (CIDR notation)\n"
+" Please note that changes to ACLs are not stored in configuration, thuse are not\n"
+" persistant between Asterisk restarts.\n"
+"\n";
+
+static struct ast_cli_entry clidef_nacl_add = {
+ { "nacl", "add", NULL },
+ cli_nacl_add, "Add a new rule to a NACL.",
+ nacl_add_usage };
+
+static struct ast_cli_entry clidef_nacl_delete = {
+ { "nacl", "delete", NULL },
+ cli_nacl_delete, "Delete a rule from an NACL.",
+ nacl_delete_usage };
+
/* Initialize named ACLs
This function is used both at load and reload time.
@@ -301,6 +463,8 @@
if (reload_reason == NACL_LOAD) {
ast_cli_register(&cli_nacl);
+ ast_cli_register(&clidef_nacl_add);
+ ast_cli_register(&clidef_nacl_delete);
}
return 0;
}
@@ -316,26 +480,3 @@
{
return nacl_init(NACL_RELOAD);
}
-
-#ifdef ERROR
-nacl.c: In function 'ast_nacl_add':
-nacl.c:95: warning: assignment from incompatible pointer type
-nacl.c: In function 'ast_nacl_find_all':
-nacl.c:114: warning: assignment from incompatible pointer type
-nacl.c:114: warning: implicit declaration of function 'ASTOBJ_RDUNLOCK'
-nacl.c: At top level:
-nacl.c:156: warning: no previous prototype for 'ast_nacl_mark_all_owned'
-nacl.c: In function 'ast_nacl_mark_all_owned':
-nacl.c:161: warning: assignment from incompatible pointer type
-nacl.c:157: warning: unused variable 'nacl'
-nacl.c:326:1: error: unterminated argument list invoking macro "ASTOBJ_CONTAINER_TRAVERSE"
-nacl.c: In function 'cli_show_nacls':
-nacl.c:239: error: 'ASTOBJ_CONTAINER_TRAVERSE' undeclared (first use in this function)
-nacl.c:239: error: (Each undeclared identifier is reported only once
-nacl.c:239: error: for each function it appears in.)
-nacl.c:239: error: expected ';' at end of input
-nacl.c:239: error: expected declaration or statement at end of input
-nacl.c:229: warning: unused variable 'nacl'
-nacl.c:239: warning: no return statement in function returning non-void
-#endif
-
More information about the asterisk-commits
mailing list