Merge pull request #169 from rhansen/geturl-force-ip-version

This commit is contained in:
Sandro 2020-06-24 15:15:12 +02:00 committed by GitHub
commit 271f277126
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

259
ddclient
View file

@ -1521,7 +1521,12 @@ sub test_possible_ip {
sub test_geturl {
my $url = shift;
my $reply = geturl(opt('proxy'), $url, opt('login'), opt('password'));
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => opt('login'),
password => opt('password'),
});
print "URL $url\n";
print defined($reply) ? $reply : "<undefined>\n";
exit;
@ -1995,13 +2000,15 @@ EOM
## geturl
######################################################################
sub geturl {
my $proxy = shift || '';
my $url = shift || '';
my $login = shift || '';
my $password = shift || '';
my $headers = shift || '';
my $method = shift || 'GET';
my $data = shift || '';
my ($params) = @_;
my $proxy = $params->{proxy} // '';
my $url = $params->{url} // '';
my $login = $params->{login} // '';
my $password = $params->{password} // '';
my $ipversion = $params->{ipversion} // '';
my $headers = $params->{headers} // '';
my $method = $params->{method} // 'GET';
my $data = $params->{data} // '';
my ($peer, $server, $port, $default_port, $use_ssl);
my ($sd, $request, $reply);
@ -2021,7 +2028,6 @@ sub geturl {
if ($force_ssl || ($globals{'ssl'} and (caller(1))[3] ne 'main::get_ip')) {
$use_ssl = 1;
$default_port = 443;
load_ssl_support;
} else {
$use_ssl = 0;
$default_port = 80;
@ -2030,6 +2036,7 @@ sub geturl {
debug("protocol = %s", $use_ssl ? "https" : "http");
debug("server = %s", $server);
debug("url = %s", $url);
debug("ip ver = %s", $ipversion);
## determine peer and port to use.
$peer = $proxy || $server;
@ -2039,9 +2046,6 @@ sub geturl {
$port = $default_port unless $port =~ /^\d+$/;
$peer =~ s%:.*$%%;
my $to = sprintf "%s%s", $server, $proxy ? " via proxy $peer:$port" : "";
verbose("CONNECT:", "%s", $to);
$request = "$method ";
if (!$use_ssl) {
$request .= "http://$server" if $proxy;
@ -2067,57 +2071,61 @@ sub geturl {
$request .= $data;
$rq .= $data;
$0 = sprintf("%s - connecting to %s port %s", $program, $peer, $port);
if (!opt('exec')) {
debug("skipped network connection");
verbose("SENDING:", "%s", $request);
} elsif ($use_ssl) {
$sd = IO::Socket::SSL->new(
PeerAddr => $peer,
PeerPort => $port,
Proto => 'tcp',
MultiHomed => 1,
Timeout => opt('timeout'),
);
defined $sd or warning("cannot connect to %s:%s socket: %s %s", $peer, $port, $@, IO::Socket::SSL::errstr());
} elsif ($globals{'ipv6'}) {
my $socket_class = 'IO::Socket::INET';
if ($use_ssl) {
# IO::Socket::SSL will load IPv6 support if available on the system.
load_ssl_support;
$socket_class = 'IO::Socket::SSL';
} elsif ($globals{'ipv6'} || $ipversion eq '6') {
load_ipv6_support;
$sd = IO::Socket::INET6->new(
PeerAddr => $peer,
PeerPort => $port,
Proto => 'tcp',
MultiHomed => 1,
Timeout => opt('timeout'),
);
defined $sd or warning("cannot connect to %s:%s socket: %s", $peer, $port, $@);
} else {
$sd = IO::Socket::INET->new(
PeerAddr => $peer,
PeerPort => $port,
Proto => 'tcp',
MultiHomed => 1,
Timeout => opt('timeout'),
);
defined $sd or warning("cannot connect to %s:%s socket: %s", $peer, $port, $@);
$socket_class = 'IO::Socket::INET6';
}
my %socket_args = (
PeerAddr => $peer,
PeerPort => $port,
Proto => 'tcp',
MultiHomed => 1,
Timeout => opt('timeout'),
);
if ($ipversion eq '4') {
$socket_args{Domain} = PF_INET;
$socket_args{Family} = AF_INET;
} elsif ($ipversion eq '6') {
$socket_args{Domain} = PF_INET6;
$socket_args{Family} = AF_INET6;
} elsif ($ipversion ne '') {
fatal("geturl passed unsupported 'ipversion' value %s", $ipversion);
}
my $ipv = $ipversion eq '' ? '' : sprintf(" (IPv%s)", $ipversion);
my $peer_port_ipv = sprintf("%s:%s%s", $peer, $port, $ipv);
my $to = sprintf("%s%s%s", $server, $proxy ? " via proxy $peer:$port" : "", $ipv);
verbose("CONNECT:", "%s", $to);
$0 = sprintf("%s - connecting to %s", $program, $peer_port_ipv);
if (opt('exec')) {
$sd = $socket_class->new(%socket_args);
defined($sd) or warning("cannot connect to %s socket: %s%s", $peer_port_ipv, $@,
$use_ssl ? ' ' . IO::Socket::SSL::errstr() : '');
} else {
debug("skipped network connection");
verbose("SENDING:", "%s", $request);
}
if (defined $sd) {
## send the request to the http server
verbose("CONNECTED: ", $use_ssl ? 'using SSL' : 'using HTTP');
verbose("SENDING:", "%s", $request);
$0 = sprintf("%s - sending to %s port %s", $program, $peer, $port);
$0 = sprintf("%s - sending to %s", $program, $peer_port_ipv);
my $result = syswrite $sd, $rq;
if ($result != length($rq)) {
warning("cannot send to %s:%s (%s).", $peer, $port, $!);
warning("cannot send to %s (%s).", $peer_port_ipv, $!);
} else {
$0 = sprintf("%s - reading from %s port %s", $program, $peer, $port);
$0 = sprintf("%s - reading from %s", $program, $peer_port_ipv);
eval {
local $SIG{'ALRM'} = sub { die "timeout"; };
alarm(opt('timeout')) if opt('timeout') > 0;
while ($_ = <$sd>) {
$0 = sprintf("%s - read from %s port %s", $program, $peer, $port);
$0 = sprintf("%s - read from %s", $program, $peer_port_ipv);
verbose("RECEIVE:", "%s", define($_, "<undefined>"));
$reply .= $_ if defined $_;
}
@ -2134,7 +2142,7 @@ sub geturl {
$reply = '' if !defined $reply;
}
}
$0 = sprintf("%s - closed %s port %s", $program, $peer, $port);
$0 = sprintf("%s - closed %s", $program, $peer_port_ipv);
## during testing simulate reading the URL
if (opt('test')) {
@ -2229,7 +2237,7 @@ sub get_ip {
$arg = $url;
if ($url) {
$reply = geturl(opt('proxy', $h), $url) || '';
$reply = geturl({ proxy => opt('proxy', $h), url => $url }) || '';
}
} elsif (($use eq 'cisco')) {
@ -2245,9 +2253,13 @@ sub get_ip {
# Protect special HTML characters (like '?')
$queryif =~ s/([\?&= ])/sprintf("%%%02x", ord($1))/ge;
$url = "http://" . opt('fw', $h) . "/level/1/exec/show/ip/interface/brief/${queryif}/CR";
$reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || '';
$arg = $url;
$url = "http://" . opt('fw', $h) . "/level/1/exec/show/ip/interface/brief/${queryif}/CR";
$reply = geturl({
url => $url,
login => opt('fw-login', $h),
password => opt('fw-password', $h),
}) || '';
$arg = $url;
} elsif (($use eq 'cisco-asa')) {
# Stuff added to support Cisco ASA ip https daemon
@ -2262,9 +2274,13 @@ sub get_ip {
# Protect special HTML characters (like '?')
$queryif =~ s/([\?&= ])/sprintf("%%%02x", ord($1))/ge;
$url = "https://" . opt('fw', $h) . "/exec/show%20interface%20${queryif}";
$reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || '';
$arg = $url;
$url = "https://" . opt('fw', $h) . "/exec/show%20interface%20${queryif}";
$reply = geturl({
url => $url,
login => opt('fw-login', $h),
password => opt('fw-password', $h),
}) || '';
$arg = $url;
} else {
$url = opt('fw', $h) || '';
@ -2277,7 +2293,11 @@ sub get_ip {
$arg = $url;
if ($url) {
$reply = geturl('', $url, opt('fw-login', $h), opt('fw-password', $h)) || '';
$reply = geturl({
url => $url,
login => opt('fw-login', $h),
password => opt('fw-password', $h),
}) || '';
}
}
if (!defined $reply) {
@ -2656,7 +2676,12 @@ sub nic_dyndns1_update {
$url .= "&backmx=" . ynu($config{$h}{'backupmx'}, 'YES', 'NO');
}
my $reply = geturl(opt('proxy'), $url, $config{$h}{'login'}, $config{$h}{'password'});
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => $config{$h}{'login'},
password => $config{$h}{'password'},
});
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'});
next;
@ -2819,7 +2844,12 @@ sub nic_dyndns2_update {
$url .= "&backmx=" . ynu($config{$h}{'backupmx'}, 'YES', 'NO');
}
my $reply = geturl(opt('proxy'), $url, $config{$h}{'login'}, $config{$h}{'password'});
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => $config{$h}{'login'},
password => $config{$h}{'password'},
});
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $hosts, $config{$h}{'server'});
last;
@ -2924,7 +2954,12 @@ sub nic_noip_update {
$url .= "&myip=";
$url .= $ip if $ip;
my $reply = geturl(opt('proxy'), $url, $config{$h}{'login'}, $config{$h}{'password'});
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => $config{$h}{'login'},
password => $config{$h}{'password'},
});
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $hosts, $config{$h}{'server'});
last;
@ -3059,7 +3094,12 @@ sub nic_dslreports1_update {
$url .= "&myip=";
$url .= $ip if $ip;
my $reply = geturl(opt('proxy'), $url, $config{$h}{'login'}, $config{$h}{'password'});
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => $config{$h}{'login'},
password => $config{$h}{'password'},
});
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'});
next;
@ -3134,7 +3174,12 @@ sub nic_hammernode1_update {
$url .= "&ip=";
$url .= $ip if $ip;
my $reply = geturl(opt('proxy'), $url, $config{$h}{'login'}, $config{$h}{'password'});
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => $config{$h}{'login'},
password => $config{$h}{'password'},
});
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'});
last;
@ -3224,7 +3269,12 @@ sub nic_zoneedit1_update {
$url .= "&dnsto=$ip" if $ip;
$url .= "&zone=$config{$h}{'zone'}" if defined $config{$h}{'zone'};
my $reply = geturl(opt('proxy'), $url, $config{$h}{'login'}, $config{$h}{'password'});
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => $config{$h}{'login'},
password => $config{$h}{'password'},
});
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $hosts, $config{$h}{'server'});
last;
@ -3374,7 +3424,12 @@ sub nic_easydns_update {
$url .= "&backmx=" . ynu($config{$h}{'backupmx'}, 'YES', 'NO');
}
my $reply = geturl(opt('proxy'), $url, $config{$h}{'login'}, $config{$h}{'password'});
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => $config{$h}{'login'},
password => $config{$h}{'password'},
});
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $hosts, $config{$h}{'server'});
last;
@ -3488,7 +3543,7 @@ sub nic_namecheap_update {
$url .= "&ip=";
$url .= $ip if $ip;
my $reply = geturl(opt('proxy'), $url);
my $reply = geturl({ proxy => opt('proxy'), url => $url });
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'});
last;
@ -3619,7 +3674,13 @@ sub nic_nfsn_make_request {
$header .= "Content-Type: application/x-www-form-urlencoded\n";
}
return geturl(opt('proxy'), $url, '', '', $header, $method, $body);
return geturl({
proxy => opt('proxy'),
url => $url,
headers => $header,
method => $method,
data => $body,
});
}
######################################################################
@ -3792,7 +3853,7 @@ sub nic_sitelutions_update {
$url .= "&ip=";
$url .= $ip if $ip;
my $reply = geturl(opt('proxy'), $url);
my $reply = geturl({ proxy => opt('proxy'), url => $url });
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'});
last;
@ -3863,7 +3924,7 @@ sub nic_freedns_update {
## First get the list of updatable hosts
my $url;
$url = "http://$config{$_[0]}{'server'}/api/?action=getdyndns&sha=" . &sha1_hex("$config{$_[0]}{'login'}|$config{$_[0]}{'password'}");
my $reply = geturl(opt('proxy'), $url);
my $reply = geturl({ proxy => opt('proxy'), url => $url });
if (!defined($reply) || !$reply || !header_ok($_[0], $reply)) {
failed("updating %s: Could not connect to %s for site list.", $_[0], $url);
return;
@ -3891,7 +3952,7 @@ sub nic_freedns_update {
$config{$h}{'status'} = 'good';
success("update not necessary %s: good: IP address already set to %s", $h, $ip);
} else {
my $reply = geturl(opt('proxy'), $freedns_hosts{$h}->[2]);
my $reply = geturl({proxy => opt('proxy'), url => $freedns_hosts{$h}->[2] });
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $freedns_hosts{$h}->[2]);
last;
@ -3968,7 +4029,12 @@ sub nic_changeip_update {
$url .= "&ip=";
$url .= $ip if $ip;
my $reply = geturl(opt('proxy'), $url, $config{$h}{'login'}, $config{$h}{'password'});
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => $config{$h}{'login'},
password => $config{$h}{'password'},
});
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'});
last;
@ -4044,7 +4110,7 @@ sub nic_dtdns_update {
$url .= $config{$h}{'client'};
# Try to get URL
my $reply = geturl(opt('proxy'), $url);
my $reply = geturl({ proxy => opt('proxy'), url => $url });
# No response, declare as failed
if (!defined($reply) || !$reply) {
@ -4129,7 +4195,12 @@ sub nic_googledomains_update {
$url .= "&myip=";
$url .= $ip if $ip;
my $reply = geturl(opt('proxy'), $url, $config{$host}{'login'}, $config{$host}{'password'});
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => $config{$host}{'login'},
password => $config{$host}{'password'},
});
unless ($reply) {
failed("updating %s: Could not connect to %s.", $host, $config{$host}{'server'});
last;
@ -4338,7 +4409,7 @@ sub nic_cloudflare_update {
my $url = "https://$config{$key}{'server'}/zones?";
$url .= "name=".$config{$key}{'zone'};
my $reply = geturl(opt('proxy'), $url, undef, undef, $headers);
my $reply = geturl({ proxy => opt('proxy'), url => $url, headers => $headers });
unless ($reply) {
failed("updating %s: Could not connect to %s.", $domain, $config{$key}{'server'});
last;
@ -4369,7 +4440,7 @@ sub nic_cloudflare_update {
$url .= "type=A&name=$domain";
}
$reply = geturl(opt('proxy'), $url, undef, undef, $headers);
$reply = geturl({ proxy => opt('proxy'), url => $url, headers => $headers });
unless ($reply) {
failed("updating %s: Could not connect to %s.", $domain, $config{$key}{'server'});
last;
@ -4395,7 +4466,13 @@ sub nic_cloudflare_update {
# Set domain
$url = "https://$config{$key}{'server'}/zones/$zone_id/dns_records/$dns_rec_id";
my $data = "{\"content\":\"$ip\"}";
$reply = geturl(opt('proxy'), $url, undef, undef, $headers, "PATCH", $data);
$reply = geturl({
proxy => opt('proxy'),
url => $url,
headers => $headers,
method => "PATCH",
data => $data,
});
unless ($reply) {
failed("updating %s: Could not connect to %s.", $domain, $config{$domain}{'server'});
last;
@ -4479,7 +4556,7 @@ sub nic_yandex_update {
my $url = "https://$config{$host}{'server'}/api2/admin/dns/list?";
$url .= "domain=";
$url .= $config{$key}{'login'};
my $reply = geturl(opt('proxy'), $url, '', '', $headers);
my $reply = geturl({ proxy => opt('proxy'), url => $url, headers => $headers });
unless ($reply) {
failed("updating %s: Could not connect to %s.", $host, $config{$key}{'server'});
last;
@ -4510,7 +4587,13 @@ sub nic_yandex_update {
$data .= "&content=";
$data .= $ip if $ip;
$reply = geturl(opt('proxy'), $url, '', '', $headers, 'POST', $data);
$reply = geturl({
proxy => opt('proxy'),
url => $url,
headers => $headers,
method => 'POST',
data => $data,
});
unless ($reply) {
failed("updating %s: Could not connect to %s.", $host, $config{$host}{'server'});
last;
@ -4588,7 +4671,7 @@ sub nic_duckdns_update {
# Try to get URL
my $reply = geturl(opt('proxy'), $url);
my $reply = geturl({ proxy => opt('proxy'), url => $url });
# No response, declare as failed
if (!defined($reply) || !$reply) {
@ -4659,7 +4742,7 @@ sub nic_freemyip_update {
$url .= $h;
# Try to get URL
my $reply = geturl(opt('proxy'), $url);
my $reply = geturl({ proxy => opt('proxy'), url => $url });
# No response, declare as failed
if (!defined($reply) || !$reply) {
@ -4787,7 +4870,12 @@ sub nic_woima_update {
$url .= "&backmx=" . ynu($config{$h}{'backupmx'}, 'YES', 'NO');
}
my $reply = geturl(opt('proxy'), $url, $config{$h}{'login'}, $config{$h}{'password'});
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => $config{$h}{'login'},
password => $config{$h}{'password'},
});
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'});
last;
@ -4903,7 +4991,7 @@ sub nic_dondominio_update {
# Try to get URL
my $reply = geturl(opt('proxy'), $url);
my $reply = geturl({ proxy => opt('proxy'), url => $url });
# No response, declare as failed
if (!defined($reply) || !$reply) {
@ -4989,7 +5077,7 @@ sub nic_dnsmadeeasy_update {
$url .= "&id=$h";
# Try to get URL
my $reply = geturl(opt('proxy'), $url);
my $reply = geturl({ proxy => opt('proxy'), url => $url });
# No response, declare as failed
if (!defined($reply) || !$reply) {
@ -5060,7 +5148,12 @@ sub nic_ovh_update {
$url .= "&myip=";
$url .= $ip if $ip;
my $reply = geturl(opt('proxy'), $url, "$config{$h}{'login'}", "$config{$h}{'password'}");
my $reply = geturl({
proxy => opt('proxy'),
url => $url,
login => $config{$h}{'login'},
password => $config{$h}{'password'},
});
if (!defined($reply) || !$reply) {
failed("updating %s: Could not connect to %s.", $h, $config{$h}{'server'});