new auth work

This commit is contained in:
Mike Macgirvin 2023-07-29 11:07:38 +10:00
parent 772a63e2e5
commit 25a69b236b
8 changed files with 75 additions and 119 deletions

View file

@ -8,6 +8,7 @@ use Code\ActivityStreams\Actor;
use Code\ActivityStreams\ASObject;
use Code\ActivityStreams\Link;
use Code\Nomad\Profile;
use Code\Web\HTTPHeaders;
use Code\Web\HTTPSig;
use Code\Access\Permissions;
use Code\Access\PermissionRoles;
@ -4596,23 +4597,14 @@ class Activity
public static function token_from_request()
{
foreach (['REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION'] as $s) {
$auth = ((array_key_exists($s, $_SERVER) && str_starts_with($_SERVER[$s], 'Bearer '))
? str_replace('Bearer ', EMPTY_STR, $_SERVER[$s])
: EMPTY_STR
);
if ($auth) {
break;
}
}
$authHeader = (new HTTPHeaders())->getAuthHeader();
$auth = ($authHeader && str_starts_with($authHeader, 'Bearer'));
if (!$auth) {
if (array_key_exists('token', $_REQUEST) && $_REQUEST['token']) {
$auth = $_REQUEST['token'];
}
}
return $auth;
}

View file

@ -3,6 +3,7 @@
namespace Code\Module;
use App;
use Code\Web\HTTPHeaders;
use DBA;
use DateTime;
use Sabre\CalDAV\CalendarRoot;
@ -63,29 +64,23 @@ class Cdav extends Controller
$_SERVER['HTTP_AUTHORIZATION'] = 'Signature ' . $_SERVER['HTTP_SIGNATURE'];
}
$authHeader = (new HTTPHeaders())->getAuthHeader();
if ($authHeader) {
foreach (['REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION'] as $head) {
/* Basic authentication */
if (array_key_exists($head, $_SERVER) && substr(trim($_SERVER[$head]), 0, 5) === 'Basic') {
$userpass = @base64_decode(substr(trim($_SERVER[$head]), 6));
if (substr(trim($authHeader), 0, 5) === 'Basic') {
$userpass = @base64_decode(substr(trim($authHeader), 6));
if (strlen($userpass)) {
list($name, $password) = explode(':', $userpass);
$_SERVER['PHP_AUTH_USER'] = $name;
$_SERVER['PHP_AUTH_PW'] = $password;
}
break;
}
/* Signature authentication */
if (array_key_exists($head, $_SERVER) && substr(trim($_SERVER[$head]), 0, 9) === 'Signature') {
if ($head !== 'HTTP_AUTHORIZATION') {
$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER[$head];
continue;
}
$sigblock = HTTPSig::parse_sigheader($_SERVER[$head]);
if (substr(trim($authHeader), 0, 9) === 'Signature') {
$sigblock = HTTPSig::parse_sigheader($authHeader);
if ($sigblock) {
$keyId = str_replace('acct:', '', $sigblock['keyId']);
if ($keyId) {
@ -103,9 +98,10 @@ class Cdav extends Controller
$channel_login = $c['channel_id'];
}
}
}
if (!$record) {
continue;
if ($record) {
break;
}
}
if ($record) {
@ -119,17 +115,11 @@ class Cdav extends Controller
change_channel($channel_login);
}
}
if ($verified && $verified['header_signed'] && $verified['header_valid'] && $record) {
break;
}
}
}
}
}
}
if ($verified && $verified['header_signed'] && $verified['header_valid'] && $record['account']) {
break;
}
}
/**

View file

@ -36,17 +36,13 @@ class Dav extends Controller
*/
public function init()
{
if (isset($_SERVER['HTTP_SIGNATURE']) &&
!isset($_SERVER['REDIRECT_REMOTE_USER']) &&
!isset($_SERVER['HTTP_AUTHORIZATION'])) {
$_SERVER['HTTP_AUTHORIZATION'] = 'Signature ' . $_SERVER['HTTP_SIGNATURE'];
}
$authHeader = (new HTTPHeaders())->getAuthHeader();
if ($authHeader) {
foreach (['REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION'] as $head) {
/* Basic authentication */
if (array_key_exists($head, $_SERVER) && str_starts_with(trim($_SERVER[$head]), 'Basic')) {
$userpass = @base64_decode(substr(trim($_SERVER[$head]), 6));
if (str_starts_with(trim($authHeader), 'Basic')) {
$userpass = @base64_decode(substr(trim($authHeader), 6));
if (strlen($userpass)) {
list($name, $password) = explode(':', $userpass);
$_SERVER['PHP_AUTH_USER'] = $name;
@ -57,13 +53,8 @@ class Dav extends Controller
/* Signature authentication */
if (array_key_exists($head, $_SERVER) && str_starts_with(trim($_SERVER[$head]), 'Signature')) {
if ($head !== 'HTTP_AUTHORIZATION') {
$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER[$head];
continue;
}
$sigblock = HTTPSig::parse_sigheader($_SERVER[$head]);
if (str_starts_with(trim($authHeader), 'Signature')) {
$sigblock = HTTPSig::parse_sigheader($authHeader);
if ($sigblock) {
$keyId = str_replace('acct:', '', $sigblock['keyId']);
if ($keyId) {
@ -81,10 +72,11 @@ class Dav extends Controller
$channel_login = $c['channel_id'];
}
}
if ($record) {
break;
}
}
if (!$record) {
continue;
}
if ($record) {
$verified = HTTPSig::verify('', $record['channel']['channel_pubkey']);
@ -97,17 +89,11 @@ class Dav extends Controller
change_channel($channel_login);
}
}
if ($verified && $verified['header_signed'] && $verified['header_valid'] && $record) {
break;
}
}
}
}
}
}
if ($verified && $verified['header_signed'] && $verified['header_valid'] && $record['account']) {
break;
}
}
if (!is_dir('store')) {

View file

@ -56,35 +56,26 @@ class Getfile extends Controller
killme();
}
if (isset($_SERVER['HTTP_SIGNATURE']) &&
!isset($_SERVER['REDIRECT_REMOTE_USER']) &&
!isset($_SERVER['HTTP_AUTHORIZATION'])) {
$_SERVER['HTTP_AUTHORIZATION'] = 'Signature ' . $_SERVER['HTTP_SIGNATURE'];
}
$authHeader = (new HTTPHeaders())->getAuthHeader();
if (($authHeader) && str_starts_with(trim($authHeader), 'Signature')) {
$_SERVER['HTTP_AUTHORIZATION'] = $authHeader;
foreach (['REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION'] as $head) {
if (array_key_exists($head, $_SERVER) && str_starts_with(trim($_SERVER[$head]), 'Signature')) {
if ($head !== 'HTTP_AUTHORIZATION') {
$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER[$head];
continue;
}
$verified = HTTPSig::verify('');
if ($verified && $verified['header_signed'] && $verified['header_valid']) {
$r = hubloc_id_addr_query($verified['signer']);
if ($r) {
foreach($r as $hub) {
if ($hub['hubloc_hash'] === $hash) {
$header_verified = true;
break;
}
$verified = HTTPSig::verify('');
if ($verified && $verified['header_signed'] && $verified['header_valid']) {
$r = hubloc_id_addr_query($verified['signer']);
if ($r) {
foreach($r as $hub) {
if ($hub['hubloc_hash'] === $hash) {
$header_verified = true;
break;
}
}
}
}
}
if (!$header_verified) {
http_status_exit(403, 'Permission denied');
}

View file

@ -21,20 +21,10 @@ class Owa extends Controller
public function init()
{
$ret = ['success' => false];
$authHeader = (new HTTPHeaders())->getAuthHeader();
if (array_key_exists('REDIRECT_REMOTE_USER', $_SERVER) && (!array_key_exists('HTTP_AUTHORIZATION', $_SERVER))) {
$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_REMOTE_USER'];
}
// Apache is now aggressively stripping authentication headers from reaching PHP. They aren't even available with the
// CGIPassAuth directive. So accept a Signature header in lieu of whatever Apache decides it isn't safe for your
// application to look at.
if (array_key_exists('HTTP_SIGNATURE', $_SERVER) && (!array_key_exists('HTTP_AUTHORIZATION', $_SERVER))) {
$_SERVER['HTTP_AUTHORIZATION'] = 'Signature ' . $_SERVER['HTTP_SIGNATURE'];
}
if (array_key_exists('HTTP_AUTHORIZATION', $_SERVER) && str_starts_with(trim($_SERVER['HTTP_AUTHORIZATION']), 'Signature')) {
$sigblock = HTTPSig::parse_sigheader($_SERVER['HTTP_AUTHORIZATION']);
if (str_starts_with(trim($authHeader), 'Signature')) {
$sigblock = HTTPSig::parse_sigheader($authHeader);
if ($sigblock) {
$keyId = $sigblock['keyId'];
if ($keyId) {

View file

@ -18,19 +18,10 @@ class Token extends Controller
{
logger('args: ' . print_r($_REQUEST, true));
$authHeader = (new HTTPHeaders())->getAuthHeader();
// workaround for HTTP-auth in CGI mode
if (x($_SERVER, 'REDIRECT_REMOTE_USER')) {
$userpass = base64_decode(substr($_SERVER["REDIRECT_REMOTE_USER"], 6));
if (strlen($userpass)) {
list($name, $password) = explode(':', $userpass);
$_SERVER['PHP_AUTH_USER'] = $name;
$_SERVER['PHP_AUTH_PW'] = $password;
}
}
if (x($_SERVER, 'HTTP_AUTHORIZATION')) {
$userpass = base64_decode(substr($_SERVER["HTTP_AUTHORIZATION"], 6));
if ($authHeader && str_starts_with($authHeader,'Basic')) {
$userpass = base64_decode(substr($authHeader, 6));
if (strlen($userpass)) {
list($name, $password) = explode(':', $userpass);
$_SERVER['PHP_AUTH_USER'] = $name;

View file

@ -8,8 +8,11 @@ class HTTPHeaders
private $in_progress = [];
private $parsed = [];
public function __construct($headers)
public function __construct($headers = null)
{
if (!$headers) {
return;
}
$lines = explode("\n", str_replace("\r", '', $headers));
if ($lines) {
@ -55,4 +58,25 @@ class HTTPHeaders
}
return $ret;
}
public function getAuthHeader()
{
$candidates = [
'HTTP_AUTHORIZATION',
'REDIRECT_HTTP_AUTHORIZATION',
'REDIRECT_REMOTE_USER',
'HTTP_SIGNATURE',
'HTTP_X_NOMAD_SIGNATURE'
];
foreach ($candidates as $candidate) {
if (!empty($_SERVER[$candidate]) && in_array($candidate, ['HTTP_SIGNATURE', 'HTTP_X_NOMAD_SIGNATURE'])) {
return 'Signature ' . $_SERVER[$candidate];
}
if (!empty($_SERVER[$candidate])) {
return $_SERVER[$candidate];
}
}
return null;
}
}

View file

@ -1,5 +1,6 @@
<?php
use Code\Web\HTTPHeaders;
use OAuth2\Request;
use Code\Identity\OAuth2Storage;
use Code\Identity\OAuth2Server;
@ -23,15 +24,7 @@ function api_login()
{
$record = null;
if (isset($_SERVER['HTTP_SIGNATURE']) &&
!isset($_SERVER['REDIRECT_REMOTE_USER']) &&
!isset($_SERVER['HTTP_AUTHORIZATION'])) {
$_SERVER['HTTP_AUTHORIZATION'] = 'Signature ' . $_SERVER['HTTP_SIGNATURE'];
}
if (array_key_exists('REDIRECT_REMOTE_USER', $_SERVER) && (! array_key_exists('HTTP_AUTHORIZATION', $_SERVER))) {
$_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_REMOTE_USER'];
}
$authHeader = (new HTTPHeaders())->getAuthHeader();
// login with oauth
@ -78,12 +71,12 @@ function api_login()
}
if (array_key_exists('HTTP_AUTHORIZATION', $_SERVER)) {
/* Basic authentication */
if ($authHeader) {
if (str_starts_with(trim($_SERVER['HTTP_AUTHORIZATION']), 'Basic')) {
/* Basic authentication */
if (str_starts_with(trim($authHeader), 'Basic')) {
// ignore base64 decoding errors caused by tricksters
$userpass = @base64_decode(substr(trim($_SERVER['HTTP_AUTHORIZATION']), 6)) ;
$userpass = @base64_decode(substr(trim($authHeader), 6)) ;
if (strlen($userpass)) {
list($name, $password) = explode(':', $userpass);
$_SERVER['PHP_AUTH_USER'] = $name;
@ -92,11 +85,10 @@ function api_login()
}
/* OpenWebAuth */
if (str_starts_with(trim($_SERVER['HTTP_AUTHORIZATION']), 'Signature')) {
if (str_starts_with(trim($authHeader), 'Signature')) {
$record = null;
$sigblock = HTTPSig::parse_sigheader($_SERVER['HTTP_AUTHORIZATION']);
$sigblock = HTTPSig::parse_sigheader($authHeader);
if ($sigblock) {
$keyId = str_replace('acct:', '', $sigblock['keyId']);
if ($keyId) {