mirror of
https://codeberg.org/streams/streams.git
synced 2024-09-22 00:15:23 +00:00
better signature handling
This commit is contained in:
parent
2e9e82662a
commit
c4ea93e6a6
13 changed files with 91 additions and 87 deletions
|
@ -13,6 +13,7 @@ class ActivityStreams {
|
||||||
public $raw = null;
|
public $raw = null;
|
||||||
public $data = null;
|
public $data = null;
|
||||||
public $valid = false;
|
public $valid = false;
|
||||||
|
public $deleted = false;
|
||||||
public $id = '';
|
public $id = '';
|
||||||
public $parent_id = '';
|
public $parent_id = '';
|
||||||
public $type = '';
|
public $type = '';
|
||||||
|
@ -67,6 +68,13 @@ class ActivityStreams {
|
||||||
|
|
||||||
$this->valid = true;
|
$this->valid = true;
|
||||||
|
|
||||||
|
if(array_key_exists('type',$this->data) && array_key_exists('actor',$this->data) && array_key_exists('object',$this->data)) {
|
||||||
|
if($this->data['type'] === 'Delete' && $this->data['actor'] === $this->data['object']) {
|
||||||
|
$this->deleted = $this->data['actor'];
|
||||||
|
$this->valid = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if($this->is_valid()) {
|
if($this->is_valid()) {
|
||||||
|
|
|
@ -12,10 +12,18 @@ class Zotfinger {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($channel) {
|
$m = parse_url($resource);
|
||||||
|
|
||||||
|
$data = json_encode([ 'zot_token' => random_string() ]);
|
||||||
|
|
||||||
|
if($channel && $m) {
|
||||||
|
|
||||||
$headers = [
|
$headers = [
|
||||||
'Accept' => 'application/x-zot+json',
|
'Accept' => 'application/x-zot+json',
|
||||||
'X-Zot-Token' => random_string(),
|
'Content-Type' => 'application/x-zot+json',
|
||||||
|
'X-Zot-Token' => random_string(),
|
||||||
|
'Digest' => HTTPSig::generate_digest_header($data),
|
||||||
|
'Host' => $m['host'],
|
||||||
];
|
];
|
||||||
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false);
|
$h = HTTPSig::create_sig($headers,$channel['channel_prvkey'],channel_url($channel),false);
|
||||||
}
|
}
|
||||||
|
@ -27,7 +35,7 @@ class Zotfinger {
|
||||||
|
|
||||||
|
|
||||||
$redirects = 0;
|
$redirects = 0;
|
||||||
$x = z_fetch_url($resource,false,$redirects, [ 'headers' => $h ] );
|
$x = z_post_url($resource,$data,$redirects, [ 'headers' => $h ] );
|
||||||
|
|
||||||
if($x['success']) {
|
if($x['success']) {
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ class Channel extends Controller {
|
||||||
|
|
||||||
if(Libzot::is_zot_request()) {
|
if(Libzot::is_zot_request()) {
|
||||||
|
|
||||||
$sigdata = HTTPSig::verify(EMPTY_STR);
|
$sigdata = HTTPSig::verify(file_get_contents('php://input'));
|
||||||
|
|
||||||
if($sigdata && $sigdata['signer'] && $sigdata['header_valid']) {
|
if($sigdata && $sigdata['signer'] && $sigdata['header_valid']) {
|
||||||
$data = json_encode(Libzot::zotinfo([ 'address' => $channel['channel_address'], 'target_url' => $sigdata['signer'] ]));
|
$data = json_encode(Libzot::zotinfo([ 'address' => $channel['channel_address'], 'target_url' => $sigdata['signer'] ]));
|
||||||
|
|
|
@ -39,8 +39,19 @@ class Inbox extends Controller {
|
||||||
|
|
||||||
//logger('debug: ' . $AS->debug());
|
//logger('debug: ' . $AS->debug());
|
||||||
|
|
||||||
if(! $AS->is_valid())
|
if(! $AS->is_valid()) {
|
||||||
|
if($AS->deleted) {
|
||||||
|
// process mastodon user deletion activities, but only if we can validate the signature
|
||||||
|
if($hsig['header_valid'] && $hsig['content_valid'] && $hsig['portable_id']) {
|
||||||
|
logger('removing deleted actor');
|
||||||
|
remove_all_xchan_resources($hsig['portable_id']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
logger('ignoring deleted actor');
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// $observer_hash in this case is the sender
|
// $observer_hash in this case is the sender
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@ class Magic extends \Zotlabs\Web\Controller {
|
||||||
$dest = hex2bin($bdest);
|
$dest = hex2bin($bdest);
|
||||||
|
|
||||||
$parsed = parse_url($dest);
|
$parsed = parse_url($dest);
|
||||||
|
|
||||||
if(! $parsed) {
|
if(! $parsed) {
|
||||||
if($test) {
|
if($test) {
|
||||||
$ret['message'] .= 'could not parse ' . $dest . EOL;
|
$ret['message'] .= 'could not parse ' . $dest . EOL;
|
||||||
|
@ -35,56 +36,12 @@ class Magic extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
$basepath = $parsed['scheme'] . '://' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : '');
|
$basepath = $parsed['scheme'] . '://' . $parsed['host'] . (($parsed['port']) ? ':' . $parsed['port'] : '');
|
||||||
|
|
||||||
$x = q("select * from hubloc where hubloc_url = '%s' order by hubloc_connected desc limit 1",
|
|
||||||
dbesc($basepath)
|
|
||||||
);
|
|
||||||
|
|
||||||
if(! $x) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We have no records for, or prior communications with this hub.
|
|
||||||
* If an address was supplied, let's finger them to create a hub record.
|
|
||||||
* Otherwise we'll use the special address '[system]' which will return
|
|
||||||
* either a system channel or the first available normal channel. We don't
|
|
||||||
* really care about what channel is returned - we need the hub information
|
|
||||||
* from that response so that we can create signed auth packets destined
|
|
||||||
* for that hub.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
$j = \Zotlabs\Zot\Finger::run((($addr) ? $addr : '[system]@' . $parsed['host']),null);
|
|
||||||
if($j['success']) {
|
|
||||||
Libzot::import_xchan($j);
|
|
||||||
|
|
||||||
// Now try again
|
|
||||||
|
|
||||||
$x = q("select * from hubloc where hubloc_url = '%s' order by hubloc_connected desc limit 1",
|
|
||||||
dbesc($basepath)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(! $x) {
|
|
||||||
if($rev)
|
|
||||||
goaway($dest);
|
|
||||||
else {
|
|
||||||
logger('mod_magic: no channels found for requested hub.' . print_r($_REQUEST,true));
|
|
||||||
if($test) {
|
|
||||||
$ret['message'] .= 'This site has no previous connections with ' . $basepath . EOL;
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
notice( t('Hub not found.') . EOL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// This is ready-made for a plugin that provides a blacklist or "ask me" before blindly authenticating.
|
// This is ready-made for a plugin that provides a blacklist or "ask me" before blindly authenticating.
|
||||||
// By default, we'll proceed without asking.
|
// By default, we'll proceed without asking.
|
||||||
|
|
||||||
$arr = array(
|
$arr = array(
|
||||||
'channel_id' => local_channel(),
|
'channel_id' => local_channel(),
|
||||||
'xchan' => $x[0],
|
|
||||||
'destination' => $dest,
|
'destination' => $dest,
|
||||||
'proceed' => true
|
'proceed' => true
|
||||||
);
|
);
|
||||||
|
@ -137,11 +94,16 @@ class Magic extends \Zotlabs\Web\Controller {
|
||||||
$dest = strip_zids($dest);
|
$dest = strip_zids($dest);
|
||||||
$dest = strip_query_param($dest,'f');
|
$dest = strip_query_param($dest,'f');
|
||||||
|
|
||||||
|
$data = json_encode([ 'OpenWebAuth' => random_string() ]);
|
||||||
|
|
||||||
$headers = [];
|
$headers = [];
|
||||||
$headers['Accept'] = 'application/x-zot+json' ;
|
$headers['Accept'] = 'application/x-zot+json' ;
|
||||||
$headers['X-Open-Web-Auth'] = random_string();
|
$headers['X-Open-Web-Auth'] = random_string();
|
||||||
|
$headers['Digest'] = HTTPSig::generate_digest_header($data);
|
||||||
|
$headers['Host'] = $parsed['host'];
|
||||||
|
|
||||||
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512');
|
$headers = HTTPSig::create_sig($headers,$channel['channel_prvkey'], channel_url($channel),true,'sha512');
|
||||||
$x = z_fetch_url($basepath . '/owa',false,$redirects,[ 'headers' => $headers ]);
|
$x = z_post_url($basepath . '/owa',$data,$redirects,[ 'headers' => $headers ]);
|
||||||
|
|
||||||
if($x['success']) {
|
if($x['success']) {
|
||||||
$j = json_decode($x['body'],true);
|
$j = json_decode($x['body'],true);
|
||||||
|
|
|
@ -52,8 +52,8 @@ class Owa extends \Zotlabs\Web\Controller {
|
||||||
}
|
}
|
||||||
if($r) {
|
if($r) {
|
||||||
foreach($r as $hubloc) {
|
foreach($r as $hubloc) {
|
||||||
$verified = HTTPSig::verify('');
|
$verified = HTTPSig::verify(file_get_contents('php://input'));
|
||||||
if($verified && $verified['header_signed'] && $verified['header_valid']) {
|
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 header: ' . print_r($verified,true),LOGGER_DATA);
|
||||||
logger('OWA success: ' . $hubloc['hubloc_addr'],LOGGER_DATA);
|
logger('OWA success: ' . $hubloc['hubloc_addr'],LOGGER_DATA);
|
||||||
$ret['success'] = true;
|
$ret['success'] = true;
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
namespace Zotlabs\Module;
|
namespace Zotlabs\Module;
|
||||||
|
|
||||||
|
use Zotlabs\Lib\Zotfinger;
|
||||||
|
use Zotlabs\Web\Controller;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* With args, register a directory server for this realm.
|
* With args, register a directory server for this realm.
|
||||||
* With no args, return a JSON array of directory servers for this realm.
|
* With no args, return a JSON array of directory servers for this realm.
|
||||||
|
@ -14,7 +17,7 @@ namespace Zotlabs\Module;
|
||||||
* @param App &$a
|
* @param App &$a
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class Regdir extends \Zotlabs\Web\Controller {
|
class Regdir extends Controller {
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
|
@ -25,7 +28,7 @@ class Regdir extends \Zotlabs\Web\Controller {
|
||||||
$valid = 0;
|
$valid = 0;
|
||||||
|
|
||||||
// we probably don't need the realm as we will find out in the probe.
|
// we probably don't need the realm as we will find out in the probe.
|
||||||
// What we may want to die is throw an error if you're trying to register in a different realm
|
// What we may want to do is throw an error if you're trying to register in a different realm
|
||||||
// so this configuration issue can be discovered.
|
// so this configuration issue can be discovered.
|
||||||
|
|
||||||
$realm = $_REQUEST['realm'];
|
$realm = $_REQUEST['realm'];
|
||||||
|
@ -59,16 +62,13 @@ class Regdir extends \Zotlabs\Web\Controller {
|
||||||
json_return_and_die($result);
|
json_return_and_die($result);
|
||||||
}
|
}
|
||||||
|
|
||||||
$j = \Zotlabs\Zot\Finger::run('[system]@' . $m['host']);
|
$j = Zotfinger::exec($url);
|
||||||
if($j['success'] && $j['guid']) {
|
if($j) {
|
||||||
$x = import_xchan($j);
|
$result['success'] = true;
|
||||||
if($x['success']) {
|
|
||||||
$result['success'] = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if(! $result['success'])
|
|
||||||
$valid = 0;
|
$valid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
q("update site set site_valid = %d where site_url = '%s'",
|
q("update site set site_valid = %d where site_url = '%s'",
|
||||||
intval($valid),
|
intval($valid),
|
||||||
|
@ -76,17 +76,14 @@ class Regdir extends \Zotlabs\Web\Controller {
|
||||||
);
|
);
|
||||||
|
|
||||||
json_return_and_die($result);
|
json_return_and_die($result);
|
||||||
} else {
|
|
||||||
|
|
||||||
// We can put this in the sql without the condition after 31 august 2015 assuming
|
}
|
||||||
// most directory servers will have updated by then
|
else {
|
||||||
// This just makes sure it happens if I forget
|
|
||||||
|
|
||||||
$sql_extra = ((datetime_convert() > datetime_convert('UTC','UTC','2015-08-31')) ? ' and site_valid = 1 ' : '' );
|
|
||||||
if ($dirmode == DIRECTORY_MODE_STANDALONE) {
|
if ($dirmode == DIRECTORY_MODE_STANDALONE) {
|
||||||
$r = array(array('site_url' => z_root()));
|
$r = array(array('site_url' => z_root()));
|
||||||
} else {
|
} else {
|
||||||
$r = q("select site_url from site where site_flags in ( 1, 2 ) and site_realm = '%s' and site_type = %d $sql_extra ",
|
$r = q("select site_url from site where site_flags in ( 1, 2 ) and site_realm = '%s' and site_type = %d and site_valid = 1 ",
|
||||||
dbesc(get_directory_realm()),
|
dbesc(get_directory_realm()),
|
||||||
intval(SITE_TYPE_ZOT)
|
intval(SITE_TYPE_ZOT)
|
||||||
);
|
);
|
||||||
|
|
|
@ -19,9 +19,9 @@ class Zot_probe extends \Zotlabs\Web\Controller {
|
||||||
|
|
||||||
if(x($_GET,'addr')) {
|
if(x($_GET,'addr')) {
|
||||||
$addr = $_GET['addr'];
|
$addr = $_GET['addr'];
|
||||||
|
$channel = (($_GET['auth']) ? \App::get_channel() : null);
|
||||||
|
|
||||||
|
$x = Zotfinger::exec($addr,$channel);
|
||||||
$x = Zotfinger::exec($addr);
|
|
||||||
|
|
||||||
$o .= '<pre>' . htmlspecialchars(print_array($x)) . '</pre>';
|
$o .= '<pre>' . htmlspecialchars(print_array($x)) . '</pre>';
|
||||||
|
|
||||||
|
|
|
@ -120,6 +120,21 @@ class HTTPSig {
|
||||||
if(array_key_exists($h,$headers)) {
|
if(array_key_exists($h,$headers)) {
|
||||||
$signed_data .= $h . ': ' . $headers[$h] . "\n";
|
$signed_data .= $h . ': ' . $headers[$h] . "\n";
|
||||||
}
|
}
|
||||||
|
if($h === 'host' && (strpos(strtolower(\App::get_hostname()),strtolower($headers[$h])) === false)) {
|
||||||
|
logger('bad host: ' . $sig_block['keyId'] . ' != ' . $headers[$h]);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
if($h === 'date') {
|
||||||
|
$d = new \DateTime($headers[$h]);
|
||||||
|
$d->setTimeZone(new \DateTimeZone('UTC'));
|
||||||
|
$dplus = datetime_convert('UTC','UTC','now + 1 day');
|
||||||
|
$dminus = datetime_convert('UTC','UTC','now - 1 day');
|
||||||
|
$c = $d->format('Y-m-d H:i:s');
|
||||||
|
if($c > $dplus || $c < $dminus) {
|
||||||
|
logger('bad time: ' . $c);
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
$signed_data = rtrim($signed_data,"\n");
|
$signed_data = rtrim($signed_data,"\n");
|
||||||
|
|
||||||
|
|
|
@ -86,7 +86,7 @@ class Auth {
|
||||||
|
|
||||||
if(! $x) {
|
if(! $x) {
|
||||||
// finger them if they can't be found.
|
// finger them if they can't be found.
|
||||||
$j = Finger::run($address, null);
|
$j = false; // Finger::run($address, null);
|
||||||
if ($j['success']) {
|
if ($j['success']) {
|
||||||
import_xchan($j);
|
import_xchan($j);
|
||||||
$x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash
|
$x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash
|
||||||
|
|
|
@ -62,7 +62,7 @@ class Finger {
|
||||||
if($r) {
|
if($r) {
|
||||||
$url = $r[0]['hubloc_url'];
|
$url = $r[0]['hubloc_url'];
|
||||||
|
|
||||||
if($r[0]['hubloc_network'] && $r[0]['hubloc_network'] !== 'zot') {
|
if($r[0]['hubloc_network'] && (! in_array($r[0]['hubloc_network'], ['zot','zot6']))) {
|
||||||
logger('zot_finger: alternate network: ' . $webbie);
|
logger('zot_finger: alternate network: ' . $webbie);
|
||||||
logger('url: ' . $url . ', net: ' . var_export($r[0]['hubloc_network'],true), LOGGER_DATA, LOG_DEBUG);
|
logger('url: ' . $url . ', net: ' . var_export($r[0]['hubloc_network'],true), LOGGER_DATA, LOG_DEBUG);
|
||||||
return $ret;
|
return $ret;
|
||||||
|
|
|
@ -278,17 +278,20 @@ function owt_init($token) {
|
||||||
}
|
}
|
||||||
|
|
||||||
$r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash
|
$r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash
|
||||||
where hubloc_addr = '%s' order by hubloc_id desc",
|
where hubloc_addr = '%s' or hubloc_id_url = '%s' or hubloc_hash = '%s' order by hubloc_id desc",
|
||||||
|
dbesc($ob_hash),
|
||||||
|
dbesc($ob_hash),
|
||||||
dbesc($ob_hash)
|
dbesc($ob_hash)
|
||||||
);
|
);
|
||||||
|
|
||||||
if(! $r) {
|
if(! $r) {
|
||||||
// finger them if they can't be found.
|
// finger them if they can't be found.
|
||||||
$j = \Zotlabs\Zot\Finger::run($ob_hash, null);
|
$wf = discover_by_webbie($ob_hash);
|
||||||
if ($j['success']) {
|
if($wf) {
|
||||||
import_xchan($j);
|
|
||||||
$r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash
|
$r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash
|
||||||
where hubloc_addr = '%s' order by hubloc_id desc",
|
where hubloc_addr = '%s' or hubloc_id_url = '%s' or hubloc_hash = '%s' order by hubloc_id desc",
|
||||||
|
dbesc($ob_hash),
|
||||||
|
dbesc($ob_hash),
|
||||||
dbesc($ob_hash)
|
dbesc($ob_hash)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
14
util/fresh
14
util/fresh
|
@ -64,13 +64,13 @@ function process_command($line) {
|
||||||
fresh_help();
|
fresh_help();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'finger':
|
// case 'finger':
|
||||||
if(argv(1)) {
|
// if(argv(1)) {
|
||||||
$x = Zotlabs\Zot\Finger::run(argv(1),$channel);
|
// $x = Zotlabs\Zot\Finger::run(argv(1),$channel);
|
||||||
if($x['success'])
|
// if($x['success'])
|
||||||
echo jindent($x);
|
// echo jindent($x);
|
||||||
}
|
// }
|
||||||
break;
|
// break;
|
||||||
|
|
||||||
case 'login':
|
case 'login':
|
||||||
if(argv(1)) {
|
if(argv(1)) {
|
||||||
|
|
Loading…
Reference in a new issue