mirror of
https://github.com/fhem/fhem-mirror.git
synced 2025-02-07 16:59:18 +00:00
HttpUtils.pm: Auth Digest, second try (Forum #43043)
git-svn-id: https://svn.fhem.de/fhem/trunk@9756 2b470e98-0d58-463d-a4d8-8e2adae1ed80
This commit is contained in:
parent
85bc15a680
commit
09448aa15a
@ -6,6 +6,7 @@ use strict;
|
||||
use warnings;
|
||||
use IO::Socket::INET;
|
||||
use MIME::Base64;
|
||||
use Digest::MD5;
|
||||
use vars qw($SSL_ERROR);
|
||||
|
||||
my %ext2MIMEType= qw{
|
||||
@ -131,7 +132,7 @@ HttpUtils_Connect($)
|
||||
}
|
||||
$hash->{path} = '/' unless defined($hash->{path});
|
||||
$hash->{addr} = "$hash->{protocol}://$host:$port";
|
||||
$hash->{auth} = encode_base64("$user:$pwd","") if($authstring);
|
||||
$hash->{auth} = "$user:$pwd" if($authstring);
|
||||
|
||||
return HttpUtils_Connect2($hash) if($hash->{conn} && $hash->{keepalive});
|
||||
|
||||
@ -251,7 +252,11 @@ HttpUtils_Connect2($)
|
||||
$hdr .= "Connection: keep-alive\r\n" if($hash->{keepalive});
|
||||
$hdr .= "Connection: Close\r\n"
|
||||
if($httpVersion ne "1.0" && !$hash->{keepalive});
|
||||
$hdr .= "Authorization: Basic $hash->{auth}\r\n" if(defined($hash->{auth}));
|
||||
|
||||
$hdr .= "Authorization: Basic ".encode_base64($hash->{auth}, "")."\r\n"
|
||||
if(defined($hash->{auth}) &&
|
||||
!($hash->{header} &&
|
||||
$hash->{header} =~ /^Authorization:\s*Digest/mi));
|
||||
$hdr .= $hash->{header}."\r\n" if(defined($hash->{header}));
|
||||
if(defined($data)) {
|
||||
$hdr .= "Content-Length: ".length($data)."\r\n";
|
||||
@ -329,6 +334,56 @@ HttpUtils_DataComplete($)
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub
|
||||
HttpUtils_DigestHeader($$)
|
||||
{
|
||||
my ($hash, $header) = @_;
|
||||
my %digdata;
|
||||
|
||||
while($header =~ /(\w+)="?([^"]+?)"?(?:,\s+|$)/gc) {
|
||||
$digdata{$1} = $2;
|
||||
}
|
||||
|
||||
my ($ha1, $ha2, $response);
|
||||
my ($user,$passwd) = split(/:/, $hash->{auth}, 2);
|
||||
|
||||
if(exists($digdata{qop})) {
|
||||
$digdata{nc} = "00000001";
|
||||
$digdata{cnonce} = md5_hex(rand.time);
|
||||
}
|
||||
$digdata{uri} = $hash->{path};
|
||||
$digdata{username} = $user;
|
||||
|
||||
if(exists($digdata{algorithm}) && $digdata{algorithm} eq "MD5-sess") {
|
||||
$ha1 = md5_hex(md5_hex($user.":".$digdata{realm}.":".$passwd).
|
||||
":".$digdata{nonce}.":".$digdata{cnonce});
|
||||
} else {
|
||||
$ha1 = md5_hex($user.":".$digdata{realm}.":".$passwd);
|
||||
}
|
||||
|
||||
# forcing qop=auth as qop=auth-int is not implemented
|
||||
$digdata{qop} = "auth" if($digdata{qop});
|
||||
my $method = $hash->{method};
|
||||
$method = ($hash->{data} ? "POST" : "GET") if( !$method );
|
||||
$ha2 = md5_hex($method.":".$hash->{path});
|
||||
|
||||
if(exists($digdata{qop}) && $digdata{qop} =~ /(auth-int|auth)/) {
|
||||
$digdata{response} = md5_hex($ha1.":".
|
||||
$digdata{nonce}.":".
|
||||
$digdata{nc}.":".
|
||||
$digdata{cnonce}.":".
|
||||
$digdata{qop}.":".
|
||||
$ha2);
|
||||
} else {
|
||||
$digdata{response} = md5_hex($ha1.":".$digdata{nonce}.":".$ha2)
|
||||
}
|
||||
|
||||
return "Authorization: Digest ".
|
||||
join(", ", map(($_.'='.($_ ne "nc" ? '"' :'').
|
||||
$digdata{$_}.($_ ne "nc" ? '"' :'')), keys(%digdata)));
|
||||
|
||||
}
|
||||
|
||||
sub
|
||||
HttpUtils_ParseAnswer($$)
|
||||
{
|
||||
@ -375,6 +430,29 @@ HttpUtils_ParseAnswer($$)
|
||||
}
|
||||
Log3 $hash,$hash->{loglevel}, "$hash->{displayurl}: HTTP response code $code";
|
||||
$hash->{code} = $code;
|
||||
|
||||
# if servers requests digest authentication
|
||||
if($code==401 && defined($hash->{auth}) &&
|
||||
!($hash->{header} && $hash->{header} =~ /^Authorization:\s*Digest/mi) &&
|
||||
$hash->{httpheader} =~ /^WWW-Authenticate:\s*Digest\s*(.+?)\s*$/mi) {
|
||||
|
||||
$hash->{header} .= "\r\n".
|
||||
HttpUtils_DigestHeader($hash, $1) if($hash->{header});
|
||||
$hash->{header} = HttpUtils_DigestHeader($hash, $1) if(!$hash->{header});
|
||||
|
||||
# Request the URL with the Digest response
|
||||
if($hash->{callback}) {
|
||||
HttpUtils_NonblockingGet($hash);
|
||||
return ("", "", 1);
|
||||
} else {
|
||||
return HttpUtils_BlockingGet($hash);
|
||||
}
|
||||
|
||||
} elsif($code==401 && defined($hash->{auth})) {
|
||||
return ("$hash->{displayurl}: wrong authentication", "")
|
||||
|
||||
}
|
||||
|
||||
if(($code==301 || $code==302 || $code==303)
|
||||
&& !$hash->{ignoreredirects}) { # redirect
|
||||
if(++$hash->{redirects} > 5) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user