| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Asterisk -- An open source telephony toolkit. | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * Copyright (C) 1999 - 2005, Digium, Inc. | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  |  * Made only slightly more sane by Mark Spencer <markster@digium.com> | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * See http://www.asterisk.org for more information about
 | 
					
						
							|  |  |  |  * the Asterisk project. Please do not directly contact | 
					
						
							|  |  |  |  * any of the maintainers of this project for assistance; | 
					
						
							|  |  |  |  * the project provides a web site, mailing lists and IRC | 
					
						
							|  |  |  |  * channels for your use. | 
					
						
							|  |  |  |  * | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  |  * This program is free software, distributed under the terms of | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * the GNU General Public License Version 2. See the LICENSE file | 
					
						
							|  |  |  |  * at the top of the source tree. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  | /*! \file
 | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2005-10-24 20:12:06 +00:00
										 |  |  |  * \brief DISA -- Direct Inward System Access Application | 
					
						
							| 
									
										
										
										
											2005-11-06 15:09:47 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * \author Jim Dixon <jim@lambdatel.com> | 
					
						
							| 
									
										
										
										
											2005-09-14 20:46:50 +00:00
										 |  |  |  *  | 
					
						
							| 
									
										
										
										
											2005-11-06 15:09:47 +00:00
										 |  |  |  * \ingroup applications | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  |  */ | 
					
						
							|  |  |  |   | 
					
						
							| 
									
										
										
										
											2006-06-07 18:54:56 +00:00
										 |  |  | #include "asterisk.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-06-06 22:39:32 +00:00
										 |  |  | #include <string.h>
 | 
					
						
							|  |  |  | #include <stdlib.h>
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | #include <math.h>
 | 
					
						
							|  |  |  | #include <sys/time.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-04-21 06:02:45 +00:00
										 |  |  | #include "asterisk/lock.h"
 | 
					
						
							|  |  |  | #include "asterisk/file.h"
 | 
					
						
							|  |  |  | #include "asterisk/logger.h"
 | 
					
						
							|  |  |  | #include "asterisk/channel.h"
 | 
					
						
							|  |  |  | #include "asterisk/app.h"
 | 
					
						
							|  |  |  | #include "asterisk/indications.h"
 | 
					
						
							|  |  |  | #include "asterisk/pbx.h"
 | 
					
						
							|  |  |  | #include "asterisk/module.h"
 | 
					
						
							|  |  |  | #include "asterisk/translate.h"
 | 
					
						
							|  |  |  | #include "asterisk/ulaw.h"
 | 
					
						
							|  |  |  | #include "asterisk/callerid.h"
 | 
					
						
							| 
									
										
										
										
											2006-02-01 23:05:28 +00:00
										 |  |  | #include "asterisk/stringfields.h"
 | 
					
						
							| 
									
										
										
										
											2006-10-03 15:53:07 +00:00
										 |  |  | #include "asterisk/options.h"
 | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | static char *app = "DISA"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *synopsis = "DISA (Direct Inward System Access)"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static char *descrip =  | 
					
						
							| 
									
										
										
										
											2006-07-15 21:56:58 +00:00
										 |  |  | 	"DISA(<numeric passcode>[|<context>]) or DISA(<filename>)\n" | 
					
						
							| 
									
										
										
										
											2005-10-21 04:00:13 +00:00
										 |  |  | 	"The DISA, Direct Inward System Access, application allows someone from \n" | 
					
						
							|  |  |  | 	"outside the telephone switch (PBX) to obtain an \"internal\" system \n" | 
					
						
							|  |  |  | 	"dialtone and to place calls from it as if they were placing a call from \n" | 
					
						
							|  |  |  | 	"within the switch.\n" | 
					
						
							|  |  |  | 	"DISA plays a dialtone. The user enters their numeric passcode, followed by\n" | 
					
						
							|  |  |  | 	"the pound sign (#). If the passcode is correct, the user is then given\n" | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	"system dialtone on which a call may be placed. Obviously, this type\n" | 
					
						
							|  |  |  | 	"of access has SERIOUS security implications, and GREAT care must be\n" | 
					
						
							|  |  |  | 	"taken NOT to compromise your security.\n\n" | 
					
						
							|  |  |  | 	"There is a possibility of accessing DISA without password. Simply\n" | 
					
						
							| 
									
										
										
										
											2005-10-21 04:00:13 +00:00
										 |  |  | 	"exchange your password with \"no-password\".\n\n" | 
					
						
							|  |  |  | 	"    Example: exten => s,1,DISA(no-password|local)\n\n" | 
					
						
							|  |  |  | 	"Be aware that using this compromises the security of your PBX.\n\n" | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	"The arguments to this application (in extensions.conf) allow either\n" | 
					
						
							| 
									
										
										
										
											2005-10-21 04:00:13 +00:00
										 |  |  | 	"specification of a single global passcode (that everyone uses), or\n" | 
					
						
							| 
									
										
										
										
											2006-05-30 16:01:50 +00:00
										 |  |  | 	"individual passcodes contained in a file. It also allows specification\n" | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	"of the context on which the user will be dialing. If no context is\n" | 
					
						
							| 
									
										
										
										
											2005-10-21 04:00:13 +00:00
										 |  |  | 	"specified, the DISA application defaults the context to \"disa\".\n" | 
					
						
							|  |  |  | 	"Presumably a normal system will have a special context set up\n" | 
					
						
							|  |  |  | 	"for DISA use with some or a lot of restrictions. \n\n" | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	"The file that contains the passcodes (if used) allows specification\n" | 
					
						
							|  |  |  | 	"of either just a passcode (defaulting to the \"disa\" context, or\n" | 
					
						
							|  |  |  | 	"passcode|context on each line of the file. The file may contain blank\n" | 
					
						
							| 
									
										
										
										
											2002-07-26 11:06:49 +00:00
										 |  |  | 	"lines, or comments starting with \"#\" or \";\". In addition, the\n" | 
					
						
							|  |  |  | 	"above arguments may have |new-callerid-string appended to them, to\n" | 
					
						
							|  |  |  | 	"specify a new (different) callerid to be used for this call, for\n" | 
					
						
							|  |  |  | 	"example: numeric-passcode|context|\"My Phone\" <(234) 123-4567> or \n" | 
					
						
							| 
									
										
										
										
											2004-10-31 23:28:42 +00:00
										 |  |  | 	"full-pathname-of-passcode-file|\"My Phone\" <(234) 123-4567>.  Last\n" | 
					
						
							|  |  |  | 	"but not least, |mailbox[@context] may be appended, which will cause\n" | 
					
						
							|  |  |  | 	"a stutter-dialtone (indication \"dialrecall\") to be used, if the\n" | 
					
						
							|  |  |  | 	"specified mailbox contains any new messages, for example:\n" | 
					
						
							|  |  |  | 	"numeric-passcode|context||1234 (w/a changing callerid).  Note that\n" | 
					
						
							| 
									
										
										
										
											2002-07-26 11:06:49 +00:00
										 |  |  | 	"in the case of specifying the numeric-passcode, the context must be\n" | 
					
						
							|  |  |  | 	"specified if the callerid is specified also.\n\n" | 
					
						
							| 
									
										
										
										
											2005-10-21 04:00:13 +00:00
										 |  |  | 	"If login is successful, the application looks up the dialed number in\n" | 
					
						
							|  |  |  | 	"the specified (or default) context, and executes it if found.\n" | 
					
						
							|  |  |  | 	"If the user enters an invalid extension and extension \"i\" (invalid) \n" | 
					
						
							| 
									
										
										
										
											2006-01-16 18:52:13 +00:00
										 |  |  | 	"exists in the context, it will be used. Also, if you set the 5th argument\n" | 
					
						
							|  |  |  | 	"to 'NOANSWER', the DISA application will not answer initially.\n"; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-10-31 23:28:42 +00:00
										 |  |  | static void play_dialtone(struct ast_channel *chan, char *mailbox) | 
					
						
							| 
									
										
										
										
											2004-08-28 19:41:18 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	const struct tone_zone_sound *ts = NULL; | 
					
						
							| 
									
										
										
										
											2004-10-31 23:28:42 +00:00
										 |  |  | 	if(ast_app_has_voicemail(mailbox, NULL)) | 
					
						
							|  |  |  | 		ts = ast_get_indication_tone(chan->zone, "dialrecall"); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		ts = ast_get_indication_tone(chan->zone, "dial"); | 
					
						
							| 
									
										
										
										
											2004-08-28 19:41:18 +00:00
										 |  |  | 	if (ts) | 
					
						
							|  |  |  | 		ast_playtones_start(chan, 0, ts->data, 0); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		ast_tonepair_start(chan, 350, 440, 0, 0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | static int disa_exec(struct ast_channel *chan, void *data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2006-01-16 18:52:13 +00:00
										 |  |  | 	int i,j,k,x,did_ignore,special_noanswer; | 
					
						
							| 
									
										
										
										
											2004-10-31 23:28:42 +00:00
										 |  |  | 	int firstdigittimeout = 20000; | 
					
						
							|  |  |  | 	int digittimeout = 10000; | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 	struct ast_module_user *u; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	char *tmp, exten[AST_MAX_EXTENSION],acctcode[20]=""; | 
					
						
							| 
									
										
										
										
											2005-11-11 00:53:19 +00:00
										 |  |  | 	char pwline[256]; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	char ourcidname[256],ourcidnum[256]; | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 	struct ast_frame *f; | 
					
						
							| 
									
										
										
										
											2005-07-15 23:00:47 +00:00
										 |  |  | 	struct timeval lastdigittime; | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 	int res; | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 	time_t rstart; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	FILE *fp; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	AST_DECLARE_APP_ARGS(args, | 
					
						
							|  |  |  | 		AST_APP_ARG(passcode); | 
					
						
							|  |  |  | 		AST_APP_ARG(context); | 
					
						
							|  |  |  | 		AST_APP_ARG(cid); | 
					
						
							|  |  |  | 		AST_APP_ARG(mailbox); | 
					
						
							| 
									
										
										
										
											2006-01-16 18:52:13 +00:00
										 |  |  | 		AST_APP_ARG(noanswer); | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-26 19:48:14 +00:00
										 |  |  | 	if (ast_strlen_zero(data)) { | 
					
						
							| 
									
										
										
										
											2006-07-15 21:56:58 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "DISA requires an argument (passcode/passcode file)\n"); | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 	u = ast_module_user_add(chan); | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2004-10-31 23:28:42 +00:00
										 |  |  | 	if (chan->pbx) { | 
					
						
							|  |  |  | 		firstdigittimeout = chan->pbx->rtimeout*1000; | 
					
						
							|  |  |  | 		digittimeout = chan->pbx->dtimeout*1000; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 	if (ast_set_write_format(chan,AST_FORMAT_ULAW)) { | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "Unable to set write format to Mu-law on %s\n", chan->name); | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 		ast_module_user_remove(u); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 	if (ast_set_read_format(chan,AST_FORMAT_ULAW)) { | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 		ast_log(LOG_WARNING, "Unable to set read format to Mu-law on %s\n", chan->name); | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 		ast_module_user_remove(u); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2006-10-03 15:53:07 +00:00
										 |  |  | 	if (option_debug) { | 
					
						
							|  |  |  | 		ast_log(LOG_DEBUG, "Digittimeout: %d\n", digittimeout); | 
					
						
							|  |  |  | 		ast_log(LOG_DEBUG, "Responsetimeout: %d\n", firstdigittimeout); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-05-10 13:22:15 +00:00
										 |  |  | 	tmp = ast_strdupa(data); | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	AST_STANDARD_APP_ARGS(args, tmp); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (ast_strlen_zero(args.context))  | 
					
						
							| 
									
										
										
										
											2005-11-15 19:40:08 +00:00
										 |  |  | 		args.context = "disa";	 | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	if (ast_strlen_zero(args.mailbox)) | 
					
						
							| 
									
										
										
										
											2005-11-15 19:40:08 +00:00
										 |  |  | 		args.mailbox = ""; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-03 15:53:07 +00:00
										 |  |  | 	if (option_debug) | 
					
						
							|  |  |  | 		ast_log(LOG_DEBUG, "Mailbox: %s\n",args.mailbox); | 
					
						
							| 
									
										
										
										
											2006-01-16 18:52:13 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	special_noanswer = 0; | 
					
						
							|  |  |  | 	if ((!args.noanswer) || strcmp(args.noanswer,"NOANSWER")) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (chan->_state != AST_STATE_UP) { | 
					
						
							|  |  |  | 			/* answer */ | 
					
						
							|  |  |  | 			ast_answer(chan); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} else special_noanswer = 1; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	i = k = x = 0; /* k is 0 for pswd entry, 1 for ext entry */ | 
					
						
							| 
									
										
										
										
											2004-09-15 22:06:30 +00:00
										 |  |  | 	did_ignore = 0; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	exten[0] = 0; | 
					
						
							| 
									
										
										
										
											2002-11-29 02:14:13 +00:00
										 |  |  | 	acctcode[0] = 0; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	/* can we access DISA without password? */  | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-10-03 15:53:07 +00:00
										 |  |  | 	if (option_debug) | 
					
						
							|  |  |  | 		ast_log(LOG_DEBUG, "Context: %s\n",args.context); | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	if (!strcasecmp(args.passcode, "no-password")) { | 
					
						
							| 
									
										
										
										
											2005-03-26 07:08:47 +00:00
										 |  |  | 		k |= 1; /* We have the password */ | 
					
						
							| 
									
										
										
										
											2006-10-03 15:53:07 +00:00
										 |  |  | 		if (option_debug) | 
					
						
							|  |  |  | 			ast_log(LOG_DEBUG, "DISA no-password login success\n"); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2005-07-15 23:00:47 +00:00
										 |  |  | 	lastdigittime = ast_tvnow(); | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 	play_dialtone(chan, args.mailbox); | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-19 18:19:02 +00:00
										 |  |  | 	for (;;) { | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		  /* if outa time, give em reorder */ | 
					
						
							| 
									
										
										
										
											2005-07-15 23:00:47 +00:00
										 |  |  | 		if (ast_tvdiff_ms(ast_tvnow(), lastdigittime) >  | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 		    ((k&2) ? digittimeout : firstdigittimeout)) { | 
					
						
							| 
									
										
										
										
											2006-10-03 15:53:07 +00:00
										 |  |  | 			if (option_debug) | 
					
						
							|  |  |  | 				ast_log(LOG_DEBUG,"DISA %s entry timeout on chan %s\n", | 
					
						
							|  |  |  | 					((k&1) ? "extension" : "password"),chan->name); | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 			break; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 		if ((res = ast_waitfor(chan, -1) < 0)) { | 
					
						
							| 
									
										
										
										
											2006-10-03 15:53:07 +00:00
										 |  |  | 			if (option_debug) | 
					
						
							|  |  |  | 				ast_log(LOG_DEBUG, "Waitfor returned %d\n", res); | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 			 | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		f = ast_read(chan); | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 		if (f == NULL) { | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 			ast_module_user_remove(u); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 			return -1; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if ((f->frametype == AST_FRAME_CONTROL) && | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 		    (f->subclass == AST_CONTROL_HANGUP)) { | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 			ast_frfree(f); | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 			ast_module_user_remove(u); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 			return -1; | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if (f->frametype == AST_FRAME_VOICE) { | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 			ast_frfree(f); | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 			continue; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		/* if not DTMF, just do it again */ | 
					
						
							|  |  |  | 		if (f->frametype != AST_FRAME_DTMF) { | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 			ast_frfree(f); | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2002-05-13 22:29:39 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		j = f->subclass;  /* save digit */ | 
					
						
							|  |  |  | 		ast_frfree(f); | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 		if (i == 0) { | 
					
						
							| 
									
										
										
										
											2005-03-26 07:08:47 +00:00
										 |  |  | 			k|=2; /* We have the first digit */  | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 			ast_playtones_stop(chan); | 
					
						
							| 
									
										
										
										
											2005-03-26 07:08:47 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-07-15 23:00:47 +00:00
										 |  |  | 		lastdigittime = ast_tvnow(); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		  /* got a DTMF tone */ | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 		if (i < AST_MAX_EXTENSION) { /* if still valid number of digits */ | 
					
						
							|  |  |  | 			if (!(k&1)) { /* if in password state */ | 
					
						
							|  |  |  | 				if (j == '#') { /* end of password */ | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 					  /* see if this is an integer */ | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 					if (sscanf(args.passcode,"%d",&j) < 1) { /* nope, it must be a filename */ | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 						fp = fopen(args.passcode,"r"); | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 						if (!fp) { | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 							ast_log(LOG_WARNING,"DISA password file %s not found on chan %s\n",args.passcode,chan->name); | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 							ast_module_user_remove(u); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 							return -1; | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2005-11-11 00:53:19 +00:00
										 |  |  | 						pwline[0] = 0; | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 						while(fgets(pwline,sizeof(pwline) - 1,fp)) { | 
					
						
							|  |  |  | 							if (!pwline[0]) | 
					
						
							|  |  |  | 								continue; | 
					
						
							| 
									
										
										
										
											2005-11-11 00:53:19 +00:00
										 |  |  | 							if (pwline[strlen(pwline) - 1] == '\n')  | 
					
						
							|  |  |  | 								pwline[strlen(pwline) - 1] = 0; | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 							if (!pwline[0]) | 
					
						
							|  |  |  | 								continue; | 
					
						
							|  |  |  | 							 /* skip comments */ | 
					
						
							|  |  |  | 							if (pwline[0] == '#') | 
					
						
							|  |  |  | 								continue; | 
					
						
							|  |  |  | 							if (pwline[0] == ';') | 
					
						
							|  |  |  | 								continue; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 							AST_STANDARD_APP_ARGS(args, pwline); | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2006-10-03 15:53:07 +00:00
										 |  |  | 							if (option_debug) | 
					
						
							|  |  |  | 								ast_log(LOG_DEBUG, "Mailbox: %s\n",args.mailbox); | 
					
						
							| 
									
										
										
										
											2005-07-07 22:42:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 							/* password must be in valid format (numeric) */ | 
					
						
							|  |  |  | 							if (sscanf(args.passcode,"%d", &j) < 1) | 
					
						
							|  |  |  | 								continue; | 
					
						
							|  |  |  | 							 /* if we got it */ | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 							if (!strcmp(exten,args.passcode)) { | 
					
						
							|  |  |  | 								if (ast_strlen_zero(args.context)) | 
					
						
							| 
									
										
										
										
											2005-11-15 19:40:08 +00:00
										 |  |  | 									args.context = "disa"; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 								if (ast_strlen_zero(args.mailbox)) | 
					
						
							| 
									
										
										
										
											2005-11-15 19:40:08 +00:00
										 |  |  | 									args.mailbox = ""; | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 								break; | 
					
						
							|  |  |  | 							} | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 						} | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 						fclose(fp); | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					/* compare the two */ | 
					
						
							|  |  |  | 					if (strcmp(exten,args.passcode)) { | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 						ast_log(LOG_WARNING,"DISA on chan %s got bad password %s\n",chan->name,exten); | 
					
						
							|  |  |  | 						goto reorder; | 
					
						
							| 
									
										
										
										
											2001-12-07 22:57:34 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 					} | 
					
						
							|  |  |  | 					 /* password good, set to dial state */ | 
					
						
							| 
									
										
										
										
											2006-10-03 15:53:07 +00:00
										 |  |  | 					if (option_debug) | 
					
						
							|  |  |  | 						ast_log(LOG_DEBUG,"DISA on chan %s password is good\n",chan->name); | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 					play_dialtone(chan, args.mailbox); | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-03-26 07:08:47 +00:00
										 |  |  | 					k|=1; /* In number mode */ | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 					i = 0;  /* re-set buffer pointer */ | 
					
						
							| 
									
										
										
										
											2001-12-07 22:57:34 +00:00
										 |  |  | 					exten[sizeof(acctcode)] = 0; | 
					
						
							| 
									
										
										
										
											2005-10-27 02:48:56 +00:00
										 |  |  | 					ast_copy_string(acctcode, exten, sizeof(acctcode)); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 					exten[0] = 0; | 
					
						
							| 
									
										
										
										
											2006-10-03 15:53:07 +00:00
										 |  |  | 					if (option_debug) | 
					
						
							|  |  |  | 						ast_log(LOG_DEBUG,"Successful DISA log-in on chan %s\n", chan->name); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 					continue; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2004-09-15 22:06:30 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 			exten[i++] = j;  /* save digit */ | 
					
						
							|  |  |  | 			exten[i] = 0; | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 			if (!(k&1)) | 
					
						
							|  |  |  | 				continue; /* if getting password, continue doing it */ | 
					
						
							|  |  |  | 			/* if this exists */ | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 			if (ast_ignore_pattern(args.context, exten)) { | 
					
						
							| 
									
										
										
										
											2004-10-31 23:28:42 +00:00
										 |  |  | 				play_dialtone(chan, ""); | 
					
						
							| 
									
										
										
										
											2004-09-15 22:06:30 +00:00
										 |  |  | 				did_ignore = 1; | 
					
						
							|  |  |  | 			} else | 
					
						
							|  |  |  | 				if (did_ignore) { | 
					
						
							|  |  |  | 					ast_playtones_stop(chan); | 
					
						
							|  |  |  | 					did_ignore = 0; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 			/* if can do some more, do it */ | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 			if (!ast_matchmore_extension(chan,args.context,exten,1, chan->cid.cid_num)) { | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 				break; | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 	if (k == 3) { | 
					
						
							|  |  |  | 		int recheck = 0; | 
					
						
							| 
									
										
										
										
											2005-11-07 04:10:41 +00:00
										 |  |  | 		struct ast_flags flags = { AST_CDR_FLAG_POSTED }; | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 		if (!ast_exists_extension(chan, args.context, exten, 1, chan->cid.cid_num)) { | 
					
						
							| 
									
										
										
										
											2005-10-23 01:39:40 +00:00
										 |  |  | 			pbx_builtin_setvar_helper(chan, "INVALID_EXTEN", exten); | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 			exten[0] = 'i'; | 
					
						
							|  |  |  | 			exten[1] = '\0'; | 
					
						
							|  |  |  | 			recheck = 1; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 		if (!recheck || ast_exists_extension(chan, args.context, exten, 1, chan->cid.cid_num)) { | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 			ast_playtones_stop(chan); | 
					
						
							|  |  |  | 			/* We're authenticated and have a target extension */ | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 			if (!ast_strlen_zero(args.cid)) { | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 				ast_callerid_split(args.cid, ourcidname, sizeof(ourcidname), ourcidnum, sizeof(ourcidnum)); | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 				ast_set_callerid(chan, ourcidnum, ourcidname, ourcidnum); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			if (!ast_strlen_zero(acctcode)) | 
					
						
							| 
									
										
										
										
											2006-02-01 23:05:28 +00:00
										 |  |  | 				ast_string_field_set(chan, accountcode, acctcode); | 
					
						
							| 
									
										
										
										
											2005-09-07 19:13:00 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-01-16 18:52:13 +00:00
										 |  |  | 			if (special_noanswer) flags.flags = 0; | 
					
						
							| 
									
										
										
										
											2005-11-07 04:10:41 +00:00
										 |  |  | 			ast_cdr_reset(chan->cdr, &flags); | 
					
						
							| 
									
										
										
										
											2005-11-15 19:27:18 +00:00
										 |  |  | 			ast_explicit_goto(chan, args.context, exten, 1); | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 			ast_module_user_remove(u); | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 			return 0; | 
					
						
							| 
									
										
										
										
											2005-07-19 23:45:21 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2005-10-13 23:52:42 +00:00
										 |  |  | 	/* Received invalid, but no "i" extension exists in the given context */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | reorder: | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	ast_indicate(chan,AST_CONTROL_CONGESTION); | 
					
						
							|  |  |  | 	/* something is invalid, give em reorder for several seconds */ | 
					
						
							|  |  |  | 	time(&rstart); | 
					
						
							| 
									
										
										
										
											2006-01-04 13:49:25 +00:00
										 |  |  | 	while(time(NULL) < rstart + 10) { | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 		if (ast_waitfor(chan, -1) < 0) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		f = ast_read(chan); | 
					
						
							|  |  |  | 		if (!f) | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		ast_frfree(f); | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2004-08-28 17:33:43 +00:00
										 |  |  | 	ast_playtones_stop(chan); | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 	ast_module_user_remove(u); | 
					
						
							| 
									
										
										
										
											2003-06-15 11:42:48 +00:00
										 |  |  | 	return -1; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | static int unload_module(void) | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2005-10-18 22:52:21 +00:00
										 |  |  | 	int res; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	res = ast_unregister_application(app); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | 	ast_module_user_hangup_all(); | 
					
						
							| 
									
										
										
										
											2005-10-18 22:52:21 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return res; | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | static int load_module(void) | 
					
						
							| 
									
										
										
										
											2001-08-25 04:26:20 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	return ast_register_application(app, disa_exec, synopsis, descrip); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2006-08-21 02:11:39 +00:00
										 |  |  | AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "DISA (Direct Inward System Access) Application"); |