diff --git a/.well-known/funding-manifest-urls b/.well-known/funding-manifest-urls new file mode 100644 index 000000000..50f929574 --- /dev/null +++ b/.well-known/funding-manifest-urls @@ -0,0 +1 @@ +https://zoneminder.com/funding.json diff --git a/db/zm_update-1.37.27.sql b/db/zm_update-1.37.27.sql index 6993e36f4..cb1cb049b 100644 --- a/db/zm_update-1.37.27.sql +++ b/db/zm_update-1.37.27.sql @@ -112,13 +112,34 @@ SET @s = (SELECT IF( PREPARE stmt FROM @s; EXECUTE stmt; -REPLACE INTO Monitors_Permissions (UserId,Permission, MonitorId) +SET @s = (SELECT IF( + (SELECT COUNT(*) + FROM INFORMATION_SCHEMA.STATISTICS + WHERE table_name = 'Users' + AND table_schema = DATABASE() + AND column_name = 'MonitorIds' + ) > 0, +"REPLACE INTO Monitors_Permissions (UserId,Permission, MonitorId) SELECT Id, 'Edit', SUBSTRING_INDEX(SUBSTRING_INDEX(Users.MonitorIds, ',', n.n), ',', -1) value FROM Users CROSS JOIN ( - SELECT a.N + b.N * 10 + 1 n FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b ORDER BY n ) n WHERE Users.Monitors='Edit' and Users.MonitorIds != '' AND n.n <= 1 + (LENGTH(Users.MonitorIds) - LENGTH(REPLACE(Users.MonitorIds, ',', ''))) ORDER BY value; + SELECT a.N + b.N * 10 + 1 n FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b ORDER BY n ) n WHERE Users.Monitors='Edit' and Users.MonitorIds != '' AND n.n <= 1 + (LENGTH(Users.MonitorIds) - LENGTH(REPLACE(Users.MonitorIds, ',', ''))) ORDER BY value", + "SELECT 'No MonitorIds in Users'" + )); +PREPARE stmt FROM @s; +EXECUTE stmt; -REPLACE INTO Monitors_Permissions (UserId,Permission, MonitorId) +SET @s = (SELECT IF( + (SELECT COUNT(*) + FROM INFORMATION_SCHEMA.STATISTICS + WHERE table_name = 'Users' + AND table_schema = DATABASE() + AND column_name = 'MonitorIds' + ) > 0, +"REPLACE INTO Monitors_Permissions (UserId,Permission, MonitorId) SELECT Id, 'View', SUBSTRING_INDEX(SUBSTRING_INDEX(Users.MonitorIds, ',', n.n), ',', -1) value FROM Users CROSS JOIN ( - SELECT a.N + b.N * 10 + 1 n FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b ORDER BY n ) n WHERE Users.Monitors!='Edit' and Users.MonitorIds != '' AND n.n <= 1 + (LENGTH(Users.MonitorIds) - LENGTH(REPLACE(Users.MonitorIds, ',', ''))) ORDER BY value; - + SELECT a.N + b.N * 10 + 1 n FROM (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b ORDER BY n ) n WHERE Users.Monitors!='Edit' and Users.MonitorIds != '' AND n.n <= 1 + (LENGTH(Users.MonitorIds) - LENGTH(REPLACE(Users.MonitorIds, ',', ''))) ORDER BY value", + "SELECT 'No MonitorIds in Users'" + )); +PREPARE stmt FROM @s; +EXECUTE stmt; DELETE FROM Monitors_Permissions WHERE MonitorID NOT IN (SELECT Id FROM Monitors); ALTER TABLE Monitors_Permissions ADD CONSTRAINT Monitors_Permissions_ibfk_1 FOREIGN KEY (`MonitorId`) REFERENCES `Monitors` (`Id`) ON DELETE CASCADE; diff --git a/funding.json b/funding.json new file mode 100644 index 000000000..5b840a677 --- /dev/null +++ b/funding.json @@ -0,0 +1,70 @@ +{ + "version": "v1.0.0", + "entity": { + "type": "organisation", + "role": "owner", + "name": "ZoneMinder Inc", + "email": "isaac@zoneminder.com", + "phone": "16478835483", + "description": "A Canadian corporation to hold and maintain the assets relating to the ZoneMinder CCTV project.", + "webpageUrl": { + "url": "https://www.zoneminder.com", + "wellKnown": "https://www.zoneminder.com/.well-known/funding-manifest-urls" + } + }, + "projects": [ + { + "guid": "zoneminder", + "name": "ZoneMinder", + "description": "A full-featured, open source, state-of-the-art video surveillance software system.", + "webpageUrl": { + "url": "https://www.zoneminder.com", + "wellKnown": "https://www.zoneminder.com/.well-known/funding-manifest-urls" + }, + "repositoryUrl": { + "url": "https://github.com/zoneminder/zoneminder", + "wellKnown": "https://github.com/zoneminder/zoneminder/blob/master/.well-known/funding-manifest-urls" + }, + "licenses": [ + "GPL-v2" + ], + "tags": [ + "video", + "security", + "cameras" + ] + } + ], + "funding": { + "channels": [ + { + "guid": "bank", + "type": "bank", + "address": "Account: 5212751 Transit No: 29842 Institution: 004", + "description": "" + }, + { + "guid": "paypal", + "type": "payment-provider", + "address": "paypal@zoneminder.com", + "description": "" + } + ], + "plans": [ + { + "guid": "myplan", + "status": "active", + "name": "Infrastructure costs, support, development", + "description": "Not really sure this plan part is about.", + "amount": 10000, + "currency": "USD", + "frequency": "yearly", + "channels": [ + "bank", + "paypal" + ] + } + ], + "history": [] + } +} diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control.pm index 0a12b4dba..a7c956bb7 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control.pm @@ -398,7 +398,7 @@ sub get_realm { if ( $$self{realm} ne $tokens{realm} ) { $$self{realm} = $tokens{realm}; Debug("Changing REALM to $$self{realm}, $$self{host}:$$self{port}, $$self{realm}, $$self{username}, $$self{password}"); - $self->{ua}->credentials("$$self{host}:$$self{port}", $$self{realm}, $$self{username}, $$self{password}); + $self->{ua}->credentials($$self{address}?$$self{address}:"$$self{host}:$$self{port}", $$self{realm}, $$self{username}, $$self{password}); $response = $self->get($url); if ( !$response->is_success() ) { Debug('Authentication still failed after updating REALM' . $response->status_line); @@ -417,9 +417,10 @@ sub get_realm { } # end if } # end foreach auth header } else { - debug('No headers line'); + Debug('No headers line'); } # end if headers } # end if not authen + return undef; } # end sub get_realm 1; diff --git a/scripts/ZoneMinder/lib/ZoneMinder/Control/Amcrest_HTTP.pm b/scripts/ZoneMinder/lib/ZoneMinder/Control/Amcrest_HTTP.pm index 6643694dc..0a8ea83f1 100644 --- a/scripts/ZoneMinder/lib/ZoneMinder/Control/Amcrest_HTTP.pm +++ b/scripts/ZoneMinder/lib/ZoneMinder/Control/Amcrest_HTTP.pm @@ -59,9 +59,9 @@ sub open { if ($self->{Monitor}->{ControlAddress} and - $self->{Monitor}{ControlAddress} ne 'user:pass@ip' + $self->{Monitor}->{ControlAddress} ne 'user:pass@ip' and - $self->{Monitor}{ControlAddress} ne 'user:port@ip' + $self->{Monitor}->{ControlAddress} ne 'user:port@ip' ) { if ( $self->{Monitor}->{ControlAddress} !~ /^\w+:\/\// ) { @@ -70,7 +70,7 @@ sub open { } my $uri = URI->new($self->{Monitor}->{ControlAddress}); - $$self{realm} = 'Login to ' . $self->{Monitor}->{ControlDevice}; + $$self{realm} = 'Login to ' . $self->{Monitor}->{ControlDevice} if $self->{Monitor}->{ControlDevice}; if ($self->{Monitor}->{ControlAddress}) { if ( $uri->userinfo()) { @$self{'username', 'password'} = $uri->userinfo() =~ /^(.*):(.*)$/; @@ -85,8 +85,8 @@ sub open { $$self{base_url} = $uri->canonical(); Debug('Using initial credentials for '.$uri->host_port().join(',', '', @$self{'realm', 'username', 'password'}).", base_url: $$self{base_url} auth:".$uri->authority()); } - } elsif ( $self->{Monitor}{Path}) { - my $uri = URI->new($self->{Monitor}{Path}); + } elsif ( $self->{Monitor}->{Path}) { + my $uri = URI->new($self->{Monitor}->{Path}); Debug("Using Path for credentials: $self->{Monitor}{Path} " . $uri->userinfo()); if ( $uri->userinfo()) { @$self{'username', 'password'} = $uri->userinfo() =~ /^(.*):(.*)$/; @@ -102,7 +102,7 @@ sub open { $$self{base_url} = $uri->canonical(); $$self{address} = $uri->host_port(); Debug("User auth $$self{username} $$self{password} " . $uri->authority() . ' ' . $uri->host_port()); - $self->{ua}->credentials($uri->host_port(), @$self{'realm', 'username', 'password'); + $self->{ua}->credentials($uri->host_port(), @$self{'realm', 'username', 'password'}); chomp $$self{base_url}; Debug("Base_url is ".$$self{base_url}); } else { @@ -111,14 +111,10 @@ sub open { my $url = $$self{base_url}.'cgi-bin/magicBox.cgi?action=getDeviceType'; # Detect REALM, has to be /cgi-bin/ptz.cgi because just / accepts no auth - my $res = $self->get_realm($url); - - if ( $res->is_success ) { + if ($self->get_realm($url)) { $self->{state} = 'open'; return !undef; - } else { - Error("Failed to get $url ".$res->status_line()); - } # end if $res->status_line() eq '401 Unauthorized' + } $self->{state} = 'closed'; return undef; diff --git a/src/zmc.cpp b/src/zmc.cpp index 432e8ec4e..faa93a648 100644 --- a/src/zmc.cpp +++ b/src/zmc.cpp @@ -246,10 +246,12 @@ int main(int argc, char *argv[]) { monitor->LoadCamera(); - while (!monitor->connect()) { + while (!monitor->connect() and !zm_terminate) { Warning("Couldn't connect to monitor %d", monitor->Id()); sleep(1); } + if (zm_terminate) break; + SystemTimePoint now = std::chrono::system_clock::now(); monitor->SetStartupTime(now);