| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387 | <?php
/**
 * Main API interface between JavaScript ajax calls and PHP functions.
 * Accepts JSON, POST data or simple GET requests, and returns JSON data.
 *
 * @author Ian Moore (imoore76 at yahoo dot com)
 * @copyright Copyright (C) 2010-2015 Ian Moore (imoore76 at yahoo dot com)
 * @version $Id: api.php 596 2015-04-19 11:50:53Z imoore76 $
 * @package phpVirtualBox
 * @see vboxconnector
 * @see vboxAjaxRequest
 *
 * @global array $GLOBALS['response'] resopnse data sent back via json
 * @name $response
*/
# Turn off PHP errors
error_reporting(E_ALL & ~E_NOTICE & ~E_STRICT & ~E_WARNING);
//Set no caching
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0");
header("Pragma: no-cache");
require_once(dirname(__FILE__).'/lib/config.php');
require_once(dirname(__FILE__).'/lib/utils.php');
require_once(dirname(__FILE__).'/lib/vboxconnector.php');
// Init session
global $_SESSION;
/*
 * Clean request
 */
$request = clean_request();
global $response;
$response = array('data'=>array('responseData'=>array()),'errors'=>array(),'persist'=>array(),'messages'=>array());
/*
 * Built-in requests
 */
$vbox = null; // May be set during request handling
/**
 * Main try / catch. Logic dictated by incoming 'fn' request
 * parameter.
 */
try {
	/* Check for password recovery file */
	if(file_exists(dirname(dirname(__FILE__)).'/recovery.php')) {
		throw new Exception('recovery.php exists in phpVirtualBox\'s folder. This is a security hazard. phpVirtualBox will not run until recovery.php has been renamed to a file name that does not end in .php such as <b>recovery.php-disabled</b>.',vboxconnector::PHPVB_ERRNO_FATAL);
	}
	/* Check for PHP version */
	if (!version_compare(PHP_VERSION, '5.2.0', '>=')) {
		throw new Exception('phpVirtualBox requires PHP >= 5.2.0, but this server is running version '. PHP_VERSION .'. Please upgrade PHP.');
	}
	# Only valid function chars
	$request['fn'] = preg_replace('[^a-zA-Z0-9_-]', '', $request['fn']);
	/* Check for function called */
	switch($request['fn']) {
		/*
		 * No method called
		 */
	    case '':
	    	throw new Exception('No method called.');
	    	break;
		/*
		 * Return phpVirtualBox's configuration data
		 */
		case 'getConfig':
			$settings = new phpVBoxConfigClass();
			$response['data']['responseData'] = get_object_vars($settings);
			$response['data']['responseData']['host'] = parse_url($response['data']['responseData']['location']);
			$response['data']['responseData']['host'] = $response['data']['responseData']['host']['host'];
			$response['data']['responseData']['phpvboxver'] = @constant('PHPVBOX_VER');
			// Session
			session_init();
			// Hide credentials
			unset($response['data']['responseData']['username']);
			unset($response['data']['responseData']['password']);
			foreach($response['data']['responseData']['servers'] as $k => $v)
				$response['data']['responseData']['servers'][$k] = array('name'=>$v['name']);
			// Vbox version
			$vbox = new vboxconnector();
			$response['data']['responseData']['version'] = $vbox->getVersion();
			$response['data']['responseData']['hostOS'] = $vbox->vbox->host->operatingSystem;
			$response['data']['responseData']['DSEP'] = $vbox->getDsep();
			$response['data']['responseData']['groupDefinitionKey'] = ($settings->phpVboxGroups ? vboxconnector::phpVboxGroupKey : 'GUI/GroupDefinitions');
			$response['data']['success'] = true;
			break;
		/*
		 *
		 * USER FUNCTIONS FOLLOW
		 *
		 */
		/*
		 * Pass login to authentication module.
		 */
		case 'login':
			// NOTE: Do not break. Fall through to 'getSession
			if(!$request['params']['u'] || !$request['params']['p']) {
				break;
			}
			// Session
			session_init(true);
			$settings = new phpVBoxConfigClass();
			// Try / catch here to hide login credentials
			try {
				$settings->auth->login($request['params']['u'], $request['params']['p']);
			} catch(Exception $e) {
				throw new Exception($e->getMessage(), $e->getCode());
			}
			// We're done writing to session
			if(function_exists('session_write_close'))
				@session_write_close();
		/*
		 * Return $_SESSION data
		 */
		case 'getSession':
			$settings = new phpVBoxConfigClass();
			if(method_exists($settings->auth,'autoLoginHook'))
			{
				// Session
				session_init(true);
				$settings->auth->autoLoginHook();
				// We're done writing to session
				if(function_exists('session_write_close'))
					@session_write_close();
			} else {
				session_init();
			}
			$response['data']['responseData'] = $_SESSION;
			$response['data']['success'] = true;
			break;
		/*
		 * Change phpVirtualBox password. Passed to auth module's
		 * changePassword method.
		 */
		case 'changePassword':
			// Session
			session_init(true);
			$settings = new phpVBoxConfigClass();
			$response['data']['success'] = $settings->auth->changePassword($request['params']['old'],
					                                                       $request['params']['new']);
			// We're done writing to session
			if(function_exists('session_write_close'))
				@session_write_close();
			break;
		/*
		 * Get a list of phpVirtualBox users. Passed to auth module's
		 * getUsers method.
		 */
		case 'getUsers':
			// Session
			session_init();
			// Must be an admin
			if(!$_SESSION['admin']) break;
			$settings = new phpVBoxConfigClass();
			$response['data']['responseData'] = $settings->auth->listUsers();
			$response['date']['success'] = true;
			break;
		/*
		 * Remove a phpVirtualBox user. Passed to auth module's
		 * deleteUser method.
		 */
		case 'delUser':
			// Session
			session_init();
			// Must be an admin
			if(!$_SESSION['admin']) break;
			$settings = new phpVBoxConfigClass();
			$settings->auth->deleteUser($request['params']['u']);
			$response['data']['success'] = true;
			break;
		/*
		 * Edit a phpVirtualBox user. Passed to auth module's
		 * updateUser method.
		 */
		case 'editUser':
			$skipExistCheck = true;
			// Fall to addUser
		/*
		 * Add a user to phpVirtualBox. Passed to auth module's
		 * updateUser method.
		 */
		case 'addUser':
			// Session
			session_init();
			// Must be an admin
			if(!$_SESSION['admin']) break;
			$settings = new phpVBoxConfigClass();
			$settings->auth->updateUser($request['params'], @$skipExistCheck);
			$response['data']['success'] = true;
			break;
		/*
		 * Log out of phpVirtualBox. Passed to auth module's
		 * logout method.
		 */
		case 'logout':
			// Session
			session_init(true);
			$vbox = new vboxconnector();
			$vbox->skipSessionCheck = true;
			$settings = new phpVBoxConfigClass();
			$settings->auth->logout($response);
			session_destroy();
			$response['data']['success'] = true;
			break;
		/*
		 * If the above cases did not match, assume it is a request
		 * that should be passed to vboxconnector.
		 */
		default:
			$vbox = new vboxconnector();
			/*
			 * Every 1 minute we'll check that the account has not
			 * been deleted since login, and update admin credentials.
			 */
			if($_SESSION['user'] && ((intval($_SESSION['authCheckHeartbeat'])+60) < time())) {
				// init session and keep it open
				session_init(true);
				$vbox->settings->auth->heartbeat($vbox);
				// We're done writing to session
				if(function_exists('session_write_close'))
					@session_write_close();
			} else {
				// init session but close it
				session_init();
			}
			/*
			 *  Persistent request data
			 */
			if(is_array($request['persist'])) {
				$vbox->persistentRequest = $request['persist'];
			}
			/*
			 * Call to vboxconnector
			 */
			$vbox->{$request['fn']}($request['params'],array(&$response));
			/*
			 * Send back persistent request in response
			*/
			if(is_array($vbox->persistentRequest) && count($vbox->persistentRequest)) {
				$response['data']['persist'] = $vbox->persistentRequest;
			}
			break;
	} // </switch()>
/*
 * Catch all exceptions and populate errors in the
 * JSON response data.
 */
} catch (Exception $e) {
	// Just append to $vbox->errors and let it get
	// taken care of below
	if(!$vbox || !$vbox->errors) {
		$vbox->errors = array();
	}
	$vbox->errors[] = $e;
}
// Add any messages
if($vbox && count($vbox->messages)) {
	foreach($vbox->messages as $m)
		$response['messages'][] = 'vboxconnector('.$request['fn'] .'): ' . $m;
}
// Add other error info
if($vbox && $vbox->errors) {
	foreach($vbox->errors as $e) { /* @var $e Exception */
		ob_start();
		print_r($e);
		$d = ob_get_contents();
		ob_end_clean();
		# Add connection details to connection errors
		if($e->getCode() == vboxconnector::PHPVB_ERRNO_CONNECT && isset($vbox->settings))
			$d .= "\n\nLocation:" . $vbox->settings->location;
		$response['messages'][] = htmlentities($e->getMessage()).' ' . htmlentities($details);
		$response['errors'][] = array(
			'error'=> ($e->getCode() & vboxconnector::PHPVB_ERRNO_HTML ? $e->getMessage() : htmlentities($e->getMessage())),
			'details'=>htmlentities($d),
			'errno'=>$e->getCode(),
			// Fatal errors halt all processing
			'fatal'=>($e->getCode() & vboxconnector::PHPVB_ERRNO_FATAL),
			// Connection errors display alternate servers options
			'connection'=>($e->getCode() & vboxconnector::PHPVB_ERRNO_CONNECT)
		);
	}
}
/*
 * Return response as JSON encoded data or use PHP's
 * print_r to dump data to browser.
 */
if(isset($request['printr'])) {
	print_r($response);
} else {
    header('Content-type: application/json');
	echo(json_encode($response));
}
 |