diff options
author | Harald Eilertsen <haraldei@anduin.net> | 2025-01-29 18:32:56 +0100 |
---|---|---|
committer | Harald Eilertsen <haraldei@anduin.net> | 2025-01-29 18:41:40 +0100 |
commit | a550c7c85354950b981bb49dbc519f83f89026a7 (patch) | |
tree | c3a71b5e2d4e385278531ea451f8f9cc73516c78 /Zotlabs | |
parent | 03d1f3383ed56ddcdaee844f435a39c4b987cd74 (diff) | |
download | volse-hubzilla-a550c7c85354950b981bb49dbc519f83f89026a7.tar.gz volse-hubzilla-a550c7c85354950b981bb49dbc519f83f89026a7.tar.bz2 volse-hubzilla-a550c7c85354950b981bb49dbc519f83f89026a7.zip |
Add error message on missing owa auth headers
If the /owa endpoint received a request with a missing or invalid
Authorization header, it would return an error to the requester, but
without any message describing why it failes.
This patch adds a message to the error response, so that it will be a
bit easier to debug these issues in the future.
The owa spec includes a 'message' field in the error response, but makes
it optional. Any conforming implementations should accept a response
that includes the 'message' field.
Diffstat (limited to 'Zotlabs')
-rw-r--r-- | Zotlabs/Module/Owa.php | 184 |
1 files changed, 106 insertions, 78 deletions
diff --git a/Zotlabs/Module/Owa.php b/Zotlabs/Module/Owa.php index 85467d4f4..21082e166 100644 --- a/Zotlabs/Module/Owa.php +++ b/Zotlabs/Module/Owa.php @@ -18,96 +18,95 @@ use Zotlabs\Web\Controller; class Owa extends Controller { - function init() { + public function init(): void + { $ret = [ 'success' => false ]; - if (array_key_exists('REDIRECT_REMOTE_USER',$_SERVER) && (! array_key_exists('HTTP_AUTHORIZATION',$_SERVER))) { - $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_REMOTE_USER']; + if (!$this->validateAuthorizationHeader()) { + $this->error('Missing or invalid authorization header.'); } - if (array_key_exists('HTTP_AUTHORIZATION',$_SERVER) && substr(trim($_SERVER['HTTP_AUTHORIZATION']),0,9) === 'Signature') { - $sigblock = HTTPSig::parse_sigheader($_SERVER['HTTP_AUTHORIZATION']); - if ($sigblock) { - $keyId = $sigblock['keyId']; - $parsed = parse_url($keyId); - if (str_starts_with($parsed['scheme'],'http')) { - unset($parsed['fragment']); - unset($parsed['query']); - $keyId = unparse_url($parsed); - } - else { - $keyId = str_replace('acct:', '', $keyId); + $sigblock = HTTPSig::parse_sigheader($_SERVER['HTTP_AUTHORIZATION']); + if ($sigblock) { + $keyId = $sigblock['keyId']; + $parsed = parse_url($keyId); + if (str_starts_with($parsed['scheme'],'http')) { + unset($parsed['fragment']); + unset($parsed['query']); + $keyId = unparse_url($parsed); + } + else { + $keyId = str_replace('acct:', '', $keyId); + } + if ($keyId) { + $r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash + WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s' OR xchan_hash = '%s') + AND hubloc_deleted = 0 AND xchan_pubkey != '' + ORDER BY hubloc_id DESC", + dbesc($keyId), + dbesc($keyId), + dbesc($keyId) + ); + if (! $r) { + $found = discover_by_webbie($keyId); + logger('found = ' . print_r($found, true)); + if ($found) { + $r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash + WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s' OR xchan_hash = '%s') AND hubloc_deleted = 0 AND xchan_pubkey != '' ORDER BY hubloc_id DESC ", + dbesc($keyId), + dbesc($keyId), + dbesc($keyId) + ); + } } - if ($keyId) { - $r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash - WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s' OR xchan_hash = '%s') - AND hubloc_deleted = 0 AND xchan_pubkey != '' - ORDER BY hubloc_id DESC", - dbesc($keyId), - dbesc($keyId), - dbesc($keyId) - ); - if (! $r) { + + if ($r) { + foreach ($r as $hubloc) { + $verified = HTTPSig::verify(file_get_contents('php://input'), $hubloc['xchan_pubkey']); + if ($verified && $verified['header_signed'] && $verified['header_valid'] && ($verified['content_valid'] || (! $verified['content_signed']))) { + logger('OWA header: ' . print_r($verified,true),LOGGER_DATA); + logger('OWA success: ' . $hubloc['hubloc_id_url'],LOGGER_DATA); + $ret['success'] = true; + $token = random_string(32); + Verify::create('owt',0,$token,$hubloc['hubloc_id_url']); + $result = ''; + openssl_public_encrypt($token,$result,$hubloc['xchan_pubkey']); + $ret['encrypted_token'] = base64url_encode($result); + break; + } else { + logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_id_url']); + } + } + + if (!$ret['success']) { + + // Possible a reinstall? + // In this case we probably already have an old hubloc + // but not the new one yet. + $found = discover_by_webbie($keyId); - logger('found = ' . print_r($found, true)); + if ($found) { $r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash - WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s' OR xchan_hash = '%s') AND hubloc_deleted = 0 AND xchan_pubkey != '' ORDER BY hubloc_id DESC ", - dbesc($keyId), - dbesc($keyId), + WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s') AND hubloc_deleted = 0 ORDER BY hubloc_id DESC LIMIT 1", + dbesc(str_replace('acct:', '', $keyId)), dbesc($keyId) ); - } - } - - if ($r) { - foreach ($r as $hubloc) { - $verified = HTTPSig::verify(file_get_contents('php://input'), $hubloc['xchan_pubkey']); - if ($verified && $verified['header_signed'] && $verified['header_valid'] && ($verified['content_valid'] || (! $verified['content_signed']))) { - logger('OWA header: ' . print_r($verified,true),LOGGER_DATA); - logger('OWA success: ' . $hubloc['hubloc_id_url'],LOGGER_DATA); - $ret['success'] = true; - $token = random_string(32); - Verify::create('owt',0,$token,$hubloc['hubloc_id_url']); - $result = ''; - openssl_public_encrypt($token,$result,$hubloc['xchan_pubkey']); - $ret['encrypted_token'] = base64url_encode($result); - break; - } else { - logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_id_url']); - } - } - if (!$ret['success']) { - - // Possible a reinstall? - // In this case we probably already have an old hubloc - // but not the new one yet. - - $found = discover_by_webbie($keyId); - - if ($found) { - $r = q("SELECT * FROM hubloc LEFT JOIN xchan ON hubloc_hash = xchan_hash - WHERE (hubloc_addr = '%s' OR hubloc_id_url = '%s') AND hubloc_deleted = 0 ORDER BY hubloc_id DESC LIMIT 1", - dbesc(str_replace('acct:', '', $keyId)), - dbesc($keyId) - ); - - if ($r) { - $verified = HTTPSig::verify(file_get_contents('php://input'), $r[0]['xchan_pubkey']); - if ($verified && $verified['header_signed'] && $verified['header_valid'] && ($verified['content_valid'] || (! $verified['content_signed']))) { - logger('OWA header: ' . print_r($verified,true), LOGGER_DATA); - logger('OWA success: ' . $r[0]['hubloc_id_url'], LOGGER_DATA); - $ret['success'] = true; - $token = random_string(32); - Verify::create('owt', 0, $token, $r[0]['hubloc_id_url']); - $result = ''; - openssl_public_encrypt($token, $result, $r[0]['xchan_pubkey']); - $ret['encrypted_token'] = base64url_encode($result); - } else { - logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_id_url']); - } + if ($r) { + $verified = HTTPSig::verify(file_get_contents('php://input'), $r[0]['xchan_pubkey']); + if ($verified && $verified['header_signed'] && $verified['header_valid'] && ($verified['content_valid'] || (! $verified['content_signed']))) { + logger('OWA header: ' . print_r($verified,true), LOGGER_DATA); + logger('OWA success: ' . $r[0]['hubloc_id_url'], LOGGER_DATA); + $ret['success'] = true; + $token = random_string(32); + Verify::create('owt', 0, $token, $r[0]['hubloc_id_url']); + $result = ''; + openssl_public_encrypt($token, $result, $r[0]['xchan_pubkey']); + $ret['encrypted_token'] = base64url_encode($result); + } else { + logger('OWA fail: ' . $hubloc['hubloc_id'] . ' ' . $hubloc['hubloc_id_url']); } } } @@ -118,4 +117,33 @@ class Owa extends Controller { json_return_and_die($ret,'application/x-zot+json'); } + + private function validateAuthorizationHeader(): bool + { + if (!empty($_SERVER['HTTP_AUTHORIZATION'])) { + $auth = trim($_SERVER['HTTP_AUTHORIZATION']); + } else if (!empty($_SERVER['REDIRECT_REMOTE_USER'])) { + $auth = trim($_SERVER['REDIRECT_REMOTE_USER']); + } else { + return false; + } + + return strncmp($auth, 'Signature', 9) === 0; + } + + /** + * Terminates the request, and return a json error response. + * + * @Note This function does not return! + * + * @param string $msg The error message for the response. + */ + private function error(string $msg): void { + $ret = [ + 'success' => false, + 'message' => $msg + ]; + + json_return_and_die($ret,'application/x-zot+json'); + } } |