mirror of
https://framagit.org/hubzilla/core.git
synced 2026-06-22 09:17:57 -04:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06273e980e | ||
|
|
c879e5de44 | ||
|
|
890290fff0 | ||
|
|
cddae14352 | ||
|
|
b3e6a3c1e2 | ||
|
|
255b6a14a8 |
10
CHANGELOG
10
CHANGELOG
@@ -1,3 +1,13 @@
|
||||
Hubzilla 5.0.1 (2020-11-12)
|
||||
- Fix share title size
|
||||
- Fix issue where hublocs could get mixed up between different protocols
|
||||
|
||||
Addons
|
||||
- Pubcrawl: implement authenticated profile fetches which are now partly required in mastodon
|
||||
- Sse: call xchan_query() just once per item
|
||||
- Pubcrawl: reject messages where sender is not the author if ld-signature is not ok
|
||||
|
||||
|
||||
Hubzilla 5.0 (2020-11-05)
|
||||
- Remove unmaintained and deprecated schemas
|
||||
- Deprecate HTML5_Parser library
|
||||
|
||||
@@ -104,6 +104,7 @@ class Activity {
|
||||
}
|
||||
else {
|
||||
logger('fetch failed: ' . $url);
|
||||
logger($x['body']);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ class JSalmon {
|
||||
. base64url_encode($x['encoding'],true) . '.'
|
||||
. base64url_encode($x['alg'],true);
|
||||
|
||||
$key = HTTPSig::get_key(EMPTY_STR,base64url_decode($x['sigs']['key_id']));
|
||||
$key = HTTPSig::get_key(EMPTY_STR,'zot6',base64url_decode($x['sigs']['key_id']));
|
||||
logger('key: ' . print_r($key,true));
|
||||
if($key['portable_id'] && $key['public_key']) {
|
||||
if(rsa_verify($signed_data,base64url_decode($x['sigs']['value']),$key['public_key'])) {
|
||||
|
||||
@@ -93,7 +93,8 @@ class LDSignatures {
|
||||
$d = jsonld_normalize($data,[ 'algorithm' => 'URDNA2015', 'format' => 'application/nquads' ]);
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
logger('normalise error:' . print_r($e,true));
|
||||
// Don't log the exception - this can exhaust memory
|
||||
// logger('normalise error:' . print_r($e,true));
|
||||
logger('normalise error: ' . print_r($data,true));
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ class Share {
|
||||
"' message_id='" . $this->item['mid'] .
|
||||
"']";
|
||||
if($this->item['title'])
|
||||
$bb .= '[b]'.$this->item['title'].'[/b]'."\r\n";
|
||||
$bb .= '[h3][b]'.$this->item['title'].'[/b][/h3]'."\r\n";
|
||||
$bb .= (($is_photo) ? $photo_bb . "\r\n" . $this->item['body'] : $this->item['body']);
|
||||
$bb .= "[/share]";
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ use Zotlabs\Web\HTTPSig;
|
||||
|
||||
class Zotfinger {
|
||||
|
||||
static function exec($resource,$channel = null) {
|
||||
static function exec($resource,$channel = null, $verify = true) {
|
||||
|
||||
if(! $resource) {
|
||||
return false;
|
||||
@@ -41,8 +41,9 @@ class Zotfinger {
|
||||
logger('fetch: ' . print_r($x,true));
|
||||
|
||||
if($x['success']) {
|
||||
|
||||
$result['signature'] = HTTPSig::verify($x);
|
||||
if ($verify) {
|
||||
$result['signature'] = HTTPSig::verify($x, EMPTY_STR, 'zot6');
|
||||
}
|
||||
|
||||
$result['data'] = json_decode($x['body'],true);
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ class Channel extends Controller {
|
||||
|
||||
if(Libzot::is_zot_request()) {
|
||||
|
||||
$sigdata = HTTPSig::verify(file_get_contents('php://input'));
|
||||
$sigdata = HTTPSig::verify(file_get_contents('php://input'), EMPTY_STR, 'zot6');
|
||||
|
||||
if($sigdata && $sigdata['signer'] && $sigdata['header_valid']) {
|
||||
$data = json_encode(Libzot::zotinfo([ 'address' => $channel['channel_address'], 'target_url' => $sigdata['signer'] ]));
|
||||
|
||||
@@ -294,8 +294,8 @@ class Connedit extends Controller {
|
||||
intval($channel['channel_id'])
|
||||
);
|
||||
if(($pr) && (! intval($orig_record[0]['abook_hidden'])) && (intval(get_pconfig($channel['channel_id'],'system','post_newfriend')))) {
|
||||
$xarr = array();
|
||||
$xarr['verb'] = ACTIVITY_FRIEND;
|
||||
$xarr = [];
|
||||
|
||||
$xarr['item_wall'] = 1;
|
||||
$xarr['item_origin'] = 1;
|
||||
$xarr['item_thread_top'] = 1;
|
||||
@@ -305,17 +305,6 @@ class Connedit extends Controller {
|
||||
$xarr['deny_cid'] = $channel['channel_deny_cid'];
|
||||
$xarr['deny_gid'] = $channel['channel_deny_gid'];
|
||||
$xarr['item_private'] = (($xarr['allow_cid']||$xarr['allow_gid']||$xarr['deny_cid']||$xarr['deny_gid']) ? 1 : 0);
|
||||
$obj = array(
|
||||
'type' => ACTIVITY_OBJ_PERSON,
|
||||
'title' => App::$poi['xchan_name'],
|
||||
'id' => App::$poi['xchan_hash'],
|
||||
'link' => array(
|
||||
array('rel' => 'alternate', 'type' => 'text/html', 'href' => App::$poi['xchan_url']),
|
||||
array('rel' => 'photo', 'type' => App::$poi['xchan_photo_mimetype'], 'href' => App::$poi['xchan_photo_l'])
|
||||
),
|
||||
);
|
||||
$xarr['obj'] = json_encode($obj);
|
||||
$xarr['obj_type'] = ACTIVITY_OBJ_PERSON;
|
||||
|
||||
$xarr['body'] = '[zrl=' . $channel['xchan_url'] . ']' . $channel['xchan_name'] . '[/zrl]' . ' ' . t('is now connected to') . ' ' . '[zrl=' . App::$poi['xchan_url'] . ']' . App::$poi['xchan_name'] . '[/zrl]';
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class Zot_probe extends \Zotlabs\Web\Controller {
|
||||
|
||||
$o .= '<pre>' . htmlspecialchars($x['header']) . '</pre>' . EOL;
|
||||
|
||||
$o .= 'verify returns: ' . str_replace("\n",EOL,print_r(HTTPSig::verify($x),true)) . EOL;
|
||||
$o .= 'verify returns: ' . str_replace("\n",EOL,print_r(HTTPSig::verify($x, EMPTY_STR, 'zot6'),true)) . EOL;
|
||||
|
||||
$o .= '<pre>' . htmlspecialchars(json_encode(json_decode($x['body']),JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)) . '</pre>' . EOL;
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ class HTTPSig {
|
||||
|
||||
// See draft-cavage-http-signatures-10
|
||||
|
||||
static function verify($data,$key = '') {
|
||||
static function verify($data,$key = '', $keytype = '') {
|
||||
|
||||
$body = $data;
|
||||
$headers = null;
|
||||
@@ -151,7 +151,7 @@ class HTTPSig {
|
||||
|
||||
$result['signer'] = $sig_block['keyId'];
|
||||
|
||||
$key = self::get_key($key,$result['signer']);
|
||||
$key = self::get_key($key,$keytype,$result['signer']);
|
||||
|
||||
if(! ($key && $key['public_key'])) {
|
||||
return $result;
|
||||
@@ -162,13 +162,26 @@ class HTTPSig {
|
||||
logger('verified: ' . $x, LOGGER_DEBUG);
|
||||
|
||||
if(! $x) {
|
||||
logger('verify failed for ' . $result['signer'] . ' alg=' . $algorithm . (($key['public_key']) ? '' : ' no key'));
|
||||
$sig_block['signature'] = base64_encode($sig_block['signature']);
|
||||
logger('affected sigblock: ' . print_r($sig_block,true));
|
||||
logger('signed_data: ' . print_r($signed_data,true));
|
||||
logger('headers: ' . print_r($headers,true));
|
||||
logger('server: ' . print_r($_SERVER,true));
|
||||
return $result;
|
||||
|
||||
// try again, ignoring the local actor (xchan) cache and refetching the key
|
||||
// from its source
|
||||
|
||||
$fkey = self::get_key($key,$keytype,$result['signer'],true);
|
||||
|
||||
if ($fkey && $fkey['public_key']) {
|
||||
$y = rsa_verify($signed_data,$sig_block['signature'],$fkey['public_key'],$algorithm);
|
||||
logger('verified: (cache reload) ' . $x, LOGGER_DEBUG);
|
||||
}
|
||||
|
||||
if (! $y) {
|
||||
logger('verify failed for ' . $result['signer'] . ' alg=' . $algorithm . (($fkey['public_key']) ? '' : ' no key'));
|
||||
$sig_block['signature'] = base64_encode($sig_block['signature']);
|
||||
logger('affected sigblock: ' . print_r($sig_block,true));
|
||||
logger('headers: ' . print_r($headers,true));
|
||||
logger('server: ' . print_r($_SERVER,true));
|
||||
return $result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$result['portable_id'] = $key['portable_id'];
|
||||
@@ -187,12 +200,17 @@ class HTTPSig {
|
||||
}
|
||||
|
||||
logger('Content_Valid: ' . (($result['content_valid']) ? 'true' : 'false'));
|
||||
if (! $result['content_valid']) {
|
||||
logger('invalid content signature: data ' . print_r($data,true));
|
||||
logger('invalid content signature: headers ' . print_r($headers,true));
|
||||
logger('invalid content signature: body ' . print_r($body,true));
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
static function get_key($key,$id) {
|
||||
static function get_key($key,$keytype,$id) {
|
||||
|
||||
if($key) {
|
||||
if(function_exists($key)) {
|
||||
@@ -201,6 +219,13 @@ class HTTPSig {
|
||||
return [ 'public_key' => $key ];
|
||||
}
|
||||
|
||||
if($keytype === 'zot6') {
|
||||
$key = self::get_zotfinger_key($id,$force);
|
||||
if($key) {
|
||||
return $key;
|
||||
}
|
||||
}
|
||||
|
||||
if(strpos($id,'#') === false) {
|
||||
$key = self::get_webfinger_key($id);
|
||||
}
|
||||
@@ -243,7 +268,7 @@ class HTTPSig {
|
||||
|
||||
$url = ((strpos($id,'#')) ? substr($id,0,strpos($id,'#')) : $id);
|
||||
|
||||
$x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s'",
|
||||
$x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s' and hubloc_network in ('zot6', 'activitypub')",
|
||||
dbesc(str_replace('acct:','',$url)),
|
||||
dbesc($url)
|
||||
);
|
||||
@@ -303,18 +328,15 @@ class HTTPSig {
|
||||
return (($key['public_key']) ? $key : false);
|
||||
}
|
||||
|
||||
|
||||
function get_zotfinger_key($id) {
|
||||
|
||||
$x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s'",
|
||||
$x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_addr = '%s' or hubloc_id_url = '%s' and hubloc_network = 'zot6'",
|
||||
dbesc(str_replace('acct:','',$id)),
|
||||
dbesc($id)
|
||||
);
|
||||
|
||||
$x = Libzot::zot_record_preferred($x);
|
||||
|
||||
if($x && $x['xchan_pubkey']) {
|
||||
return [ 'portable_id' => $x['xchan_hash'], 'public_key' => $x['xchan_pubkey'] , 'hubloc' => $x ];
|
||||
if($x && $x[0]['xchan_pubkey']) {
|
||||
return [ 'portable_id' => $x[0]['xchan_hash'], 'public_key' => $x[0]['xchan_pubkey'] , 'hubloc' => $x[0] ];
|
||||
}
|
||||
|
||||
$wf = Webfinger::exec($id);
|
||||
@@ -330,13 +352,18 @@ class HTTPSig {
|
||||
continue;
|
||||
}
|
||||
if($l['rel'] === 'http://purl.org/zot/protocol/6.0' && array_key_exists('href',$l) && $l['href'] !== EMPTY_STR) {
|
||||
$z = \Zotlabs\Lib\Zotfinger::exec($l['href']);
|
||||
|
||||
// The third argument to Zotfinger::exec() tells it not to verify signatures
|
||||
// Since we're inside a function that is fetching keys with which to verify signatures,
|
||||
// this is necessary to prevent infinite loops.
|
||||
|
||||
$z = \Zotlabs\Lib\Zotfinger::exec($l['href'],null,false);
|
||||
if($z) {
|
||||
$i = Libzot::import_xchan($z['data']);
|
||||
if($i['success']) {
|
||||
$key['portable_id'] = $i['hash'];
|
||||
|
||||
$x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' limit 1",
|
||||
$x = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where hubloc_id_url = '%s' and hubloc_network = 'zot6'",
|
||||
dbesc($l['href'])
|
||||
);
|
||||
if($x) {
|
||||
@@ -485,7 +512,6 @@ class HTTPSig {
|
||||
|
||||
if(preg_match('/iv="(.*?)"/ism',$header,$matches))
|
||||
$header = self::decrypt_sigheader($header);
|
||||
|
||||
if(preg_match('/keyId="(.*?)"/ism',$header,$matches))
|
||||
$ret['keyId'] = $matches[1];
|
||||
if(preg_match('/algorithm="(.*?)"/ism',$header,$matches))
|
||||
|
||||
@@ -155,7 +155,7 @@ class Receiver {
|
||||
|
||||
$result = false;
|
||||
|
||||
$this->sigdata = HTTPSig::verify($this->rawdata);
|
||||
$this->sigdata = HTTPSig::verify($this->rawdata, EMPTY_STR, 'zot6');
|
||||
|
||||
if ($this->sigdata && $this->sigdata['header_signed'] && $this->sigdata['header_valid']) {
|
||||
$result = true;
|
||||
|
||||
Reference in New Issue
Block a user