2015-06-11 10:58:58 +08:00
|
|
|
<?php
|
|
|
|
App::uses('AppController', 'Controller');
|
|
|
|
|
|
|
|
class HostController extends AppController {
|
2018-07-11 21:54:25 +08:00
|
|
|
|
2018-07-16 09:17:35 +08:00
|
|
|
public $components = array('RequestHandler', 'Session');
|
2015-06-11 10:58:58 +08:00
|
|
|
|
2018-07-16 09:17:35 +08:00
|
|
|
public function daemonCheck($daemon=false, $args=false) {
|
2018-04-30 23:24:53 +08:00
|
|
|
$string = Configure::read('ZM_PATH_BIN').'/zmdc.pl check';
|
2018-04-07 02:41:39 +08:00
|
|
|
if ( $daemon ) {
|
2018-08-08 21:59:46 +08:00
|
|
|
$string .= " $daemon";
|
|
|
|
if ( $args )
|
|
|
|
$string .= " $args";
|
2015-06-11 10:58:58 +08:00
|
|
|
}
|
2018-04-30 23:24:53 +08:00
|
|
|
$result = exec($string);
|
|
|
|
$result = preg_match('/running/', $result);
|
2015-06-11 10:58:58 +08:00
|
|
|
|
2018-07-16 09:17:35 +08:00
|
|
|
$this->set(array(
|
|
|
|
'result' => $result,
|
|
|
|
'_serialize' => array('result')
|
|
|
|
));
|
|
|
|
}
|
2015-06-11 10:58:58 +08:00
|
|
|
|
2018-07-16 09:17:35 +08:00
|
|
|
function getLoad() {
|
|
|
|
$load = sys_getloadavg();
|
2015-06-11 10:58:58 +08:00
|
|
|
|
2018-07-16 09:17:35 +08:00
|
|
|
$this->set(array(
|
|
|
|
'load' => $load,
|
|
|
|
'_serialize' => array('load')
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
function login() {
|
2019-05-13 06:19:19 +08:00
|
|
|
|
2019-05-09 03:26:51 +08:00
|
|
|
$mUser = $this->request->query('user') ? $this->request->query('user') : $this->request->data('user');
|
|
|
|
$mPassword = $this->request->query('pass') ? $this->request->query('pass') : $this->request->data('pass');
|
|
|
|
$mToken = $this->request->query('token') ? $this->request->query('token') : $this->request->data('token');
|
|
|
|
|
2019-05-13 06:51:07 +08:00
|
|
|
|
|
|
|
if ( !($mUser && $mPassword) && !$mToken ) {
|
|
|
|
throw new UnauthorizedException(__('No identity provided'));
|
|
|
|
}
|
2018-07-16 09:17:35 +08:00
|
|
|
|
|
|
|
$ver = $this->_getVersion();
|
2019-05-13 06:19:19 +08:00
|
|
|
$cred = [];
|
|
|
|
$cred_depr = [];
|
|
|
|
|
2019-05-09 03:26:51 +08:00
|
|
|
if ($mUser && $mPassword) {
|
2019-05-13 06:19:19 +08:00
|
|
|
$cred = $this->_getCredentials(true); // generate refresh
|
2019-05-09 03:26:51 +08:00
|
|
|
}
|
|
|
|
else {
|
2019-05-18 23:23:16 +08:00
|
|
|
$cred = $this->_getCredentials(false, $mToken); // don't generate refresh
|
2019-05-13 06:19:19 +08:00
|
|
|
}
|
2019-05-09 03:26:51 +08:00
|
|
|
|
2019-05-13 06:19:19 +08:00
|
|
|
$login_array = array (
|
|
|
|
'access_token'=>$cred[0],
|
2019-05-13 06:51:07 +08:00
|
|
|
'access_token_expires'=>$cred[1]
|
2019-05-13 06:19:19 +08:00
|
|
|
);
|
|
|
|
|
|
|
|
$login_serialize_list = array (
|
|
|
|
'access_token',
|
2019-05-13 06:51:07 +08:00
|
|
|
'access_token_expires'
|
2019-05-13 06:19:19 +08:00
|
|
|
);
|
|
|
|
|
2019-05-13 06:51:07 +08:00
|
|
|
if ($mUser && $mPassword) {
|
2019-05-13 06:19:19 +08:00
|
|
|
$login_array['refresh_token'] = $cred[2];
|
|
|
|
$login_array['refresh_token_expires'] = $cred[3];
|
|
|
|
array_push ($login_serialize_list, 'refresh_token', 'refresh_token_expires');
|
2019-05-09 03:26:51 +08:00
|
|
|
}
|
|
|
|
|
2019-05-13 06:19:19 +08:00
|
|
|
if (ZM_OPT_USE_LEGACY_API_AUTH) {
|
|
|
|
$cred_depr = $this->_getCredentialsDeprecated();
|
|
|
|
$login_array ['credentials']=$cred_depr[0];
|
|
|
|
$login_array ['append_password']=$cred_depr[1];
|
|
|
|
array_push ($login_serialize_list, 'credentials', 'append_password');
|
|
|
|
}
|
|
|
|
|
2019-05-13 06:51:07 +08:00
|
|
|
|
|
|
|
$login_array['version'] = $ver[0];
|
|
|
|
$login_array['apiversion'] = $ver[1];
|
|
|
|
array_push ($login_serialize_list, 'version', 'apiversion');
|
|
|
|
|
|
|
|
$login_array["_serialize"] = $login_serialize_list;
|
|
|
|
|
|
|
|
$this->set($login_array);
|
2019-05-13 06:19:19 +08:00
|
|
|
|
2019-05-09 03:26:51 +08:00
|
|
|
|
2018-08-08 21:59:46 +08:00
|
|
|
} // end function login()
|
2018-07-16 09:17:35 +08:00
|
|
|
|
|
|
|
// clears out session
|
|
|
|
function logout() {
|
2019-02-27 06:01:45 +08:00
|
|
|
userLogout();
|
2018-07-16 09:17:35 +08:00
|
|
|
|
|
|
|
$this->set(array(
|
|
|
|
'result' => 'ok',
|
|
|
|
'_serialize' => array('result')
|
|
|
|
));
|
|
|
|
|
2018-08-08 21:59:46 +08:00
|
|
|
} // end function logout()
|
2019-05-08 03:04:12 +08:00
|
|
|
|
|
|
|
private function _getCredentialsDeprecated() {
|
2018-07-11 21:54:25 +08:00
|
|
|
$credentials = '';
|
|
|
|
$appendPassword = 0;
|
2019-05-08 03:04:12 +08:00
|
|
|
if (ZM_OPT_USE_AUTH) {
|
|
|
|
require_once __DIR__ .'/../../../includes/auth.php';
|
|
|
|
if (ZM_AUTH_RELAY=='hashed') {
|
|
|
|
$credentials = 'auth='.generateAuthHash(ZM_AUTH_HASH_IPS,true);
|
|
|
|
}
|
|
|
|
else {
|
2019-02-27 06:01:45 +08:00
|
|
|
$credentials = 'user='.$this->Session->read('Username').'&pass=';
|
2018-07-11 21:54:25 +08:00
|
|
|
$appendPassword = 1;
|
|
|
|
}
|
2019-05-08 03:04:12 +08:00
|
|
|
return array($credentials, $appendPassword);
|
2018-04-30 23:24:53 +08:00
|
|
|
}
|
2019-05-08 03:04:12 +08:00
|
|
|
}
|
2018-07-16 09:17:35 +08:00
|
|
|
|
2019-05-18 23:23:16 +08:00
|
|
|
private function _getCredentials($generate_refresh_token=false, $mToken='') {
|
2018-07-11 21:54:25 +08:00
|
|
|
$credentials = '';
|
|
|
|
$this->loadModel('Config');
|
2018-07-16 09:17:35 +08:00
|
|
|
|
2019-05-09 00:11:32 +08:00
|
|
|
if ( ZM_OPT_USE_AUTH ) {
|
2019-05-08 03:04:12 +08:00
|
|
|
require_once __DIR__ .'/../../../includes/auth.php';
|
|
|
|
require_once __DIR__.'/../../../vendor/autoload.php';
|
2019-05-09 00:11:32 +08:00
|
|
|
|
2019-05-08 03:04:12 +08:00
|
|
|
$key = ZM_AUTH_HASH_SECRET;
|
2019-05-09 02:26:16 +08:00
|
|
|
if (!$key) {
|
|
|
|
throw new ForbiddenException(__('Please create a valid AUTH_HASH_SECRET in ZoneMinder'));
|
|
|
|
}
|
2019-05-09 00:11:32 +08:00
|
|
|
|
2019-05-18 23:23:16 +08:00
|
|
|
if ($mToken) {
|
|
|
|
// If we have a token, we need to derive username from there
|
Replace MySQL Password() with bcrypt, allow for alternate JWT tokens (#2598)
* added sha1 and bcrypt submodules
* added bcrypt and sha to src build process
* added test sha1 and bcrypt code to validate working
* bcrypt auth migration in PHP land
* added include path
* add sha source
* added bcrypt to others
* put link_dir ahead of add_executable
* fixed typo
* try add_library instead
* absolute path
* absolute path
* build bcrypt as static
* move to wrapper
* move to fork
* logs tweak
* added lib-ssl/dev for JWT signing
* Moved to openSSL SHA1, initial JWT plugin
* removed vog
* fixed SHA1 algo
* typo
* use php-jwt, use proper way to add PHP modules, via composer
* fixed module path
* first attempt to fix cast error
* own fork
* own fork
* add composer vendor directory
* go back to jwt-cpp as PR merged
* moved to jwt-cpp after PR merge
* New token= query for JWT
* Add JWT token creation, move old code to a different function for future deprecation, simplified code for ZM_XX parameter reading
* JWT integration, validate JWT token via validateToken
* added token validation to zms/zmu/zmuser
* add token to command line for zmu
* move decode inside try/catch
* exception handling for try/catch
* fix db read, forgot to exec query
* remove allowing auth_hash_ip for token
* support refresh tokens as well for increased security
* remove auth_hash_ip
* Error out if used did not create an AUTH_HASH_SECRET
* fixed type conversion
* make sure refresh token login doesn't generate another refresh token
* fix absolute path
* move JWT/Bcrypt inside zm_crypt
* move sha headers out
* move out sha header
* handle case when supplied password is hashed, fix wrong params in AppController
* initial baby step for api tab
* initial plumbing to introduce token expiry and API bans per user
* remove M typo
* display user table in api
* added revoke all tokens code, removed test code
* use strtoul for conversion
* use strtoul for conversion
* use strtoul for conversion
* more fixes
* more fixes
* add mintokenexpiry to DB seek
* typo
* add ability to revoke tokens and enable/disable APIs per user
* moved API enable back to system
* comma
* enable API options only if API enabled
* move user creation to bcrypt
* added password_compat for PHP >=5.3 <5.5
* add Password back so User object indexes don't change
* move token index after adding password
* demote logs
* make old API auth optional, on by default
* make old API auth mechanism optional
* removed stale code
* forgot to checkin update file
* bulk overlay hash mysql encoded passwords
* add back ssl_dev, got deleted
* fix update script
* added token support to index.php
* reworked API document for new changes in 2.0
* Migrate from libdigest to crypt-eks-blowfish due to notice
* merge typo
* css classess for text that disappear
* fixed html typo
* added deps to ubuntu control files
* spaces
* removed extra line
* when regenerating using refresh tokens, username needs to be derived from the refresh token, as no session would exist
* add libssl1.0.0 for ubuntu 16/12
* small API fixes
* clean up of API, remove redundant sections
* moved to ZM fork for bcrypt
* whitespace and google code style
* regenerate auth hash if doing password migration
* dont need AUTH HASH LOGIN to be on
* Add auth hash verification to the user logged in already case
* fix missing ]
* reject requests if per user API disabled
2019-05-25 01:48:40 +08:00
|
|
|
$ret = validateToken($mToken, 'refresh', true);
|
2019-05-18 23:23:16 +08:00
|
|
|
$mUser = $ret[0]['Username'];
|
|
|
|
|
|
|
|
} else {
|
|
|
|
$mUser = $_SESSION['username'];
|
|
|
|
}
|
|
|
|
|
|
|
|
ZM\Info("Creating token for \"$mUser\"");
|
|
|
|
|
2019-05-09 00:11:32 +08:00
|
|
|
/* we won't support AUTH_HASH_IPS in token mode
|
|
|
|
reasons:
|
|
|
|
a) counter-intuitive for mobile consumers
|
|
|
|
b) zmu will never be able to to validate via a token if we sign
|
|
|
|
it after appending REMOTE_ADDR
|
|
|
|
|
|
|
|
if (ZM_AUTH_HASH_IPS) {
|
2019-05-08 03:04:12 +08:00
|
|
|
$key = $key . $_SERVER['REMOTE_ADDR'];
|
2019-05-09 00:11:32 +08:00
|
|
|
}*/
|
|
|
|
|
2019-05-09 01:38:42 +08:00
|
|
|
$access_issued_at = time();
|
|
|
|
$access_ttl = (ZM_AUTH_HASH_TTL || 2) * 3600;
|
2019-05-08 03:04:12 +08:00
|
|
|
|
2019-05-09 01:38:42 +08:00
|
|
|
// by default access token will expire in 2 hrs
|
|
|
|
// you can change it by changing the value of ZM_AUTH_HASH_TLL
|
|
|
|
$access_expire_at = $access_issued_at + $access_ttl;
|
2019-05-12 03:47:57 +08:00
|
|
|
//$access_expire_at = $access_issued_at + 60; // TEST, REMOVE
|
2019-05-08 03:04:12 +08:00
|
|
|
|
2019-05-09 01:38:42 +08:00
|
|
|
$access_token = array(
|
2019-05-08 03:04:12 +08:00
|
|
|
"iss" => "ZoneMinder",
|
2019-05-09 01:38:42 +08:00
|
|
|
"iat" => $access_issued_at,
|
|
|
|
"exp" => $access_expire_at,
|
2019-05-18 23:23:16 +08:00
|
|
|
"user" => $mUser,
|
2019-05-09 01:38:42 +08:00
|
|
|
"type" => "access"
|
2019-05-08 03:04:12 +08:00
|
|
|
);
|
|
|
|
|
2019-05-09 01:38:42 +08:00
|
|
|
$jwt_access_token = \Firebase\JWT\JWT::encode($access_token, $key, 'HS256');
|
|
|
|
|
2019-05-09 03:26:51 +08:00
|
|
|
$jwt_refresh_token = "";
|
|
|
|
$refresh_ttl = 0;
|
2019-05-08 03:04:12 +08:00
|
|
|
|
2019-05-09 03:26:51 +08:00
|
|
|
if ($generate_refresh_token) {
|
|
|
|
$refresh_issued_at = time();
|
|
|
|
$refresh_ttl = 24 * 3600; // 1 day
|
|
|
|
|
|
|
|
$refresh_expire_at = $refresh_issued_at + $refresh_ttl;
|
|
|
|
$refresh_token = array(
|
|
|
|
"iss" => "ZoneMinder",
|
|
|
|
"iat" => $refresh_issued_at,
|
|
|
|
"exp" => $refresh_expire_at,
|
2019-05-18 23:23:16 +08:00
|
|
|
"user" => $mUser,
|
2019-05-09 03:26:51 +08:00
|
|
|
"type" => "refresh"
|
|
|
|
);
|
|
|
|
$jwt_refresh_token = \Firebase\JWT\JWT::encode($refresh_token, $key, 'HS256');
|
|
|
|
}
|
|
|
|
|
2019-05-08 03:04:12 +08:00
|
|
|
}
|
2019-05-09 01:38:42 +08:00
|
|
|
return array($jwt_access_token, $access_ttl, $jwt_refresh_token, $refresh_ttl);
|
2018-07-11 21:54:25 +08:00
|
|
|
}
|
2018-04-07 02:41:39 +08:00
|
|
|
|
2018-07-16 09:17:35 +08:00
|
|
|
// If $mid is set, only return disk usage for that monitor
|
2015-06-11 10:58:58 +08:00
|
|
|
// Else, return an array of total disk usage, and per-monitor
|
|
|
|
// usage.
|
2019-04-17 21:55:34 +08:00
|
|
|
// This function is deprecated. Use the Storage object or monitor object instead
|
2018-07-16 09:17:35 +08:00
|
|
|
function getDiskPercent($mid = null) {
|
|
|
|
$this->loadModel('Config');
|
|
|
|
$this->loadModel('Monitor');
|
|
|
|
|
|
|
|
// If $mid is passed, see if it is valid
|
2018-10-03 23:11:33 +08:00
|
|
|
if ( $mid ) {
|
|
|
|
if ( !$this->Monitor->exists($mid) ) {
|
2018-07-16 09:17:35 +08:00
|
|
|
throw new NotFoundException(__('Invalid monitor'));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-10-03 22:56:02 +08:00
|
|
|
$zm_dir_events = ZM_DIR_EVENTS;
|
2018-07-16 09:17:35 +08:00
|
|
|
|
|
|
|
// Test to see if $zm_dir_events is relative or absolute
|
2018-10-03 23:11:33 +08:00
|
|
|
#if ('/' === "" || strrpos($zm_dir_events, '/', -strlen($zm_dir_events)) !== TRUE) {
|
|
|
|
if ( substr($zm_dir_events, 0, 1) != '/' ) {
|
2018-07-16 09:17:35 +08:00
|
|
|
// relative - so add the full path
|
2018-10-03 22:56:02 +08:00
|
|
|
$zm_dir_events = ZM_PATH_WEB . '/' . $zm_dir_events;
|
2018-07-16 09:17:35 +08:00
|
|
|
}
|
|
|
|
|
2018-10-03 22:56:02 +08:00
|
|
|
if ( $mid ) {
|
2018-07-16 09:17:35 +08:00
|
|
|
// Get disk usage for $mid
|
2019-02-27 07:09:18 +08:00
|
|
|
ZM\Logger::Debug("Executing du -s0 $zm_dir_events/$mid | awk '{print $1}'");
|
2018-10-03 23:11:33 +08:00
|
|
|
$usage = shell_exec("du -s0 $zm_dir_events/$mid | awk '{print $1}'");
|
2018-07-16 09:17:35 +08:00
|
|
|
} else {
|
|
|
|
$monitors = $this->Monitor->find('all', array(
|
|
|
|
'fields' => array('Id', 'Name', 'WebColour')
|
|
|
|
));
|
|
|
|
$usage = array();
|
|
|
|
|
|
|
|
// Add each monitor's usage to array
|
|
|
|
foreach ($monitors as $key => $value) {
|
|
|
|
$id = $value['Monitor']['Id'];
|
|
|
|
$name = $value['Monitor']['Name'];
|
|
|
|
$color = $value['Monitor']['WebColour'];
|
|
|
|
|
|
|
|
$space = shell_exec ("du -s0 $zm_dir_events/$id | awk '{print $1}'");
|
|
|
|
if ($space == null) {
|
|
|
|
$space = 0;
|
|
|
|
}
|
|
|
|
$space = $space/1024/1024;
|
|
|
|
|
|
|
|
$usage[$name] = array(
|
|
|
|
'space' => rtrim($space),
|
|
|
|
'color' => $color
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Add total usage to array
|
|
|
|
$space = shell_exec( "df $zm_dir_events |tail -n1 | awk '{print $3 }'");
|
|
|
|
$space = $space/1024/1024;
|
|
|
|
$usage['Total'] = array(
|
|
|
|
'space' => rtrim($space),
|
|
|
|
'color' => '#F7464A'
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->set(array(
|
|
|
|
'usage' => $usage,
|
|
|
|
'_serialize' => array('usage')
|
|
|
|
));
|
|
|
|
}
|
2015-06-11 10:58:58 +08:00
|
|
|
|
2018-04-07 02:41:39 +08:00
|
|
|
function getTimeZone() {
|
|
|
|
//http://php.net/manual/en/function.date-default-timezone-get.php
|
|
|
|
$tz = date_default_timezone_get();
|
|
|
|
$this->set(array(
|
|
|
|
'tz' => $tz,
|
|
|
|
'_serialize' => array('tz')
|
|
|
|
));
|
|
|
|
}
|
2016-10-19 02:07:31 +08:00
|
|
|
|
2018-07-16 09:17:35 +08:00
|
|
|
private function _getVersion() {
|
|
|
|
$version = Configure::read('ZM_VERSION');
|
2019-05-08 03:04:12 +08:00
|
|
|
$apiversion = '2.0';
|
2018-07-16 09:17:35 +08:00
|
|
|
return array($version, $apiversion);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getVersion() {
|
|
|
|
$val = $this->_getVersion();
|
|
|
|
$this->set(array(
|
|
|
|
'version' => $val[0],
|
|
|
|
'apiversion' => $val[1],
|
|
|
|
'_serialize' => array('version', 'apiversion')
|
|
|
|
));
|
|
|
|
}
|
2015-06-11 10:58:58 +08:00
|
|
|
}
|