From 7ef9cf42311a6a12e09709953cf619ecefac02ce Mon Sep 17 00:00:00 2001 From: Andrew Bauer Date: Thu, 13 Sep 2018 20:13:06 -0500 Subject: [PATCH 01/10] typo --- utils/packpack/startpackpack.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/packpack/startpackpack.sh b/utils/packpack/startpackpack.sh index 3ed227a44..677fa1f32 100755 --- a/utils/packpack/startpackpack.sh +++ b/utils/packpack/startpackpack.sh @@ -154,7 +154,7 @@ movecrud () { echo "Unpacking CakePHP-Enum-Behavior plugin..." tar -xzf build/cakephp-enum-behavior-${CEBVER}.tar.gz rmdir web/api/app/Plugin/CakePHP-Enum-Behavior - mv -f crud-${CEBVER} web/api/app/Plugin/CakePHP-Enum-Behavior + mv -f CakePHP-Enum-Behavior-${CEBVER} web/api/app/Plugin/CakePHP-Enum-Behavior fi } From 63bed3af109282ce36fb5cbf2bf4d23a07806825 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 14 Sep 2018 09:23:09 -0400 Subject: [PATCH 02/10] replace all uses of getEventPath with object function event->Path(). Remove getEventPath --- scripts/ZoneMinder/lib/ZoneMinder/General.pm | 14 -------------- scripts/zmfilter.pl.in | 4 ++-- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/General.pm b/scripts/ZoneMinder/lib/ZoneMinder/General.pm index c91511869..02764b778 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/General.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/General.pm @@ -47,7 +47,6 @@ our %EXPORT_TAGS = ( getCmdFormat runCommand setFileOwner - getEventPath createEventPath createEvent deleteEventFiles @@ -181,19 +180,6 @@ sub runCommand { return( $output ); } -sub getEventPath { - my $event = shift; - - my $Storage = new ZoneMinder::Storage( $$event{StorageId} ); - my $event_path = join( '/', - $Storage->Path(), - $event->{MonitorId}, - ( $Config{ZM_USE_DEEP_STORAGE} ? strftime( "%y/%m/%d/%H/%M/%S", localtime($event->{Time}) ) : $event->{Id} ), - ); - - return( $event_path ); -} - sub createEventPath { # # WARNING assumes running from events directory diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index 0d76cbd97..7e0c0a10f 100644 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -475,7 +475,7 @@ sub uploadArchFile { } my $archFile = $event->{MonitorName}.'-'.$event->{Id}; - my $archImagePath = getEventPath($event) + my $archImagePath = $event->Path(); .'/' .( ( $Config{ZM_UPLOAD_ARCH_ANALYSE} ) @@ -951,7 +951,7 @@ sub executeCommand { my $filter = shift; my $event = shift; - my $event_path = getEventPath($event); + my $event_path = $event->Path(); my $command = $filter->{AutoExecuteCmd}; $command .= " $event_path"; From 11137d271e4a5ef6fef0a9b1e0ea9944856f247c Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 14 Sep 2018 10:06:36 -0400 Subject: [PATCH 03/10] Create utility functions in event for creating linkPath and idPath. Replace the code in Generate::createEventPath with using these nice new functions --- scripts/ZoneMinder/lib/ZoneMinder/Event.pm | 21 ++++++++ scripts/ZoneMinder/lib/ZoneMinder/General.pm | 53 ++------------------ 2 files changed, 26 insertions(+), 48 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm index 8eca805aa..a8a38fc65 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm @@ -254,6 +254,27 @@ sub LinkPath { return $$event{LinkPath}; } # end sub LinkPath +sub createPath { + makePath($_[0]->Path()); +} + +sub createLinkPath { + makePath($_[0]->LinkPath()); +} + +sub idPath { + return sprintf('%s/.%d', $event->Path(), $event->{Id}); +} + +sub createIdPath { + my $event = shift; + my $idFile = $event->idPath(); + open( my $ID_FP, '>', $idFile ) + or Error("Can't open $idFile: $!"); + close($ID_FP); + setFileOwner($idFile); +} + sub GenerateVideo { my ( $self, $rate, $fps, $scale, $size, $overwrite, $format ) = @_; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/General.pm b/scripts/ZoneMinder/lib/ZoneMinder/General.pm index 02764b778..36e65f332 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/General.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/General.pm @@ -181,56 +181,13 @@ sub runCommand { } sub createEventPath { -# -# WARNING assumes running from events directory -# my $event = shift; - my $Storage = new ZoneMinder::Storage( $$event{Id} ); - my $eventPath = $Storage->Path() . '/'.$event->{MonitorId}; + my $eventPath = $event->Path(); + $event->createPath(); + $event->createIdFile(); + $event->createLinkPath(); - if ( $Config{ZM_USE_DEEP_STORAGE} ) { - my @startTime = localtime( $event->{StartTime} ); - - my @datetimeParts = (); - $datetimeParts[0] = sprintf( "%02d", $startTime[5]-100 ); - $datetimeParts[1] = sprintf( "%02d", $startTime[4]+1 ); - $datetimeParts[2] = sprintf( "%02d", $startTime[3] ); - $datetimeParts[3] = sprintf( "%02d", $startTime[2] ); - $datetimeParts[4] = sprintf( "%02d", $startTime[1] ); - $datetimeParts[5] = sprintf( "%02d", $startTime[0] ); - - my $datePath = join('/',@datetimeParts[0..2]); - my $timePath = join('/',@datetimeParts[3..5]); - - makePath( $datePath, $eventPath ); - $eventPath .= '/'.$datePath; - -# Create event id symlink - my $idFile = sprintf( "%s/.%d", $eventPath, $event->{Id} ); - symlink( $timePath, $idFile ) - or Fatal( "Can't symlink $idFile -> $eventPath: $!" ); - - makePath( $timePath, $eventPath ); - $eventPath .= '/'.$timePath; - setFileOwner( $idFile ); # Must come after directory has been created - -# Create empty id tag file - $idFile = sprintf( "%s/.%d", $eventPath, $event->{Id} ); - open( my $ID_FP, ">", $idFile ) - or Fatal( "Can't open $idFile: $!" ); - close( $ID_FP ); - setFileOwner( $idFile ); - } else { - makePath( $event->{Id}, $eventPath ); - $eventPath .= '/'.$event->{Id}; - - my $idFile = sprintf( "%s/.%d", $eventPath, $event->{Id} ); - open( my $ID_FP, ">", $idFile ) - or Fatal( "Can't open $idFile: $!" ); - close( $ID_FP ); - setFileOwner( $idFile ); - } - return( $eventPath ); + return $eventPath; } use Data::Dumper; From ca3fd5ddf8ed4a911d2d4e268e361b0a59b62f36 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 14 Sep 2018 10:08:35 -0400 Subject: [PATCH 04/10] get rid of deleteEventFiles function. People should use the object method --- scripts/ZoneMinder/lib/ZoneMinder/General.pm | 48 -------------------- 1 file changed, 48 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/General.pm b/scripts/ZoneMinder/lib/ZoneMinder/General.pm index 36e65f332..1dc9291f5 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/General.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/General.pm @@ -49,7 +49,6 @@ our %EXPORT_TAGS = ( setFileOwner createEventPath createEvent - deleteEventFiles makePath jsonEncode jsonDecode @@ -424,53 +423,6 @@ sub updateEvent { or Fatal( "Can't execute sql '$sql': ".$sth->errstr() ); } -sub deleteEventFiles { -# -# WARNING assumes running from events directory -# - my $event_id = shift; - my $monitor_id = shift; - $monitor_id = '*' if ( !defined($monitor_id) ); - - if ( $Config{ZM_USE_DEEP_STORAGE} ) { - my $link_path = $monitor_id."/*/*/*/.".$event_id; -#Debug( "LP1:$link_path" ); - my @links = glob($link_path); -#Debug( "L:".$links[0].": $!" ); - if ( @links ) { - ( $link_path ) = ( $links[0] =~ /^(.*)$/ ); # De-taint -#Debug( "LP2:$link_path" ); - - ( my $day_path = $link_path ) =~ s/\.\d+//; -#Debug( "DP:$day_path" ); - my $event_path = $day_path.readlink( $link_path ); - ( $event_path ) = ( $event_path =~ /^(.*)$/ ); # De-taint -#Debug( "EP:$event_path" ); - my $command = "/bin/rm -rf ".$event_path; -#Debug( "C:$command" ); - executeShellCommand( $command ); - - unlink( $link_path ) or Error( "Unable to unlink '$link_path': $!" ); - my @path_parts = split( /\//, $event_path ); - for ( my $i = int(@path_parts)-2; $i >= 1; $i-- ) { - my $delete_path = join( '/', @path_parts[0..$i] ); -#Debug( "DP$i:$delete_path" ); - my @has_files = glob( $delete_path."/*" ); -#Debug( "HF1:".$has_files[0] ) if ( @has_files ); - last if ( @has_files ); - @has_files = glob( $delete_path."/.[0-9]*" ); -#Debug( "HF2:".$has_files[0] ) if ( @has_files ); - last if ( @has_files ); - my $command = "/bin/rm -rf ".$delete_path; - executeShellCommand( $command ); - } - } - } else { - my $command = "/bin/rm -rf $monitor_id/$event_id"; - executeShellCommand( $command ); - } -} - sub makePath { my $path = shift; my $root = shift; From 4528a043c5b88052b3f79fccb2ba8e4482c642a6 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 14 Sep 2018 11:04:52 -0400 Subject: [PATCH 05/10] fixtypo --- scripts/zmfilter.pl.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/zmfilter.pl.in b/scripts/zmfilter.pl.in index 7e0c0a10f..6277469b6 100644 --- a/scripts/zmfilter.pl.in +++ b/scripts/zmfilter.pl.in @@ -475,7 +475,7 @@ sub uploadArchFile { } my $archFile = $event->{MonitorName}.'-'.$event->{Id}; - my $archImagePath = $event->Path(); + my $archImagePath = $event->Path() .'/' .( ( $Config{ZM_UPLOAD_ARCH_ANALYSE} ) From f2a117c85bb7eeebf8edd676e73dafa7035f434f Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 14 Sep 2018 11:06:08 -0400 Subject: [PATCH 06/10] fix undefined $event --- scripts/ZoneMinder/lib/ZoneMinder/Event.pm | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm index a8a38fc65..71986ad05 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Event.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Event.pm @@ -259,14 +259,20 @@ sub createPath { } sub createLinkPath { - makePath($_[0]->LinkPath()); + my $LinkPath = $_[0]->LinkPath(); + my $EventPath = $_[0]->EventPath(); + if ( $LinkPath ) { + if ( !symlink($EventPath, $LinkPath) ) { + Error("Failed symlinking $EventPath to $LinkPath"); + } + } } sub idPath { - return sprintf('%s/.%d', $event->Path(), $event->{Id}); + return sprintf('%s/.%d', $_[0]->Path(), $_[0]->{Id}); } -sub createIdPath { +sub createIdFile { my $event = shift; my $idFile = $event->idPath(); open( my $ID_FP, '>', $idFile ) From 0e2fdf4a1c4723372e4e296ad3558cd3279b6b35 Mon Sep 17 00:00:00 2001 From: Pliable Pixels Date: Fri, 14 Sep 2018 11:48:22 -0400 Subject: [PATCH 07/10] fixed path for login/logout api --- docs/api.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index a5bdd35f3..942d701e2 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -29,13 +29,13 @@ This means if you plan to use cuRL to experiment with these APIs, you first need :: - curl -XPOST -d "user=XXXX&pass=YYYY" -c cookies.txt http://yourzmip/zm/api/login.json + curl -XPOST -d "user=XXXX&pass=YYYY" -c cookies.txt http://yourzmip/zm/api/host/login.json Staring ZM 1.32.0, you also have a `logout` API that basically clears your session. It looks like this: :: - curl -b cookies.txt http://yourzmip/zm/api/logout.json + curl -b cookies.txt http://yourzmip/zm/api/host/logout.json **Login process for older versions of ZoneMinder** From b5b71edbf64a4b46fc49b39038703e507c2038b1 Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 14 Sep 2018 14:26:45 -0400 Subject: [PATCH 08/10] Make a Url function in the Monitor object to use the Server->Url + Port. Default to port used in current url. Fixes problems with using something other than port 80 --- web/includes/Monitor.php | 11 +++++++++-- web/skins/classic/views/js/montage.js.php | 2 +- web/skins/classic/views/js/watch.js.php | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/web/includes/Monitor.php b/web/includes/Monitor.php index f6ceca734..1ad2df517 100644 --- a/web/includes/Monitor.php +++ b/web/includes/Monitor.php @@ -510,8 +510,12 @@ private $control_fields = array( $source = preg_replace( '/^.*\//', '', $this->{'Path'} ); } elseif ( $this->{'Type'} == 'Ffmpeg' || $this->{'Type'} == 'Libvlc' || $this->{'Type'} == 'WebSite' ) { $url_parts = parse_url( $this->{'Path'} ); - if ( ZM_WEB_FILTER_SOURCE == "Hostname" ) { # Filter out everything but the hostname - $source = $url_parts['host']; + if ( ZM_WEB_FILTER_SOURCE == 'Hostname' ) { # Filter out everything but the hostname + if ( isset($url_parts['host']) ) { + $source = $url_parts['host']; + } else { + $source = $this->{'Path'}; + } } elseif ( ZM_WEB_FILTER_SOURCE == "NoCredentials" ) { # Filter out sensitive and common items unset($url_parts['user']); unset($url_parts['pass']); @@ -531,6 +535,9 @@ private $control_fields = array( return $source; } // end function Source + public function Url() { + return $this->Server()->Url() .':'. ( ZM_MIN_STREAMING_PORT ? (ZM_MIN_STREAMING_PORT+$this->Id()) : $_SERVER['SERVER_PORT'] ); + } } // end class Monitor ?> diff --git a/web/skins/classic/views/js/montage.js.php b/web/skins/classic/views/js/montage.js.php index 1b67d764b..3b0c5005b 100644 --- a/web/skins/classic/views/js/montage.js.php +++ b/web/skins/classic/views/js/montage.js.php @@ -35,7 +35,7 @@ monitorData[monitorData.length] = { 'connKey': connKey() ?>, 'width': Width() ?>, 'height':Height() ?>, - 'server_url': 'Server()->Url().$_SERVER['PHP_SELF'] ?>', + 'server_url': 'Url() ?>', 'onclick': function(){createPopup( '?view=watch&mid=Id() ?>', 'zmWatchId() ?>', 'watch', Width(), $monitor->PopupScale() ); ?>, Height(), $monitor->PopupScale() ); ?> );}, 'type': 'Type() ?>', 'refresh': 'Refresh() ?>' diff --git a/web/skins/classic/views/js/watch.js.php b/web/skins/classic/views/js/watch.js.php index c446703cf..51c1801e8 100644 --- a/web/skins/classic/views/js/watch.js.php +++ b/web/skins/classic/views/js/watch.js.php @@ -48,7 +48,7 @@ var maxDisplayEvents = ; var monitorId = Id() ?>; var monitorWidth = Width() ?>; var monitorHeight = Height() ?>; -var monitorUrl = 'Server()->Url() . ( ZM_MIN_STREAMING_PORT ? ':'. (ZM_MIN_STREAMING_PORT+$monitor->Id()) : '' ) ) ?>'; +var monitorUrl = 'Url(); ?>'; var monitorType = 'Type() ) ?>'; var monitorRefresh = 'Refresh() ) ?>'; From d9b1d3ec1189d9a36d6d68cad4c74b89dbd1b69d Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 14 Sep 2018 14:52:33 -0400 Subject: [PATCH 09/10] fix CORS Headers when we are coming from a non-standard port. Use a regexp instead of == so that we match regardless of port --- web/includes/functions.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/web/includes/functions.php b/web/includes/functions.php index 09a86c03c..744cf0bdb 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -36,20 +36,20 @@ function noCacheHeaders() { } function CORSHeaders() { - if ( isset( $_SERVER['HTTP_ORIGIN'] ) ) { + if ( isset($_SERVER['HTTP_ORIGIN']) ) { # The following is left for future reference/use. $valid = false; - $servers = dbFetchAll( 'SELECT * FROM Servers' ); + $servers = dbFetchAll('SELECT * FROM Servers'); if ( sizeof($servers) <= 1 ) { # Only need CORSHeaders in the event that there are multiple servers in use. return; } foreach( $servers as $row ) { - $Server = new Server( $row ); - if ( $_SERVER['HTTP_ORIGIN'] == $Server->Url() ) { + $Server = new Server($row); + if ( preg_match('/^'.preg_quote($Server->Url(),'/').'/', $_SERVER['HTTP_ORIGIN']) ) { $valid = true; - header('Access-Control-Allow-Origin: ' . $Server->Url() ); + header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Headers: x-requested-with,x-request'); } } From f1442eba9094e529fc70b61d4ff1cd3b952efb1e Mon Sep 17 00:00:00 2001 From: Isaac Connor Date: Fri, 14 Sep 2018 14:56:26 -0400 Subject: [PATCH 10/10] once we have found a match for our origin, break out of loop --- web/includes/functions.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/web/includes/functions.php b/web/includes/functions.php index 744cf0bdb..e66139d7c 100644 --- a/web/includes/functions.php +++ b/web/includes/functions.php @@ -51,10 +51,11 @@ function CORSHeaders() { $valid = true; header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']); header('Access-Control-Allow-Headers: x-requested-with,x-request'); + break; } } - if ( ! $valid ) { - Warning( $_SERVER['HTTP_ORIGIN'] . ' is not found in servers list.' ); + if ( !$valid ) { + Warning($_SERVER['HTTP_ORIGIN'] . ' is not found in servers list.'); } } }