app_authenticate.c 4.0 KB

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