Add http digest authentication and make it the default with an option to use basic if required.
This commit is contained in:
parent
e137068d23
commit
a30b4662b4
|
|
@ -249,13 +249,75 @@ openlog("fusion-provisioning", LOG_PID | LOG_PERROR, LOG_LOCAL0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//http authentication
|
//http authentication - digest
|
||||||
if (strlen($provision["http_auth_username"]) > 0 && strlen($provision["http_auth_password"]) > 0) {
|
if (strlen($provision["http_auth_username"]) > 0 && strlen($provision["http_auth_type"]) == 0) { $provision["http_auth_type"] = "digest"; }
|
||||||
|
if (strlen($provision["http_auth_username"]) > 0 && strlen($provision["http_auth_password"]) > 0 && $provision["http_auth_type"] == "digest") {
|
||||||
|
//function to parse the http auth header
|
||||||
|
function http_digest_parse($txt) {
|
||||||
|
//protect against missing data
|
||||||
|
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
|
||||||
|
$data = array();
|
||||||
|
$keys = implode('|', array_keys($needed_parts));
|
||||||
|
preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
|
||||||
|
foreach ($matches as $m) {
|
||||||
|
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
|
||||||
|
unset($needed_parts[$m[1]]);
|
||||||
|
}
|
||||||
|
return $needed_parts ? false : $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
//function to request digest authentication
|
||||||
|
function http_digest_request($realm) {
|
||||||
|
header('HTTP/1.1 401 Authorization Required');
|
||||||
|
header('WWW-Authenticate: Digest realm="'.$realm.'", qop="auth", nonce="'.uniqid().'", opaque="'.md5($realm).'"');
|
||||||
|
header("Content-Type: text/html");
|
||||||
|
$content = 'Authorization Cancelled';
|
||||||
|
header("Content-Length: ".strval(strlen($content)));
|
||||||
|
echo $content;
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
|
//set the realm
|
||||||
|
$realm = $_SESSION['domain_name'];
|
||||||
|
|
||||||
|
//request authentication
|
||||||
|
if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
|
||||||
|
http_digest_request($realm);
|
||||||
|
}
|
||||||
|
|
||||||
|
//check for valid digest authentication details
|
||||||
|
if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || ($data['username'] != $provision["http_auth_username"])) {
|
||||||
|
header('HTTP/1.1 401 Unauthorized');
|
||||||
|
header("Content-Type: text/html");
|
||||||
|
$content = 'Unauthorized '.$__line__;
|
||||||
|
header("Content-Length: ".strval(strlen($content)));
|
||||||
|
echo $content;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
//generate the valid response
|
||||||
|
$A1 = md5($provision["http_auth_username"] . ':' . $realm . ':' . $provision["http_auth_password"]);
|
||||||
|
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
|
||||||
|
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
|
||||||
|
if ($data['response'] != $valid_response) {
|
||||||
|
header('HTTP/1.0 401 Unauthorized');
|
||||||
|
header("Content-Type: text/html");
|
||||||
|
$content = 'Unauthorized '.$__line__;
|
||||||
|
header("Content-Length: ".strval(strlen($content)));
|
||||||
|
echo $content;
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//http authentication - basic
|
||||||
|
if (strlen($provision["http_auth_username"]) > 0 && strlen($provision["http_auth_password"]) > 0 && $provision["http_auth_type"] == "basic") {
|
||||||
if (!isset($_SERVER['PHP_AUTH_USER'])) {
|
if (!isset($_SERVER['PHP_AUTH_USER'])) {
|
||||||
header('WWW-Authenticate: Basic realm="'.$_SESSION['domain_name']." ".date('r').'"');
|
header('WWW-Authenticate: Basic realm="'.$_SESSION['domain_name'].'"');
|
||||||
header('HTTP/1.0 401 Unauthorized');
|
header('HTTP/1.0 401 Authorization Required');
|
||||||
header("Content-Type: text/plain");
|
header("Content-Type: text/html");
|
||||||
header("Content-Length: 0");
|
$content = 'Authorization Required';
|
||||||
|
header("Content-Length: ".strval(strlen($content)));
|
||||||
|
echo $content;
|
||||||
exit;
|
exit;
|
||||||
} else {
|
} else {
|
||||||
if ($_SERVER['PHP_AUTH_USER'] == $provision["http_auth_username"] && $_SERVER['PHP_AUTH_PW'] == $provision["http_auth_password"]) {
|
if ($_SERVER['PHP_AUTH_USER'] == $provision["http_auth_username"] && $_SERVER['PHP_AUTH_PW'] == $provision["http_auth_password"]) {
|
||||||
|
|
@ -263,10 +325,10 @@ openlog("fusion-provisioning", LOG_PID | LOG_PERROR, LOG_LOCAL0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//access denied
|
//access denied
|
||||||
header('WWW-Authenticate: Basic realm="'.$_SESSION['domain_name']." ".date('r').'"');
|
header('HTTP/1.0 401 Unauthorized');
|
||||||
|
header('WWW-Authenticate: Basic realm="'.$_SESSION['domain_name'].'"');
|
||||||
unset($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
|
unset($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']);
|
||||||
usleep(rand(1000000,3000000));//1-3 seconds.
|
$content = 'Unauthorized';
|
||||||
$content = 'Authorization Required';
|
|
||||||
header("Content-Length: ".strval(strlen($content)));
|
header("Content-Length: ".strval(strlen($content)));
|
||||||
echo $content;
|
echo $content;
|
||||||
exit;
|
exit;
|
||||||
|
|
@ -282,7 +344,6 @@ openlog("fusion-provisioning", LOG_PID | LOG_PERROR, LOG_LOCAL0);
|
||||||
openlog('FusionPBX', LOG_NDELAY, LOG_AUTH);
|
openlog('FusionPBX', LOG_NDELAY, LOG_AUTH);
|
||||||
syslog(LOG_WARNING, '['.$_SERVER['REMOTE_ADDR']."] provision attempt bad password for ".check_str($_REQUEST['mac']));
|
syslog(LOG_WARNING, '['.$_SERVER['REMOTE_ADDR']."] provision attempt bad password for ".check_str($_REQUEST['mac']));
|
||||||
closelog();
|
closelog();
|
||||||
usleep(rand(1000000,3000000));//1-3 seconds.
|
|
||||||
echo "access denied 4";
|
echo "access denied 4";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -334,17 +395,4 @@ openlog("fusion-provisioning", LOG_PID | LOG_PERROR, LOG_LOCAL0);
|
||||||
echo $file_contents;
|
echo $file_contents;
|
||||||
closelog();
|
closelog();
|
||||||
|
|
||||||
function http_digest_parse($txt){
|
|
||||||
// protect against missing data
|
|
||||||
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
|
|
||||||
$data = array();
|
|
||||||
$keys = implode('|', array_keys($needed_parts));
|
|
||||||
preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);
|
|
||||||
foreach ($matches as $m) {
|
|
||||||
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
|
|
||||||
unset($needed_parts[$m[1]]);
|
|
||||||
}
|
|
||||||
return $needed_parts ? false : $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue