2 * Asterisk -- A telephony toolkit for Linux.
4 * Execute arbitrary authenticate commands
6 * Copyright (C) 1999, Mark Spencer
8 * Mark Spencer <markster@linux-support.net>
10 * This program is free software, distributed under the terms of
11 * the GNU General Public License
14 #include <asterisk/lock.h>
15 #include <asterisk/file.h>
16 #include <asterisk/logger.h>
17 #include <asterisk/channel.h>
18 #include <asterisk/pbx.h>
19 #include <asterisk/module.h>
20 #include <asterisk/app.h>
21 #include <asterisk/astdb.h>
31 static char *tdesc = "Authentication Application";
33 static char *app = "Authenticate";
35 static char *synopsis = "Authenticate a user";
37 static char *descrip =
38 " Authenticate(password[|options]): Requires a user to enter a"
39 "given password in order to continue execution. If the\n"
40 "password begins with the '/' character, it is interpreted as\n"
41 "a file which contains a list of valid passwords (1 per line).\n"
42 "an optional set of opions may be provided by concatenating any\n"
43 "of the following letters:\n"
44 " a - Set account code to the password that is entered\n"
45 " d - Interpret path as database key, not literal file\n"
46 " r - Remove database key upon successful entry (valid with 'd' only)\n"
48 "When using a database key, the value associated with the key can be\n"
50 "Returns 0 if the user enters a valid password within three\n"
51 "tries, or -1 otherwise (or on hangup).\n";
57 static int auth_exec(struct ast_channel *chan, void *data)
62 char password[256]="";
66 if (!data || !strlen(data)) {
67 ast_log(LOG_WARNING, "Authenticate requires an argument(password)\n");
71 if (chan->_state != AST_STATE_UP) {
72 res = ast_answer(chan);
78 strncpy(password, data, sizeof(password) - 1);
79 opts=strchr(password, '|');
85 /* Start asking for password */
86 prompt = "agent-pass";
87 for (retries = 0; retries < 3; retries++) {
88 res = ast_app_getdata(chan, prompt, passwd, sizeof(passwd) - 2, 0);
92 if (password[0] == '/') {
93 if (strchr(opts, 'd')) {
95 /* Compare against a database key */
96 if (!ast_db_get(password + 1, passwd, tmp, sizeof(tmp))) {
97 /* It's a good password */
98 if (strchr(opts, 'r')) {
99 ast_db_del(password + 1, passwd);
104 /* Compare against a file */
106 f = fopen(password, "r");
110 fgets(buf, sizeof(buf), f);
111 if (!feof(f) && strlen(buf)) {
112 buf[strlen(buf) - 1] = '\0';
113 if (strlen(buf) && !strcmp(passwd, buf))
118 if (strlen(buf) && !strcmp(passwd, buf))
121 ast_log(LOG_WARNING, "Unable to open file '%s' for authentication: %s\n", password, strerror(errno));
124 /* Compare against a fixed password */
125 if (!strcmp(passwd, password))
128 prompt="auth-incorrect";
130 if ((retries < 3) && !res) {
131 if (strchr(opts, 'a'))
132 ast_cdr_setaccount(chan, passwd);
133 res = ast_streamfile(chan, "auth-thankyou", chan->language);
135 res = ast_waitstream(chan, "");
138 res = ast_streamfile(chan, "vm-goodbye", chan->language);
140 res = ast_waitstream(chan, "");
143 LOCAL_USER_REMOVE(u);
147 int unload_module(void)
149 STANDARD_HANGUP_LOCALUSERS;
150 return ast_unregister_application(app);
153 int load_module(void)
155 return ast_register_application(app, auth_exec, synopsis, descrip);
158 char *description(void)
166 STANDARD_USECOUNT(res);
172 return ASTERISK_GPL_KEY;