Update to use Control:: methods instead of our own duplicates

This commit is contained in:
Isaac Connor
2025-11-07 16:23:01 -05:00
parent dcc2779882
commit 9c9a2dcb0b

View File

@@ -17,127 +17,28 @@ our @ISA = qw(ZoneMinder::Control);
# can set them here if you want.
#
our $REALM = '';
our $PROTOCOL = 'http://';
our $USERNAME = 'admin';
our $PASSWORD = '';
our $ADDRESS = '';
use ZoneMinder::Logger qw(:all);
use ZoneMinder::Config qw(:all);
use URI;
use LWP::UserAgent;
sub credentials {
my $self = shift;
($USERNAME, $PASSWORD) = @_;
Debug("Setting credentials to $USERNAME/$PASSWORD");
}
sub open {
my $self = shift;
$self->loadMonitor();
if ($self->{Monitor}{ControlAddress}
and
$self->{Monitor}{ControlAddress} ne 'user:pass@ip'
and
$self->{Monitor}{ControlAddress} ne 'user:port@ip'
and
($self->{Monitor}->{ControlAddress} =~ /^(?<PROTOCOL>https?:\/\/)?(?<USERNAME>[^:@]+)?:?(?<PASSWORD>[^\/@]+)?@?(?<ADDRESS>.*)$/)
) {
$PROTOCOL = $+{PROTOCOL} if $+{PROTOCOL};
$USERNAME = $+{USERNAME} if $+{USERNAME};
$PASSWORD = $+{PASSWORD} if $+{PASSWORD};
$ADDRESS = $+{ADDRESS} if $+{ADDRESS};
} elsif ($self->{Monitor}{Path}) {
Debug("Using Path for credentials: $self->{Monitor}{Path}");
my $uri = URI->new($self->{Monitor}{Path});
if ($uri->userinfo()) {
Debug("Using Path for credentials: $self->{Monitor}{Path}");
( $USERNAME, $PASSWORD ) = split(/:/, $uri->userinfo());
} elsif ($self->{Monitor}->{User} ) {
Debug('Using User/Pass for credentials');
( $USERNAME, $PASSWORD ) = ($self->{Monitor}->{User}, $self->{Monitor}->{Pass});
}
$ADDRESS = $uri->host();
} else {
Error('Failed to parse auth from address ' . $self->{Monitor}->{ControlAddress});
$ADDRESS = $self->{Monitor}->{ControlAddress};
}
if ( !($ADDRESS =~ /:/) ) {
$ADDRESS .= ':80';
}
$self->{ua} = LWP::UserAgent->new;
$self->{ua}->agent('ZoneMinder Control Agent/'.ZoneMinder::Base::ZM_VERSION);
$self->{state} = 'closed';
# credentials: ("ip:port" (no prefix!), realm (string), username (string), password (string)
Debug("sendCmd credentials control address:'".$ADDRESS
."' realm:'" . $REALM
. "' username:'" . $USERNAME
. "' password:'".$PASSWORD
."'"
);
# Detect REALM
$REALM = $self->detect_realm($PROTOCOL, $ADDRESS, $REALM, $USERNAME, $PASSWORD, '/cgi/ptdc.cgi');
if ($REALM) {
$self->guess_credentials();
if ($self->get_realm('/cgi/ptdc.cgi')) {
$self->{state} = 'open';
return !undef;
return 1;
}
return undef;
} # end sub open
sub detect_realm {
my ($self, $protocol, $address, $realm, $username, $password, $url) = @_;
$self->{ua}->credentials($address, $realm, $username, $password);
my $res = $self->{ua}->get($protocol.$address.$url);
if ($res->is_success) {
Debug(1, 'Success opening without realm detection for '.$url);
return $realm;
}
if ($res->status_line() ne '401 Unauthorized') {
return $realm;
}
my $headers = $res->headers();
foreach my $k ( keys %$headers ) {
Debug("Initial Header $k => $$headers{$k}");
}
if ($$headers{'www-authenticate'}) {
my ( $auth, $tokens ) = $$headers{'www-authenticate'} =~ /^(\w+)\s+(.*)$/;
if ( $tokens =~ /\w+="([^"]+)"/i ) {
if ($realm ne $1) {
$realm = $1;
Debug("Changing REALM to $realm");
$self->{ua}->credentials($address, $realm, $username, $password);
$res = $self->{ua}->get($protocol.$address.$url);
if ($res->status_line() ne '401 Unauthorized') {
return $realm;
}
Error('Authentication still failed after updating REALM' . $res->status_line);
$headers = $res->headers();
foreach my $k ( keys %$headers ) {
Debug("Initial Header $k => $$headers{$k}");
} # end foreach
} else {
Error('Authentication failed, not a REALM problem');
}
} else {
Error('Failed to match realm in tokens');
} # end if
} else {
Debug('No headers line');
} # end if headers
return '';
}
sub sendCmd {
# This routine is used for all moving, which are all GET commands...
my $self = shift;
@@ -147,16 +48,11 @@ sub sendCmd {
}
my $cmd = shift;
my $url = $PROTOCOL.$ADDRESS.'/cgi/ptdc.cgi?command='.$cmd;
my $res = $self->{ua}->get($url);
Debug('sendCmd command: ' . $url);
my $url = '/cgi/ptdc.cgi?command='.$cmd;
my $res = $self->get($url);
if (!$res->is_success) {
Error("sendCmdPost Error check failed: '".$res->status_line()."' cmd:");
my $new_realm = $self->detect_realm($PROTOCOL, $ADDRESS, $REALM, $USERNAME, $PASSWORD, $url);
if (defined($new_realm) and ($new_realm ne $REALM)) {
Debug("Success after re-detecting realm. New realm is $new_realm");
return !undef;
}
return;
}
if (!$self->{Monitor}->{ModectDuringPTZ}) {
@@ -186,24 +82,13 @@ sub sendCmdPost {
return -1;
}
Debug('sendCmdPost url: ' . $PROTOCOL.$ADDRESS.$url);
my $res = $self->{ua}->post(
$PROTOCOL.$ADDRESS.$url,
Referer=>$PROTOCOL.$ADDRESS.$url,
my $res = $self->post(
$url,
Referer=>$$self{BaseURL},
Content=>$form
);
Debug("sendCmdPost credentials control to: $PROTOCOL$ADDRESS$url realm:'" . $REALM . "' username:'" . $USERNAME . "' password:'".$PASSWORD."'");
if (!$res->is_success) {
Error("sendCmdPost Error check failed: '".$res->status_line()."' cmd:");
my $new_realm = $self->detect_realm($PROTOCOL, $ADDRESS, $REALM, $USERNAME, $PASSWORD, $url);
if (defined($new_realm) and ($new_realm ne $REALM)) {
Debug("Success after re-detecting realm. New realm is $new_realm");
return !undef;
}
Warning('Failed to reboot');
return undef;
}
Debug($res->content);
@@ -434,17 +319,6 @@ sub reboot {
#$initial_url = $HI->ip().'/eng/admin/tools_default.cgi';
}
sub ping {
return -1 if ! $ADDRESS;
require Net::Ping;
my $p = Net::Ping->new();
my $rv = $p->ping($ADDRESS);
$p->close();
return $rv;
}
1;
__END__