Sun Jun 12 16:37:48 2011

Asterisk developer's documentation


app_authenticate.c File Reference

Execute arbitrary authenticate commands. More...

#include "asterisk.h"
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/app.h"
#include "asterisk/astdb.h"
#include "asterisk/utils.h"
#include "asterisk/options.h"

Include dependency graph for app_authenticate.c:

Go to the source code of this file.

Enumerations

enum  {
  OPT_ACCOUNT = (1 << 0), OPT_DATABASE = (1 << 1), OPT_JUMP = (1 << 2), OPT_MULTIPLE = (1 << 3),
  OPT_REMOVE = (1 << 4)
}

Functions

 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),})
 AST_MODULE_INFO_STANDARD (ASTERISK_GPL_KEY,"Authentication Application")
static int auth_exec (struct ast_channel *chan, void *data)
static int load_module (void)
static int unload_module (void)

Variables

static char * app = "Authenticate"
enum { ... }  auth_option_flags
static char * descrip
static char * synopsis = "Authenticate a user"


Detailed Description

Execute arbitrary authenticate commands.

Author:
Mark Spencer <markster@digium.com>

Definition in file app_authenticate.c.


Enumeration Type Documentation

anonymous enum

Enumerator:
OPT_ACCOUNT 
OPT_DATABASE 
OPT_JUMP 
OPT_MULTIPLE 
OPT_REMOVE 

Definition at line 49 of file app_authenticate.c.

00049      {
00050    OPT_ACCOUNT = (1 << 0),
00051    OPT_DATABASE = (1 << 1),
00052    OPT_JUMP = (1 << 2),
00053    OPT_MULTIPLE = (1 << 3),
00054    OPT_REMOVE = (1 << 4),
00055 } auth_option_flags;


Function Documentation

AST_APP_OPTIONS ( auth_app_options   ) 

AST_MODULE_INFO_STANDARD ( ASTERISK_GPL_KEY  ,
"Authentication Application"   
)

static int auth_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 94 of file app_authenticate.c.

References ast_channel::_state, ast_answer(), AST_APP_ARG, ast_app_getdata(), ast_app_parse_options(), ast_cdr_setaccount(), ast_db_del(), ast_db_get(), AST_DECLARE_APP_ARGS, ast_goto_if_exists(), ast_log(), ast_md5_hash(), ast_module_user_add, ast_module_user_remove, AST_STANDARD_APP_ARGS, AST_STATE_UP, ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitstream(), ast_channel::context, errno, ast_channel::exten, f, len, LOG_WARNING, OPT_ACCOUNT, OPT_DATABASE, OPT_JUMP, OPT_MULTIPLE, OPT_REMOVE, password, and ast_channel::priority.

Referenced by load_module().

00095 {
00096    int res=0;
00097    int retries;
00098    struct ast_module_user *u;
00099    char passwd[256];
00100    char *prompt;
00101    int maxdigits;
00102    char *argcopy =NULL;
00103    struct ast_flags flags = {0};
00104 
00105    AST_DECLARE_APP_ARGS(arglist,
00106       AST_APP_ARG(password);
00107       AST_APP_ARG(options);
00108       AST_APP_ARG(maxdigits);
00109    );
00110    
00111    if (ast_strlen_zero(data)) {
00112       ast_log(LOG_WARNING, "Authenticate requires an argument(password)\n");
00113       return -1;
00114    }
00115    
00116    u = ast_module_user_add(chan);
00117 
00118    if (chan->_state != AST_STATE_UP) {
00119       res = ast_answer(chan);
00120       if (res) {
00121          ast_module_user_remove(u);
00122          return -1;
00123       }
00124    }
00125    
00126    argcopy = ast_strdupa(data);
00127 
00128    AST_STANDARD_APP_ARGS(arglist,argcopy);
00129    
00130    if (!ast_strlen_zero(arglist.options)) {
00131       ast_app_parse_options(auth_app_options, &flags, NULL, arglist.options);
00132    }
00133 
00134    if (!ast_strlen_zero(arglist.maxdigits)) {
00135       maxdigits = atoi(arglist.maxdigits);
00136       if ((maxdigits<1) || (maxdigits>sizeof(passwd)-2))
00137          maxdigits = sizeof(passwd) - 2;
00138    } else {
00139       maxdigits = sizeof(passwd) - 2;
00140    }
00141 
00142    /* Start asking for password */
00143    prompt = "agent-pass";
00144    for (retries = 0; retries < 3; retries++) {
00145       res = ast_app_getdata(chan, prompt, passwd, maxdigits, 0);
00146       if (res < 0)
00147          break;
00148       res = 0;
00149       if (arglist.password[0] == '/') {
00150          if (ast_test_flag(&flags,OPT_DATABASE)) {
00151             char tmp[256];
00152             /* Compare against a database key */
00153             if (!ast_db_get(arglist.password + 1, passwd, tmp, sizeof(tmp))) {
00154                /* It's a good password */
00155                if (ast_test_flag(&flags,OPT_REMOVE)) {
00156                   ast_db_del(arglist.password + 1, passwd);
00157                }
00158                break;
00159             }
00160          } else {
00161             /* Compare against a file */
00162             FILE *f;
00163             f = fopen(arglist.password, "r");
00164             if (f) {
00165                char buf[256] = "";
00166                char md5passwd[33] = "";
00167                char *md5secret = NULL;
00168 
00169                while (!feof(f)) {
00170                   fgets(buf, sizeof(buf), f);
00171                   if (!ast_strlen_zero(buf)) {
00172                      size_t len = strlen(buf);
00173                      if (buf[len - 1] == '\n')
00174                         buf[len - 1] = '\0';
00175                      if (ast_test_flag(&flags,OPT_MULTIPLE)) {
00176                         md5secret = strchr(buf, ':');
00177                         if (md5secret == NULL)
00178                            continue;
00179                         *md5secret = '\0';
00180                         md5secret++;
00181                         ast_md5_hash(md5passwd, passwd);
00182                         if (!strcmp(md5passwd, md5secret)) {
00183                            if (ast_test_flag(&flags,OPT_ACCOUNT))
00184                               ast_cdr_setaccount(chan, buf);
00185                            break;
00186                         }
00187                      } else {
00188                         if (!strcmp(passwd, buf)) {
00189                            if (ast_test_flag(&flags,OPT_ACCOUNT))
00190                               ast_cdr_setaccount(chan, buf);
00191                            break;
00192                         }
00193                      }
00194                   }
00195                }
00196                fclose(f);
00197                if (!ast_strlen_zero(buf)) {
00198                   if (ast_test_flag(&flags,OPT_MULTIPLE)) {
00199                      if (md5secret && !strcmp(md5passwd, md5secret))
00200                         break;
00201                   } else {
00202                      if (!strcmp(passwd, buf))
00203                         break;
00204                   }
00205                }
00206             } else 
00207                ast_log(LOG_WARNING, "Unable to open file '%s' for authentication: %s\n", arglist.password, strerror(errno));
00208          }
00209       } else {
00210          /* Compare against a fixed password */
00211          if (!strcmp(passwd, arglist.password)) 
00212             break;
00213       }
00214       prompt="auth-incorrect";
00215    }
00216    if ((retries < 3) && !res) {
00217       if (ast_test_flag(&flags,OPT_ACCOUNT) && !ast_test_flag(&flags,OPT_MULTIPLE)) 
00218          ast_cdr_setaccount(chan, passwd);
00219       res = ast_streamfile(chan, "auth-thankyou", chan->language);
00220       if (!res)
00221          res = ast_waitstream(chan, "");
00222    } else {
00223       if (ast_test_flag(&flags,OPT_JUMP) && ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101) == 0) {
00224          res = 0;
00225       } else {
00226          if (!ast_streamfile(chan, "vm-goodbye", chan->language))
00227             res = ast_waitstream(chan, "");
00228          res = -1;
00229       }
00230    }
00231    ast_module_user_remove(u);
00232    return res;
00233 }

static int load_module ( void   )  [static]

Definition at line 247 of file app_authenticate.c.

References ast_register_application(), and auth_exec().

00248 {
00249    return ast_register_application(app, auth_exec, synopsis, descrip);
00250 }

static int unload_module ( void   )  [static]

Definition at line 235 of file app_authenticate.c.

References ast_module_user_hangup_all, and ast_unregister_application().

00236 {
00237    int res;
00238 
00239    ast_module_user_hangup_all();
00240 
00241    res = ast_unregister_application(app);
00242 
00243    
00244    return res;
00245 }


Variable Documentation

char* app = "Authenticate" [static]

Definition at line 66 of file app_authenticate.c.

enum { ... } auth_option_flags

char* descrip [static]

Definition at line 70 of file app_authenticate.c.

char* synopsis = "Authenticate a user" [static]

Definition at line 68 of file app_authenticate.c.


Generated on Sun Jun 12 16:37:48 2011 for Asterisk - the Open Source PBX by  doxygen 1.5.6