Use find_user for existsmailbox
[asterisk/asterisk.git] / apps / app_authenticate.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Execute arbitrary authenticate commands
5  * 
6  * Copyright (C) 1999, Mark Spencer
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
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>
22 #include <asterisk/utils.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <pthread.h>
30
31
32 static char *tdesc = "Authentication Application";
33
34 static char *app = "Authenticate";
35
36 static char *synopsis = "Authenticate a user";
37
38 static char *descrip =
39 "  Authenticate(password[|options]): Requires a user to enter a"
40 "given password in order to continue execution.  If the\n"
41 "password begins with the '/' character, it is interpreted as\n"
42 "a file which contains a list of valid passwords (1 per line).\n"
43 "an optional set of opions may be provided by concatenating any\n"
44 "of the following letters:\n"
45 "     a - Set account code to the password that is entered\n"
46 "     d - Interpret path as database key, not literal file\n"
47 "     r - Remove database key upon successful entry (valid with 'd' only)\n"
48 "\n"
49 "When using a database key, the value associated with the key can be\n"
50 "anything.\n"
51 "Returns 0 if the user enters a valid password within three\n"
52 "tries, or -1 otherwise (or on hangup).\n";
53
54 STANDARD_LOCAL_USER;
55
56 LOCAL_USER_DECL;
57
58 static int auth_exec(struct ast_channel *chan, void *data)
59 {
60         int res=0;
61         int retries;
62         struct localuser *u;
63         char password[256]="";
64         char passwd[256];
65         char *opts;
66         char *prompt;
67         if (!data || ast_strlen_zero(data)) {
68                 ast_log(LOG_WARNING, "Authenticate requires an argument(password)\n");
69                 return -1;
70         }
71         LOCAL_USER_ADD(u);
72         if (chan->_state != AST_STATE_UP) {
73                 res = ast_answer(chan);
74                 if (res) {
75                         LOCAL_USER_REMOVE(u);
76                         return -1;
77                 }
78         }
79         strncpy(password, data, sizeof(password) - 1);
80         opts=strchr(password, '|');
81         if (opts) {
82                 *opts = 0;
83                 opts++;
84         } else
85                 opts = "";
86         /* Start asking for password */
87         prompt = "agent-pass";
88         for (retries = 0; retries < 3; retries++) {
89                 res = ast_app_getdata(chan, prompt, passwd, sizeof(passwd) - 2, 0);
90                 if (res < 0)
91                         break;
92                 res = 0;
93                 if (password[0] == '/') {
94                         if (strchr(opts, 'd')) {
95                                 char tmp[256];
96                                 /* Compare against a database key */
97                                 if (!ast_db_get(password + 1, passwd, tmp, sizeof(tmp))) {
98                                         /* It's a good password */
99                                         if (strchr(opts, 'r')) {
100                                                 ast_db_del(password + 1, passwd);
101                                         }
102                                         break;
103                                 }
104                         } else {
105                                 /* Compare against a file */
106                                 FILE *f;
107                                 f = fopen(password, "r");
108                                 if (f) {
109                                         char buf[256] = "";
110                                         while(!feof(f)) {
111                                                 fgets(buf, sizeof(buf), f);
112                                                 if (!feof(f) && !ast_strlen_zero(buf)) {
113                                                         buf[strlen(buf) - 1] = '\0';
114                                                         if (!ast_strlen_zero(buf) && !strcmp(passwd, buf))
115                                                                 break;
116                                                 }
117                                         }
118                                         fclose(f);
119                                         if (!ast_strlen_zero(buf) && !strcmp(passwd, buf))
120                                                 break;
121                                 } else 
122                                         ast_log(LOG_WARNING, "Unable to open file '%s' for authentication: %s\n", password, strerror(errno));
123                         }
124                 } else {
125                         /* Compare against a fixed password */
126                         if (!strcmp(passwd, password)) 
127                                 break;
128                 }
129                 prompt="auth-incorrect";
130         }
131         if ((retries < 3) && !res) {
132                 if (strchr(opts, 'a')) 
133                         ast_cdr_setaccount(chan, passwd);
134                 res = ast_streamfile(chan, "auth-thankyou", chan->language);
135                 if (!res)
136                         res = ast_waitstream(chan, "");
137         } else {
138                 if (!res)
139                         res = ast_streamfile(chan, "vm-goodbye", chan->language);
140                 if (!res)
141                         res = ast_waitstream(chan, "");
142                 res = -1;
143         }
144         LOCAL_USER_REMOVE(u);
145         return res;
146 }
147
148 int unload_module(void)
149 {
150         STANDARD_HANGUP_LOCALUSERS;
151         return ast_unregister_application(app);
152 }
153
154 int load_module(void)
155 {
156         return ast_register_application(app, auth_exec, synopsis, descrip);
157 }
158
159 char *description(void)
160 {
161         return tdesc;
162 }
163
164 int usecount(void)
165 {
166         int res;
167         STANDARD_USECOUNT(res);
168         return res;
169 }
170
171 char *key()
172 {
173         return ASTERISK_GPL_KEY;
174 }