219 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| phpagi-asmanager:  an Asterisk Manager class written in PHP
 | |
| 
 | |
|   Matthew Asham <matthewa@bcwireless.net>
 | |
|   http://phpagi.sourceforge.net
 | |
| ------------------------------------------------------------------------------
 | |
| 
 | |
| ------------------------------------------------------------------------------
 | |
| SECURITY
 | |
| ------------------------------------------------------------------------------
 | |
| 
 | |
| Validation:
 | |
| 
 | |
| ******If asterisk is running as root, the manager interface may allow the
 | |
| execution of arbitrary shell commands as root. If the user can update any
 | |
| configuration file that can execute arbitrary command (like the dialplan),
 | |
| the system may be compromised.
 | |
| 
 | |
| Also, look out for command injection.  Consider the following example:
 | |
| 
 | |
| 	$as->Events($_POST['events_status']);
 | |
| 
 | |
| We expect either 'on' or 'off', but the attacker uses:
 | |
| 
 | |
| 	"\r\n\r\nAction: Command\r\nCommand: database put forward 54321 19005551212";
 | |
| 
 | |
| 
 | |
| Validation is a *must* for all user data.
 | |
| 
 | |
| 
 | |
| Username and Secret:
 | |
| 
 | |
| Storing the username and secret in the config file will isolate them from your
 | |
| code.
 | |
| 
 | |
| Isolation of username and secret in the config file does not mean that the
 | |
| script cannot simple read the config file.  The config file must be readable
 | |
| by the script.
 | |
| 
 | |
| 
 | |
| CREATING A NEW INSTANCE OF THE CLASS
 | |
| ------------------------------------------------------------------------------
 | |
| 
 | |
| The class can be created standalone of phpagi.php, or through phpagi.
 | |
| 
 | |
| STANDALONE:
 | |
| 
 | |
| require "phpagi-asmanager.php";
 | |
| 
 | |
| $as = new AGI_AsteriskManager();
 | |
| 
 | |
| FROM PHPAGI:
 | |
| 
 | |
| require "phpagi.php";
 | |
| 
 | |
| $agi = new AGI();
 | |
| $as = $agi->new_AsteriskManager();
 | |
| 
 | |
| Notes:
 | |
| 
 | |
| * If the class is created using $agi->new_AsteriskManager(),
 | |
|   AGI_AsteriskManager will use the parent phpagi for logging to the Asterisk 
 | |
|   console.  
 | |
| 
 | |
| * phpagi.php will include phpagi-asmanager.php by itself.  
 | |
|   * If phpagi-asmanager.php is included _before_ phpagi.php, phpagi.php will 
 | |
|     not attempt to re-include it.
 | |
|   * If phpagi.php tries to include phpagi-asmanager.php but is unable to do 
 | |
|     so, an error will be echoed to the asterisk console and the script will 
 | |
|     continue running normally.  in this case the return value of 
 | |
|     new_AsteriskManager() will be FALSE.
 | |
| 
 | |
| ------------------------------------------------------------------------------
 | |
| CONFIGURATION
 | |
| ------------------------------------------------------------------------------
 | |
| 
 | |
| phpagi-asmanager uses the same configuration file as phpagi.conf (usually
 | |
| /etc/asterisk/phpagi.conf). All configuration information specific to
 | |
| phpagi-asmanager is contained in the [asmanager] section of the .conf file.
 | |
| 
 | |
| supported directives:
 | |
| 
 | |
| [asmanager]
 | |
| # server to connect to
 | |
| server=localhost
 | |
| 
 | |
| # default manager port
 | |
| port=5038
 | |
| 
 | |
| #username for login
 | |
| username=me_and_only_me
 | |
| 
 | |
| #password for login
 | |
| secret=i_am_not_telling
 | |
| 
 | |
| 
 | |
| 
 | |
| ------------------------------------------------------------------------------
 | |
| CONNECTING
 | |
| ------------------------------------------------------------------------------
 | |
| 
 | |
| 	$res = $as->connect("localhost", "username", "password");
 | |
| 	if($res == FALSE) {
 | |
| 		echo "Connection failed.\n";
 | |
| 	}
 | |
| 	elseif($res == TRUE){
 | |
| 		echo "Connection established.\n";
 | |
| 	}
 | |
| 
 | |
| A port can also be specified for the hostname.  eg:
 | |
| 
 | |
| 	$res = $as->connect("my.asterisk.server:1234", "username", "port");
 | |
| 
 | |
| If the no parameters are specified, the defaults from the config will be used.
 | |
| 
 | |
| 
 | |
| ------------------------------------------------------------------------------
 | |
| DISCONNECTING
 | |
| ------------------------------------------------------------------------------
 | |
| 
 | |
|   $as->disconnect();
 | |
| 
 | |
| ------------------------------------------------------------------------------
 | |
| SENDING REQUESTS
 | |
| ------------------------------------------------------------------------------
 | |
| 
 | |
| 	$as->send_request($eventname, $arrayofparameterstopass);
 | |
| 
 | |
| send_request() calls wait_request and returns an array of returned data from
 | |
| the manager.  If something went wrong, it returns false.
 | |
| 
 | |
| wait_request() shouldn't need to be called from a script directly unless you 
 | |
| are implementing merely an event listener.
 | |
| 
 | |
| wait_request() will also detect events and dispatch any registered event
 | |
| handlers for the event.
 | |
| 
 | |
| examples:
 | |
| 
 | |
| 	$res = $as->send_request('EventName',
 | |
|                                  array('Channel'=>'Zap/1/16045551212',
 | |
|                                                   'SomeParameter'=>'data'));
 | |
| 	echo "Dump of returned data:\n";
 | |
| 	foreach($res as $var=>$val)
 | |
| 	  echo "$var = $val\n";
 | |
| 
 | |
| 
 | |
| $res['Response'] will generally be 'Success' on success and 'Error' on
 | |
| failure. But this is not always true.  If $res['Response'] == 'Follows', a
 | |
| multi-line response will be stored in $res['data'].
 | |
| 
 | |
| Several manager commands have been aliased for convenience. See below.
 | |
| 
 | |
| ------------------------------------------------------------------------------
 | |
| EVENTS
 | |
| ------------------------------------------------------------------------------
 | |
| 
 | |
| TODO: non-blocking socket i/o. 
 | |
| 
 | |
| The class uses event callbacks to process events received from the manager.
 | |
| 
 | |
| The event callback prototype looks like:
 | |
| 
 | |
| 	function dump_event($ecode, $data, $server, $port)
 | |
| 	{
 | |
| 	  echo "received event '$ecode' from $server:$port\n";
 | |
| 	  print_r($data);
 | |
| 	}
 | |
| 
 | |
| To register an event call back:
 | |
| 
 | |
| 	$as->add_event_handler('eventname', 'eventfunction');
 | |
| 
 | |
| eg:
 | |
| 
 | |
| 	$as->add_event_handler('registry', 'dump_event');
 | |
| 
 | |
| 
 | |
| The special eventname "*" can also be registered.  any eventname not
 | |
| specifically registered will be handled by the "*" handler.  If no "*" handler
 | |
| is defined, the event will be silently ignored.
 | |
| 
 | |
| 
 | |
| ------------------------------------------------------------------------------
 | |
| PRECANNED FUNCTIONS
 | |
| ------------------------------------------------------------------------------
 | |
| 
 | |
| The following Manager functions have been aliased for convenience:
 | |
| 
 | |
| AbsoluteTimeout
 | |
| ChangeMonitor
 | |
| Command
 | |
| Events
 | |
| ExtensionState
 | |
| GetVar
 | |
| Hangup
 | |
| IAXPeers
 | |
| ListCommands
 | |
| Logoff
 | |
| MailboxCount
 | |
| MailboxStatus
 | |
| Monitor
 | |
| Originate
 | |
| ParkedCalls
 | |
| Ping
 | |
| Queues
 | |
| QueueStatus
 | |
| Redirect
 | |
| SetCDRUserField
 | |
| SetVar
 | |
| SIPpeers
 | |
| Status
 | |
| StopMontor
 | |
| ZapDialOffhook
 | |
| ZapDNDoff
 | |
| ZapDNDon
 | |
| ZapHangup
 | |
| ZapTransfer
 | |
| 
 |