Merge branch 'storageareas' of github.com:ConnorTechnology/ZoneMinder into storageareas
This commit is contained in:
commit
4e7ce479b4
|
@ -271,3 +271,8 @@ EXECUTE stmt;
|
||||||
|
|
||||||
ALTER TABLE Monitors MODIFY EncoderParameters TEXT;
|
ALTER TABLE Monitors MODIFY EncoderParameters TEXT;
|
||||||
ALTER TABLE Monitors MODIFY Path VARCHAR(255);
|
ALTER TABLE Monitors MODIFY Path VARCHAR(255);
|
||||||
|
|
||||||
|
ALTER TAble Monitors MODIFY V4LMultiBuffer tinyint(1) unsigned;
|
||||||
|
ALTER TAble Monitors MODIFY ControlId int(10) unsigned;
|
||||||
|
ALTER TAble Monitors MODIFY TrackDelay smallint(5) unsigned;
|
||||||
|
ALTER TAble Monitors MODIFY ReturnDelay smallint(5) unsigned;
|
||||||
|
|
|
@ -116,7 +116,7 @@ switch ( $data['type'] )
|
||||||
session_start();
|
session_start();
|
||||||
$time = time();
|
$time = time();
|
||||||
// Regenerate auth hash after half the lifetime of the hash
|
// Regenerate auth hash after half the lifetime of the hash
|
||||||
if ( $_SESSION['AuthHashGeneratedAt'] < $time - (ZM_AUTH_HASH_TTL * 1800) ) {
|
if ( (!isset($_SESSION['AuthHashGeneratedAt'])) or ( $_SESSION['AuthHashGeneratedAt'] < $time - (ZM_AUTH_HASH_TTL * 1800) ) ) {
|
||||||
$data['auth'] = generateAuthHash( ZM_AUTH_HASH_IPS );
|
$data['auth'] = generateAuthHash( ZM_AUTH_HASH_IPS );
|
||||||
}
|
}
|
||||||
session_write_close();
|
session_write_close();
|
||||||
|
@ -134,7 +134,7 @@ switch ( $data['type'] )
|
||||||
session_start();
|
session_start();
|
||||||
$time = time();
|
$time = time();
|
||||||
// Regenerate auth hash after half the lifetime of the hash
|
// Regenerate auth hash after half the lifetime of the hash
|
||||||
if ( $_SESSION['AuthHashGeneratedAt'] < $time - (ZM_AUTH_HASH_TTL * 1800) ) {
|
if ( (!isset($_SESSION['AuthHashGeneratedAt'])) or ( $_SESSION['AuthHashGeneratedAt'] < $time - (ZM_AUTH_HASH_TTL * 1800) ) ) {
|
||||||
$data['auth'] = generateAuthHash( ZM_AUTH_HASH_IPS );
|
$data['auth'] = generateAuthHash( ZM_AUTH_HASH_IPS );
|
||||||
}
|
}
|
||||||
session_write_close();
|
session_write_close();
|
||||||
|
|
|
@ -126,7 +126,7 @@ class Event {
|
||||||
} # ! ZM_OPT_FAST_DELETE
|
} # ! ZM_OPT_FAST_DELETE
|
||||||
} # end Event->delete
|
} # end Event->delete
|
||||||
|
|
||||||
public function getStreamSrc( $args, $querySep='&' ) {
|
public function getStreamSrc( $args=array(), $querySep='&' ) {
|
||||||
if ( $this->{'DefaultVideo'} ) {
|
if ( $this->{'DefaultVideo'} ) {
|
||||||
return ( ZM_BASE_PATH != '/' ? ZM_BASE_PATH : '' ).'/index.php?view=view_video&eid='.$this->{'Id'};
|
return ( ZM_BASE_PATH != '/' ? ZM_BASE_PATH : '' ).'/index.php?view=view_video&eid='.$this->{'Id'};
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ $GLOBALS['csrf']['rewrite-js'] = false;
|
||||||
* place it here. If you change this value, all previously generated tokens
|
* place it here. If you change this value, all previously generated tokens
|
||||||
* will become invalid.
|
* will become invalid.
|
||||||
*/
|
*/
|
||||||
$GLOBALS['csrf']['secret'] = '';
|
$GLOBALS['csrf']['secret'] = ZM_AUTH_HASH_SECRET;
|
||||||
// nota bene: library code should use csrf_get_secret() and not access
|
// nota bene: library code should use csrf_get_secret() and not access
|
||||||
// this global directly
|
// this global directly
|
||||||
|
|
||||||
|
@ -102,7 +102,7 @@ $GLOBALS['csrf']['user'] = false;
|
||||||
* tokens, and have Squid ignore that cookie for get requests, for anonymous
|
* tokens, and have Squid ignore that cookie for get requests, for anonymous
|
||||||
* users. (If you haven't guessed, this scheme was(?) used for MediaWiki).
|
* users. (If you haven't guessed, this scheme was(?) used for MediaWiki).
|
||||||
*/
|
*/
|
||||||
$GLOBALS['csrf']['key'] = false;
|
$GLOBALS['csrf']['key'] = ZM_AUTH_HASH_SECRET;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the magic CSRF token that will be placed in all forms, i.e.
|
* The name of the magic CSRF token that will be placed in all forms, i.e.
|
||||||
|
@ -188,11 +188,23 @@ function csrf_check($fatal = true) {
|
||||||
$ok = false;
|
$ok = false;
|
||||||
$tokens = '';
|
$tokens = '';
|
||||||
do {
|
do {
|
||||||
if (!isset($_POST[$name])) break;
|
if (!isset($_POST[$name])) {
|
||||||
|
Debug("POST[$name] is not set");
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
Debug("POST[$name] is set as " . $_POST[$name] );
|
||||||
|
|
||||||
|
}
|
||||||
// we don't regenerate a token and check it because some token creation
|
// we don't regenerate a token and check it because some token creation
|
||||||
// schemes are volatile.
|
// schemes are volatile.
|
||||||
$tokens = $_POST[$name];
|
$tokens = $_POST[$name];
|
||||||
if (!csrf_check_tokens($tokens)) break;
|
if (!csrf_check_tokens($tokens)) {
|
||||||
|
Debug("Failed checking tokens");
|
||||||
|
break;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Debug("Token passed");
|
||||||
|
}
|
||||||
$ok = true;
|
$ok = true;
|
||||||
} while (false);
|
} while (false);
|
||||||
if ($fatal && !$ok) {
|
if ($fatal && !$ok) {
|
||||||
|
@ -225,13 +237,13 @@ function csrf_get_tokens() {
|
||||||
csrf_start();
|
csrf_start();
|
||||||
|
|
||||||
// These are "strong" algorithms that don't require per se a secret
|
// These are "strong" algorithms that don't require per se a secret
|
||||||
|
if ($GLOBALS['csrf']['key']) return 'key:' . csrf_hash($GLOBALS['csrf']['key']) . $ip;
|
||||||
if (session_id()) return 'sid:' . csrf_hash(session_id()) . $ip;
|
if (session_id()) return 'sid:' . csrf_hash(session_id()) . $ip;
|
||||||
if ($GLOBALS['csrf']['cookie']) {
|
if ($GLOBALS['csrf']['cookie']) {
|
||||||
$val = csrf_generate_secret();
|
$val = csrf_generate_secret();
|
||||||
setcookie($GLOBALS['csrf']['cookie'], $val);
|
setcookie($GLOBALS['csrf']['cookie'], $val);
|
||||||
return 'cookie:' . csrf_hash($val) . $ip;
|
return 'cookie:' . csrf_hash($val) . $ip;
|
||||||
}
|
}
|
||||||
if ($GLOBALS['csrf']['key']) return 'key:' . csrf_hash($GLOBALS['csrf']['key']) . $ip;
|
|
||||||
// These further algorithms require a server-side secret
|
// These further algorithms require a server-side secret
|
||||||
if (!$secret) return 'invalid';
|
if (!$secret) return 'invalid';
|
||||||
if ($GLOBALS['csrf']['user'] !== false) {
|
if ($GLOBALS['csrf']['user'] !== false) {
|
||||||
|
@ -296,23 +308,40 @@ function csrf_check_tokens($tokens) {
|
||||||
* Checks if a token is valid.
|
* Checks if a token is valid.
|
||||||
*/
|
*/
|
||||||
function csrf_check_token($token) {
|
function csrf_check_token($token) {
|
||||||
if (strpos($token, ':') === false) return false;
|
Debug("Checking CSRF token $token");
|
||||||
|
if (strpos($token, ':') === false) {
|
||||||
|
Debug("Checking CSRF token $token bad because no :");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
list($type, $value) = explode(':', $token, 2);
|
list($type, $value) = explode(':', $token, 2);
|
||||||
if (strpos($value, ',') === false) return false;
|
if (strpos($value, ',') === false) {
|
||||||
|
Debug("Checking CSRF token $token bad because no ,");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
list($x, $time) = explode(',', $token, 2);
|
list($x, $time) = explode(',', $token, 2);
|
||||||
if ($GLOBALS['csrf']['expires']) {
|
if ($GLOBALS['csrf']['expires']) {
|
||||||
if (time() > $time + $GLOBALS['csrf']['expires']) return false;
|
if (time() > $time + $GLOBALS['csrf']['expires']) {
|
||||||
|
Debug("Checking CSRF token $token bad because expired");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case 'sid':
|
case 'sid':
|
||||||
|
{
|
||||||
|
Debug("Checking sid: $value === " . csrf_hash(session_id(), $time) );
|
||||||
return $value === csrf_hash(session_id(), $time);
|
return $value === csrf_hash(session_id(), $time);
|
||||||
|
}
|
||||||
case 'cookie':
|
case 'cookie':
|
||||||
$n = $GLOBALS['csrf']['cookie'];
|
$n = $GLOBALS['csrf']['cookie'];
|
||||||
if (!$n) return false;
|
if (!$n) return false;
|
||||||
if (!isset($_COOKIE[$n])) return false;
|
if (!isset($_COOKIE[$n])) return false;
|
||||||
return $value === csrf_hash($_COOKIE[$n], $time);
|
return $value === csrf_hash($_COOKIE[$n], $time);
|
||||||
case 'key':
|
case 'key':
|
||||||
if (!$GLOBALS['csrf']['key']) return false;
|
if (!$GLOBALS['csrf']['key']) {
|
||||||
|
Debug("Checking key: no key set" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Debug("Checking sid: $value === " . csrf_hash($GLOBALS['csrf']['key'], $time) );
|
||||||
return $value === csrf_hash($GLOBALS['csrf']['key'], $time);
|
return $value === csrf_hash($GLOBALS['csrf']['key'], $time);
|
||||||
// We could disable these 'weaker' checks if 'key' was set, but
|
// We could disable these 'weaker' checks if 'key' was set, but
|
||||||
// that doesn't make me feel good then about the cookie-based
|
// that doesn't make me feel good then about the cookie-based
|
||||||
|
|
|
@ -118,7 +118,7 @@ function getAuthUser( $auth ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $_SESSION['username'] ) {
|
if ( isset( $_SESSION['username'] ) ) {
|
||||||
# Most of the time we will be logged in already and the session will have our username, so we can significantly speed up our hash testing by only looking at our user.
|
# Most of the time we will be logged in already and the session will have our username, so we can significantly speed up our hash testing by only looking at our user.
|
||||||
# Only really important if you have a lot of users.
|
# Only really important if you have a lot of users.
|
||||||
$sql = "SELECT * FROM Users WHERE Enabled = 1 AND Username='".$_SESSION['username']."'";
|
$sql = "SELECT * FROM Users WHERE Enabled = 1 AND Username='".$_SESSION['username']."'";
|
||||||
|
|
|
@ -175,7 +175,9 @@ foreach ( getSkinIncludes( 'skin.php' ) as $includeFile )
|
||||||
|
|
||||||
if ( ZM_OPT_USE_AUTH && ZM_AUTH_HASH_LOGINS ) {
|
if ( ZM_OPT_USE_AUTH && ZM_AUTH_HASH_LOGINS ) {
|
||||||
if ( empty($user) && ! empty($_REQUEST['auth']) ) {
|
if ( empty($user) && ! empty($_REQUEST['auth']) ) {
|
||||||
|
Debug("Getting user from auth hash");
|
||||||
if ( $authUser = getAuthUser( $_REQUEST['auth'] ) ) {
|
if ( $authUser = getAuthUser( $_REQUEST['auth'] ) ) {
|
||||||
|
Debug("Success Getting user from auth hash");
|
||||||
userLogin( $authUser['Username'], $authUser['Password'], true );
|
userLogin( $authUser['Username'], $authUser['Password'], true );
|
||||||
}
|
}
|
||||||
} else if ( ! empty($user) ) {
|
} else if ( ! empty($user) ) {
|
||||||
|
@ -206,6 +208,7 @@ require_once( 'includes/actions.php' );
|
||||||
|
|
||||||
# If I put this here, it protects all views and popups, but it has to go after actions.php because actions.php does the actual logging in.
|
# If I put this here, it protects all views and popups, but it has to go after actions.php because actions.php does the actual logging in.
|
||||||
if ( ZM_OPT_USE_AUTH && ! isset($user) ) {
|
if ( ZM_OPT_USE_AUTH && ! isset($user) ) {
|
||||||
|
Debug("Redirecting to login" );
|
||||||
$view = 'login';
|
$view = 'login';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -80,8 +80,8 @@
|
||||||
border: 1px solid #006699;
|
border: 1px solid #006699;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
width: 100px;
|
width: 102px;
|
||||||
height: 100px;
|
height: 102px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ptzControls .controlsPanel .pantiltPanel .pantiltControls .arrowBtn {
|
.ptzControls .controlsPanel .pantiltPanel .pantiltControls .arrowBtn {
|
||||||
|
|
|
@ -80,8 +80,8 @@
|
||||||
border: 1px solid #006699;
|
border: 1px solid #006699;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 1px;
|
padding: 1px;
|
||||||
width: 100px;
|
width: 102px;
|
||||||
height: 100px;
|
height: 102px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ptzControls .controlsPanel .pantiltPanel .pantiltControls .arrowBtn {
|
.ptzControls .controlsPanel .pantiltPanel .pantiltControls .arrowBtn {
|
||||||
|
|
|
@ -98,10 +98,10 @@ var $j = jQuery.noConflict();
|
||||||
<script src='https://www.google.com/recaptcha/api.js'></script>
|
<script src='https://www.google.com/recaptcha/api.js'></script>
|
||||||
<?php } else if ( $title == 'Event' ) {
|
<?php } else if ( $title == 'Event' ) {
|
||||||
?>
|
?>
|
||||||
<link href="skins/<?php echo $skin; ?>/js/video-js.css" rel="stylesheet">
|
<link href="skins/<?php echo $skin ?>/js/video-js.css" rel="stylesheet">
|
||||||
<script src="skins/<?php echo $skin; ?>/js/video.js"></script>
|
<script src="skins/<?php echo $skin ?>/js/video.js"></script>
|
||||||
<script src="./js/videojs.zoomrotate.js"></script>
|
<script src="./js/videojs.zoomrotate.js"></script>
|
||||||
<script src="skins/<?php echo $skin; ?>/js/moment.min.js"></script>
|
<script src="skins/<?php echo $skin ?>/js/moment.min.js"></script>
|
||||||
<?php
|
<?php
|
||||||
}
|
}
|
||||||
if ( $skinJsPhpFile )
|
if ( $skinJsPhpFile )
|
||||||
|
|
|
@ -127,7 +127,10 @@ if ( canEdit( 'Events' ) ) {
|
||||||
<div id="editEvent"><a href="#" onclick="editEvent()"><?php echo translate('Edit') ?></a></div>
|
<div id="editEvent"><a href="#" onclick="editEvent()"><?php echo translate('Edit') ?></a></div>
|
||||||
<div id="archiveEvent" class="hidden"><a href="#" onclick="archiveEvent()"><?php echo translate('Archive') ?></a></div>
|
<div id="archiveEvent" class="hidden"><a href="#" onclick="archiveEvent()"><?php echo translate('Archive') ?></a></div>
|
||||||
<div id="unarchiveEvent" class="hidden"><a href="#" onclick="unarchiveEvent()"><?php echo translate('Unarchive') ?></a></div>
|
<div id="unarchiveEvent" class="hidden"><a href="#" onclick="unarchiveEvent()"><?php echo translate('Unarchive') ?></a></div>
|
||||||
|
<?php if ( $Event->DefaultVideo() ) { ?>
|
||||||
|
<div id="downloadEventFile"><a href="<?php echo $Event->getStreamSrc()?>">Download MP4</a></div>
|
||||||
<?php
|
<?php
|
||||||
|
} // end if Event->DefaultVideo
|
||||||
} // end if can edit Events
|
} // end if can edit Events
|
||||||
if ( canView( 'Events' ) ) {
|
if ( canView( 'Events' ) ) {
|
||||||
?>
|
?>
|
||||||
|
@ -139,8 +142,8 @@ if ( $Event->SaveJPEGs() & 3 ) { // Analysis or Jpegs
|
||||||
<?php
|
<?php
|
||||||
} // has frames or analysis
|
} // has frames or analysis
|
||||||
?>
|
?>
|
||||||
<div id="videoEvent"<?php if ( $streamMode == 'video' ) { ?> class="hidden"<?php } ?>><a href="#" onclick="showVideo()"><?php echo translate('Video') ?></a></div>
|
<div id="videoEvent"><a href="#" onclick="videoEvent();"><?php echo translate('Video') ?></a></div>
|
||||||
<div id="exportEvent"><a href="#" onclick="exportEvent()"><?php echo translate('Export') ?></a></div>
|
<div id="exportEvent"><a href="#" onclick="exportEvent();"><?php echo translate('Export') ?></a></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="eventVideo" class="">
|
<div id="eventVideo" class="">
|
||||||
<?php
|
<?php
|
||||||
|
|
|
@ -701,6 +701,11 @@ function showFrameStats()
|
||||||
createPopup( '?view=stats&eid='+eventData.Id+'&fid='+fid, 'zmStats', 'stats', eventData.Width, eventData.Height );
|
createPopup( '?view=stats&eid='+eventData.Id+'&fid='+fid, 'zmStats', 'stats', eventData.Width, eventData.Height );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function videoEvent()
|
||||||
|
{
|
||||||
|
createPopup( '?view=video&eid='+eventData.Id, 'zmVideo', 'video', eventData.Width, eventData.Height );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function drawProgressBar()
|
function drawProgressBar()
|
||||||
{
|
{
|
||||||
|
|
|
@ -330,19 +330,23 @@ function streamCmdQuery() {
|
||||||
var statusCmdParms = "view=request&request=status&entity=monitor&id="+monitorId+"&element[]=Status&element[]=FrameRate";
|
var statusCmdParms = "view=request&request=status&entity=monitor&id="+monitorId+"&element[]=Status&element[]=FrameRate";
|
||||||
if ( auth_hash )
|
if ( auth_hash )
|
||||||
statusCmdParms += '&auth='+auth_hash;
|
statusCmdParms += '&auth='+auth_hash;
|
||||||
var statusCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'post', data: statusCmdParms, timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStatusCmdResponse } );
|
var statusCmdReq = new Request.JSON( { url: monitorUrl+thisUrl, method: 'get', data: statusCmdParms, timeout: AJAX_TIMEOUT, link: 'cancel', onSuccess: getStatusCmdResponse } );
|
||||||
var statusCmdTimer = null;
|
var statusCmdTimer = null;
|
||||||
|
|
||||||
function getStatusCmdResponse( respObj, respText ) {
|
function getStatusCmdResponse( respObj, respText ) {
|
||||||
|
console.log("Got statusCmdQuery");
|
||||||
watchdogOk("status");
|
watchdogOk("status");
|
||||||
if ( statusCmdTimer )
|
if ( statusCmdTimer )
|
||||||
statusCmdTimer = clearTimeout( statusCmdTimer );
|
statusCmdTimer = clearTimeout( statusCmdTimer );
|
||||||
|
|
||||||
if ( respObj.result == 'Ok' ) {
|
if ( respObj.result == 'Ok' ) {
|
||||||
|
console.log("Got ok for status");
|
||||||
$('fpsValue').set( 'text', respObj.monitor.FrameRate );
|
$('fpsValue').set( 'text', respObj.monitor.FrameRate );
|
||||||
setAlarmState( respObj.monitor.Status );
|
setAlarmState( respObj.monitor.Status );
|
||||||
} else
|
} else {
|
||||||
|
console.log("Got bad response for status");
|
||||||
checkStreamForErrors("getStatusCmdResponse",respObj);
|
checkStreamForErrors("getStatusCmdResponse",respObj);
|
||||||
|
}
|
||||||
|
|
||||||
var statusCmdTimeout = statusRefreshTimeout;
|
var statusCmdTimeout = statusRefreshTimeout;
|
||||||
if ( alarmState == STATE_ALARM || alarmState == STATE_ALERT )
|
if ( alarmState == STATE_ALARM || alarmState == STATE_ALERT )
|
||||||
|
@ -351,6 +355,7 @@ function getStatusCmdResponse( respObj, respText ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function statusCmdQuery() {
|
function statusCmdQuery() {
|
||||||
|
console.log("Sending statusCmdQuery");
|
||||||
statusCmdReq.send();
|
statusCmdReq.send();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue