[svn-commits] trunk - r7822 /trunk/apps/app_authenticate.c

svn-commits at lists.digium.com svn-commits at lists.digium.com
Thu Jan 5 15:47:44 CST 2006


Author: mogorman
Date: Thu Jan  5 15:47:44 2006
New Revision: 7822

URL: http://svn.digium.com/view/asterisk?rev=7822&view=rev
Log:
Added feature from bug #5053, allowing for 
app_authenticate to set a max number of digits
also implemented the new argument and option
parsing code.

Modified:
    trunk/apps/app_authenticate.c

Modified: trunk/apps/app_authenticate.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_authenticate.c?rev=7822&r1=7821&r2=7822&view=diff
==============================================================================
--- trunk/apps/app_authenticate.c (original)
+++ trunk/apps/app_authenticate.c Thu Jan  5 15:47:44 2006
@@ -44,6 +44,23 @@
 #include "asterisk/app.h"
 #include "asterisk/astdb.h"
 #include "asterisk/utils.h"
+#include "asterisk/options.h"
+
+enum {
+	OPT_ACCOUNT = (1 << 0),
+	OPT_DATABASE = (1 << 1),
+	OPT_JUMP = (1 << 2),
+	OPT_MULTIPLE = (1 << 3),
+	OPT_REMOVE = (1 << 4),
+} auth_option_flags;
+
+AST_APP_OPTIONS(auth_app_options, {
+	AST_APP_OPTION('a', OPT_ACCOUNT),
+	AST_APP_OPTION('d', OPT_DATABASE),
+	AST_APP_OPTION('j', OPT_JUMP),
+	AST_APP_OPTION('m', OPT_MULTIPLE),
+	AST_APP_OPTION('r', OPT_REMOVE),
+});
 
 static char *tdesc = "Authentication Application";
 
@@ -52,9 +69,9 @@
 static char *synopsis = "Authenticate a user";
 
 static char *descrip =
-"  Authenticate(password[|options]): This application asks the caller to enter a\n"
-"given password in order to continue dialplan execution. If the password begins\n"
-"with the '/' character, it is interpreted as a file which contains a list of\n"
+"  Authenticate(password[|options[|maxdigits]]): This application asks the caller\n"
+"to enter a given password in order to continue dialplan execution. If the password\n"
+"begins with the '/' character, it is interpreted as a file which contains a list of\n"
 "valid passwords, listed 1 password per line in the file.\n"
 "  When using a database key, the value associated with the key can be anything.\n"
 "Users have three attempts to authenticate before the channel is hung up. If the\n"
@@ -69,6 +86,10 @@
 "         the file. When one of the passwords is matched, the channel will have\n"
 "         its account code set to the corresponding account code in the file.\n"
 "     r - Remove the database key upon successful entry (valid with 'd' only)\n"
+"     maxdigits  - maximum acceptable number of digits. Stops reading after\n"
+"         maxdigits have been entered (without requiring the user to\n"
+"         press the '#' key).\n"
+"         Defaults to 0 - no limit - wait for the user press the '#' key.\n"
 ;
 
 STANDARD_LOCAL_USER;
@@ -78,13 +99,19 @@
 static int auth_exec(struct ast_channel *chan, void *data)
 {
 	int res=0;
-	int jump = 0;
 	int retries;
 	struct localuser *u;
-	char password[256]="";
 	char passwd[256];
-	char *opts;
 	char *prompt;
+	int maxdigits;
+	char *argcopy =NULL;
+	struct ast_flags flags = {0};
+
+	AST_DECLARE_APP_ARGS(arglist,
+		AST_APP_ARG(password);
+		AST_APP_ARG(options);
+		AST_APP_ARG(maxdigits);
+	);
 	
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "Authenticate requires an argument(password)\n");
@@ -101,37 +128,49 @@
 		}
 	}
 	
-	strncpy(password, data, sizeof(password) - 1);
-	opts=strchr(password, '|');
-	if (opts) {
-		*opts = 0;
-		opts++;
-	} else
-		opts = "";
-	if (strchr(opts, 'j'))
-		jump = 1;
+	argcopy = ast_strdupa(data);
+	if (!argcopy) {
+		ast_log(LOG_ERROR, "Out of memory!\n");
+		LOCAL_USER_REMOVE(u);
+		return -1;
+	}
+
+	AST_STANDARD_APP_ARGS(arglist,argcopy);
+	
+	if (!ast_strlen_zero(arglist.options)) {
+		ast_app_parse_options(auth_app_options, &flags, NULL, arglist.options);
+	}
+
+	if (!ast_strlen_zero(arglist.maxdigits)) {
+		maxdigits = atoi(arglist.maxdigits);
+		if ((maxdigits<1) || (maxdigits>sizeof(passwd)-2))
+			maxdigits = sizeof(passwd) - 2;
+	} else {
+		maxdigits = sizeof(passwd) - 2;
+	}
+
 	/* Start asking for password */
 	prompt = "agent-pass";
 	for (retries = 0; retries < 3; retries++) {
-		res = ast_app_getdata(chan, prompt, passwd, sizeof(passwd) - 2, 0);
+		res = ast_app_getdata(chan, prompt, passwd, maxdigits, 0);
 		if (res < 0)
 			break;
 		res = 0;
-		if (password[0] == '/') {
-			if (strchr(opts, 'd')) {
+		if (arglist.password[0] == '/') {
+			if (ast_test_flag(&flags,OPT_DATABASE)) {
 				char tmp[256];
 				/* Compare against a database key */
-				if (!ast_db_get(password + 1, passwd, tmp, sizeof(tmp))) {
+				if (!ast_db_get(arglist.password + 1, passwd, tmp, sizeof(tmp))) {
 					/* It's a good password */
-					if (strchr(opts, 'r')) {
-						ast_db_del(password + 1, passwd);
+					if (ast_test_flag(&flags,OPT_REMOVE)) {
+						ast_db_del(arglist.password + 1, passwd);
 					}
 					break;
 				}
 			} else {
 				/* Compare against a file */
 				FILE *f;
-				f = fopen(password, "r");
+				f = fopen(arglist.password, "r");
 				if (f) {
 					char buf[256] = "";
 					char md5passwd[33] = "";
@@ -141,7 +180,7 @@
 						fgets(buf, sizeof(buf), f);
 						if (!feof(f) && !ast_strlen_zero(buf)) {
 							buf[strlen(buf) - 1] = '\0';
-							if (strchr(opts, 'm')) {
+							if (ast_test_flag(&flags,OPT_MULTIPLE)) {
 								md5secret = strchr(buf, ':');
 								if (md5secret == NULL)
 									continue;
@@ -149,13 +188,13 @@
 								md5secret++;
 								ast_md5_hash(md5passwd, passwd);
 								if (!strcmp(md5passwd, md5secret)) {
-									if (strchr(opts, 'a'))
+									if (ast_test_flag(&flags,OPT_ACCOUNT))
 										ast_cdr_setaccount(chan, buf);
 									break;
 								}
 							} else {
 								if (!strcmp(passwd, buf)) {
-									if (strchr(opts, 'a'))
+									if (ast_test_flag(&flags,OPT_ACCOUNT))
 										ast_cdr_setaccount(chan, buf);
 									break;
 								}
@@ -164,7 +203,7 @@
 					}
 					fclose(f);
 					if (!ast_strlen_zero(buf)) {
-						if (strchr(opts, 'm')) {
+						if (ast_test_flag(&flags,OPT_MULTIPLE)) {
 							if (md5secret && !strcmp(md5passwd, md5secret))
 								break;
 						} else {
@@ -173,23 +212,23 @@
 						}
 					}
 				} else 
-					ast_log(LOG_WARNING, "Unable to open file '%s' for authentication: %s\n", password, strerror(errno));
+					ast_log(LOG_WARNING, "Unable to open file '%s' for authentication: %s\n", arglist.password, strerror(errno));
 			}
 		} else {
 			/* Compare against a fixed password */
-			if (!strcmp(passwd, password)) 
+			if (!strcmp(passwd, arglist.password)) 
 				break;
 		}
 		prompt="auth-incorrect";
 	}
 	if ((retries < 3) && !res) {
-		if (strchr(opts, 'a') && !strchr(opts, 'm')) 
+		if (ast_test_flag(&flags,OPT_ACCOUNT) && !ast_test_flag(&flags,OPT_MULTIPLE)) 
 			ast_cdr_setaccount(chan, passwd);
 		res = ast_streamfile(chan, "auth-thankyou", chan->language);
 		if (!res)
 			res = ast_waitstream(chan, "");
 	} else {
-		if (jump && ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
+		if (ast_test_flag(&flags,OPT_JUMP) && ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
 			res = 0;
 		} else {
 			if (!ast_streamfile(chan, "vm-goodbye", chan->language))



More information about the svn-commits mailing list