mirror of
https://github.com/friendica/friendica
synced 2025-02-11 13:34:01 +00:00
Merge pull request #14700 from annando/get-signer
Issue 14692: Prevent loops with remote servers
This commit is contained in:
commit
3d1ab8c5b9
1 changed files with 38 additions and 30 deletions
|
@ -57,11 +57,13 @@ class HTTPSignature
|
||||||
|
|
||||||
// Decide if $data arrived via controller submission or curl.
|
// Decide if $data arrived via controller submission or curl.
|
||||||
$headers = [];
|
$headers = [];
|
||||||
|
|
||||||
$headers['(request-target)'] = strtolower(DI::args()->getMethod()) . ' ' . $_SERVER['REQUEST_URI'];
|
$headers['(request-target)'] = strtolower(DI::args()->getMethod()) . ' ' . $_SERVER['REQUEST_URI'];
|
||||||
|
|
||||||
foreach ($_SERVER as $k => $v) {
|
foreach ($_SERVER as $k => $v) {
|
||||||
if (strpos($k, 'HTTP_') === 0) {
|
if (strpos($k, 'HTTP_') === 0) {
|
||||||
$field = str_replace('_', '-', strtolower(substr($k, 5)));
|
$field = str_replace('_', '-', strtolower(substr($k, 5)));
|
||||||
|
|
||||||
$headers[$field] = $v;
|
$headers[$field] = $v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,6 +100,7 @@ class HTTPSignature
|
||||||
|
|
||||||
if ($key && function_exists($key)) {
|
if ($key && function_exists($key)) {
|
||||||
$result['signer'] = $sig_block['keyId'];
|
$result['signer'] = $sig_block['keyId'];
|
||||||
|
|
||||||
$key = $key($sig_block['keyId']);
|
$key = $key($sig_block['keyId']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,7 +390,7 @@ class HTTPSignature
|
||||||
* @param int $gsid Server ID
|
* @param int $gsid Server ID
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
static public function setInboxStatus(string $url, bool $success, bool $shared = false, int $gsid = null)
|
public static function setInboxStatus(string $url, bool $success, bool $shared = false, int $gsid = null)
|
||||||
{
|
{
|
||||||
$now = DateTimeFormat::utcNow();
|
$now = DateTimeFormat::utcNow();
|
||||||
|
|
||||||
|
@ -604,13 +607,14 @@ class HTTPSignature
|
||||||
/**
|
/**
|
||||||
* Gets a signer from a given HTTP request
|
* Gets a signer from a given HTTP request
|
||||||
*
|
*
|
||||||
* @param string $content
|
* @param string $content Body of the request
|
||||||
* @param array $http_headers
|
* @param array $http_headers array containing the HTTP headers
|
||||||
|
* @param ?boolean $update true = always update, false = never update, null = update when not found or outdated
|
||||||
*
|
*
|
||||||
* @return string|null|false Signer
|
* @return string|null|false Signer
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
public static function getSigner(string $content, array $http_headers)
|
public static function getSigner(string $content, array $http_headers, ?bool $update = null)
|
||||||
{
|
{
|
||||||
if (empty($http_headers['HTTP_SIGNATURE'])) {
|
if (empty($http_headers['HTTP_SIGNATURE'])) {
|
||||||
DI::logger()->debug('No HTTP_SIGNATURE header');
|
DI::logger()->debug('No HTTP_SIGNATURE header');
|
||||||
|
@ -630,11 +634,13 @@ class HTTPSignature
|
||||||
}
|
}
|
||||||
|
|
||||||
$headers = [];
|
$headers = [];
|
||||||
|
|
||||||
$headers['(request-target)'] = strtolower(DI::args()->getMethod()) . ' ' . parse_url($http_headers['REQUEST_URI'], PHP_URL_PATH);
|
$headers['(request-target)'] = strtolower(DI::args()->getMethod()) . ' ' . parse_url($http_headers['REQUEST_URI'], PHP_URL_PATH);
|
||||||
|
|
||||||
// First take every header
|
// First take every header
|
||||||
foreach ($http_headers as $k => $v) {
|
foreach ($http_headers as $k => $v) {
|
||||||
$field = str_replace('_', '-', strtolower($k));
|
$field = str_replace('_', '-', strtolower($k));
|
||||||
|
|
||||||
$headers[$field] = $v;
|
$headers[$field] = $v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,6 +648,7 @@ class HTTPSignature
|
||||||
foreach ($http_headers as $k => $v) {
|
foreach ($http_headers as $k => $v) {
|
||||||
if (strpos($k, 'HTTP_') === 0) {
|
if (strpos($k, 'HTTP_') === 0) {
|
||||||
$field = str_replace('_', '-', strtolower(substr($k, 5)));
|
$field = str_replace('_', '-', strtolower(substr($k, 5)));
|
||||||
|
|
||||||
$headers[$field] = $v;
|
$headers[$field] = $v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -700,7 +707,7 @@ class HTTPSignature
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$key = self::fetchKey($sig_block['keyId'], $actor);
|
$key = self::fetchKey($sig_block['keyId'], $actor, $update);
|
||||||
if (empty($key)) {
|
if (empty($key)) {
|
||||||
DI::logger()->info('Empty key');
|
DI::logger()->info('Empty key');
|
||||||
return false;
|
return false;
|
||||||
|
@ -802,17 +809,18 @@ class HTTPSignature
|
||||||
/**
|
/**
|
||||||
* fetches a key for a given id and actor
|
* fetches a key for a given id and actor
|
||||||
*
|
*
|
||||||
* @param string $id
|
* @param string $id keyId of the signature block
|
||||||
* @param string $actor
|
* @param string $actor Actor URI
|
||||||
|
* @param ?boolean $update true = always update, false = never update, null = update when not found or outdated
|
||||||
*
|
*
|
||||||
* @return array with actor url and public key
|
* @return array with actor url and public key
|
||||||
* @throws \Exception
|
* @throws \Exception
|
||||||
*/
|
*/
|
||||||
private static function fetchKey(string $id, string $actor): array
|
private static function fetchKey(string $id, string $actor, ?bool $update = null): array
|
||||||
{
|
{
|
||||||
$url = (strpos($id, '#') ? substr($id, 0, strpos($id, '#')) : $id);
|
$url = (strpos($id, '#') ? substr($id, 0, strpos($id, '#')) : $id);
|
||||||
|
|
||||||
$profile = APContact::getByURL($url);
|
$profile = APContact::getByURL($url, $update);
|
||||||
if (!empty($profile)) {
|
if (!empty($profile)) {
|
||||||
DI::logger()->info('Taking key from id', ['id' => $id]);
|
DI::logger()->info('Taking key from id', ['id' => $id]);
|
||||||
return ['url' => $url, 'pubkey' => $profile['pubkey'], 'type' => $profile['type']];
|
return ['url' => $url, 'pubkey' => $profile['pubkey'], 'type' => $profile['type']];
|
||||||
|
|
Loading…
Add table
Reference in a new issue