Merge remote-tracking branch 'mike/master' into dev
This commit is contained in:
commit
9be4c4d6d1
@ -67,6 +67,7 @@ require_once('include/bbcode.php');
|
|||||||
* location channel_id
|
* location channel_id
|
||||||
* request channel_id xchan_hash message_id
|
* request channel_id xchan_hash message_id
|
||||||
* rating xlink_id
|
* rating xlink_id
|
||||||
|
* keychange channel_id
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -144,6 +145,20 @@ class Notifier {
|
|||||||
$packet_type = 'request';
|
$packet_type = 'request';
|
||||||
$normal_mode = false;
|
$normal_mode = false;
|
||||||
}
|
}
|
||||||
|
elseif($cmd === 'keychange') {
|
||||||
|
$channel = channelx_by_n($item_id);
|
||||||
|
$r = q("select abook_xchan from abook where abook_channel = %d",
|
||||||
|
intval($item_id)
|
||||||
|
);
|
||||||
|
if($r) {
|
||||||
|
foreach($r as $rr) {
|
||||||
|
$recipients[] = $rr['abook_xchan'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$private = false;
|
||||||
|
$packet_type = 'keychange';
|
||||||
|
$normal_mode = false;
|
||||||
|
}
|
||||||
elseif($cmd == 'permission_update' || $cmd == 'permission_create') {
|
elseif($cmd == 'permission_update' || $cmd == 'permission_create') {
|
||||||
// Get the (single) recipient
|
// Get the (single) recipient
|
||||||
$r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0",
|
$r = q("select * from abook left join xchan on abook_xchan = xchan_hash where abook_id = %d and abook_self = 0",
|
||||||
@ -570,12 +585,17 @@ class Notifier {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$hash = random_string();
|
$hash = random_string();
|
||||||
$packet = null;
|
$packet = null;
|
||||||
|
$pmsg = '';
|
||||||
|
|
||||||
if($packet_type === 'refresh' || $packet_type === 'purge') {
|
if($packet_type === 'refresh' || $packet_type === 'purge') {
|
||||||
$packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null));
|
$packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null));
|
||||||
}
|
}
|
||||||
|
if($packet_type === 'keychange') {
|
||||||
|
$packet = zot_build_packet($channel,$packet_type,(($packet_recips) ? $packet_recips : null));
|
||||||
|
$pmsg = get_pconfig($channel['channel_id'],'system','keychange');
|
||||||
|
}
|
||||||
elseif($packet_type === 'request') {
|
elseif($packet_type === 'request') {
|
||||||
$env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : '');
|
$env = (($hub_env && $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']]) ? $hub_env[$hub['hubloc_host'] . $hub['hubloc_sitekey']] : '');
|
||||||
$packet = zot_build_packet($channel,$packet_type,$env,$hub['hubloc_sitekey'],$hub['site_crypto'],
|
$packet = zot_build_packet($channel,$packet_type,$env,$hub['hubloc_sitekey'],$hub['site_crypto'],
|
||||||
@ -589,7 +609,8 @@ class Notifier {
|
|||||||
'account_id' => $channel['channel_account_id'],
|
'account_id' => $channel['channel_account_id'],
|
||||||
'channel_id' => $channel['channel_id'],
|
'channel_id' => $channel['channel_id'],
|
||||||
'posturl' => $hub['hubloc_callback'],
|
'posturl' => $hub['hubloc_callback'],
|
||||||
'notify' => $packet
|
'notify' => $packet,
|
||||||
|
'msg' => (($pmsg) ? json_encode($pmsg) : '')
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -265,7 +265,7 @@ class File extends DAV\Node implements DAV\IFile {
|
|||||||
$f = 'store/' . $this->auth->owner_nick . '/' . (($this->os_path) ? $this->os_path . '/' : '') . $x;
|
$f = 'store/' . $this->auth->owner_nick . '/' . (($this->os_path) ? $this->os_path . '/' : '') . $x;
|
||||||
else
|
else
|
||||||
$f = $x;
|
$f = $x;
|
||||||
return fopen($f, 'rb');
|
return @fopen($f, 'rb');
|
||||||
}
|
}
|
||||||
return dbunescbin($r[0]['content']);
|
return dbunescbin($r[0]['content']);
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,8 @@ interface IHandler {
|
|||||||
|
|
||||||
function Request($data);
|
function Request($data);
|
||||||
|
|
||||||
|
function Rekey($sender,$data);
|
||||||
|
|
||||||
function AuthCheck($data,$encrypted);
|
function AuthCheck($data,$encrypted);
|
||||||
|
|
||||||
function Purge($sender,$recipients);
|
function Purge($sender,$recipients);
|
||||||
|
@ -120,6 +120,10 @@ class Receiver {
|
|||||||
$this->handler->Notify($this->data);
|
$this->handler->Notify($this->data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'rekey':
|
||||||
|
$this->handler->Rekey($this->sender, $this->data);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
$this->response['message'] = 'Not implemented';
|
$this->response['message'] = 'Not implemented';
|
||||||
json_return_and_die($this->response);
|
json_return_and_die($this->response);
|
||||||
|
@ -20,6 +20,10 @@ class ZotHandler implements IHandler {
|
|||||||
zot_reply_message_request($data);
|
zot_reply_message_request($data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Rekey($sender,$data) {
|
||||||
|
zot_rekey_request($sender,$data);
|
||||||
|
}
|
||||||
|
|
||||||
function AuthCheck($data,$encrypted) {
|
function AuthCheck($data,$encrypted) {
|
||||||
zot_reply_auth_check($data,$encrypted);
|
zot_reply_auth_check($data,$encrypted);
|
||||||
}
|
}
|
||||||
|
2
boot.php
2
boot.php
@ -50,7 +50,7 @@ require_once('include/attach.php');
|
|||||||
|
|
||||||
define ( 'PLATFORM_NAME', 'hubzilla' );
|
define ( 'PLATFORM_NAME', 'hubzilla' );
|
||||||
define ( 'STD_VERSION', '2.5.10' );
|
define ( 'STD_VERSION', '2.5.10' );
|
||||||
define ( 'ZOT_REVISION', '1.2' );
|
define ( 'ZOT_REVISION', '1.3' );
|
||||||
|
|
||||||
define ( 'DB_UPDATE_VERSION', 1192 );
|
define ( 'DB_UPDATE_VERSION', 1192 );
|
||||||
|
|
||||||
|
@ -454,6 +454,108 @@ function create_identity($arr) {
|
|||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function change_channel_keys($channel) {
|
||||||
|
|
||||||
|
$ret = array('success' => false);
|
||||||
|
|
||||||
|
$stored = [];
|
||||||
|
|
||||||
|
$key = new_keypair(4096);
|
||||||
|
|
||||||
|
$sig = base64url_encode(rsa_sign($channel['channel_guid'],$key['prvkey']));
|
||||||
|
$hash = make_xchan_hash($channel['channel_guid'],$sig);
|
||||||
|
|
||||||
|
$stored['old_guid'] = $channel['channel_guid'];
|
||||||
|
$stored['old_guid_sig'] = $channel['channel_guid_sig'];
|
||||||
|
$stored['old_key'] = $channel['channel_pubkey'];
|
||||||
|
$stored['old_hash'] = $channel['channel_hash'];
|
||||||
|
|
||||||
|
$stored['new_key'] = $key['pubkey'];
|
||||||
|
$stored['new_sig'] = base64url_encode(rsa_sign($key['pubkey'],$channel['channel_prvkey']));
|
||||||
|
|
||||||
|
// Save this info for the notifier to collect
|
||||||
|
|
||||||
|
set_pconfig($channel['channel_id'],'system','keychange',$stored);
|
||||||
|
|
||||||
|
$r = q("update channel set channel_prvkey = '%s', channel_pubkey = '%s', channel_guid_sig = '%s', channel_hash = '%s' where channel_id = %d",
|
||||||
|
dbesc($key['prvkey']),
|
||||||
|
dbesc($key['pubkey']),
|
||||||
|
dbesc($sig),
|
||||||
|
dbesc($hash),
|
||||||
|
intval($channel['channel_id'])
|
||||||
|
);
|
||||||
|
if(! $r) {
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = q("select * from channel where channel_id = %d",
|
||||||
|
intval($channel['channel_id'])
|
||||||
|
);
|
||||||
|
|
||||||
|
if(! $r) {
|
||||||
|
$ret['message'] = t('Unable to retrieve modified identity');
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
$modified = $r[0];
|
||||||
|
|
||||||
|
$h = q("select * from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' ",
|
||||||
|
dbesc($stored['old_hash']),
|
||||||
|
dbesc(z_root())
|
||||||
|
);
|
||||||
|
|
||||||
|
if($h) {
|
||||||
|
foreach($h as $hv) {
|
||||||
|
$hv['hubloc_guid_sig'] = $sig;
|
||||||
|
$hv['hubloc_hash'] = $hash;
|
||||||
|
$hv['hubloc_url_sig'] = base64url_encode(rsa_sign(z_root(),$modifed['channel_prvkey']));
|
||||||
|
hubloc_store_lowlevel($hv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$x = q("select * from xchan where xchan_hash = '%s' ",
|
||||||
|
dbesc($stored['old_hash'])
|
||||||
|
);
|
||||||
|
|
||||||
|
$check = q("select * from xchan where xchan_hash = '%s'",
|
||||||
|
dbesc($hash)
|
||||||
|
);
|
||||||
|
|
||||||
|
if(($x) && (! $check)) {
|
||||||
|
$oldxchan = $x[0];
|
||||||
|
foreach($x as $xv) {
|
||||||
|
$xv['xchan_guid_sig'] = $sig;
|
||||||
|
$xv['xchan_hash'] = $hash;
|
||||||
|
$xv['xchan_pubkey'] = $key['pubkey'];
|
||||||
|
xchan_store_lowlevel($xv);
|
||||||
|
$newxchan = $xv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
build_sync_packet($channel['channel_id'], [ 'keychange' => $stored ]);
|
||||||
|
|
||||||
|
$a = q("select * from abook where abook_xchan = '%s' and abook_self = 1",
|
||||||
|
dbesc($stored['old_hash'])
|
||||||
|
);
|
||||||
|
|
||||||
|
if($a) {
|
||||||
|
q("update abook set abook_xchan = '%s' where abook_id = %d",
|
||||||
|
dbesc($hash),
|
||||||
|
intval($a[0]['abook_id'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
xchan_change_key($oldxchan,$newxchan,$stored);
|
||||||
|
|
||||||
|
Zotlabs\Daemon\Master::Summon(array('Notifier', 'keychange', $channel['channel_id']));
|
||||||
|
|
||||||
|
$ret['success'] = true;
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Set default channel to be used on login.
|
* @brief Set default channel to be used on login.
|
||||||
*
|
*
|
||||||
|
@ -185,6 +185,16 @@ function crypto_methods() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function signing_methods() {
|
||||||
|
|
||||||
|
|
||||||
|
$r = [ 'sha256' ];
|
||||||
|
call_hooks('signing_methods',$r);
|
||||||
|
return $r;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function aes_encapsulate($data,$pubkey) {
|
function aes_encapsulate($data,$pubkey) {
|
||||||
if(! $pubkey)
|
if(! $pubkey)
|
||||||
logger('aes_encapsulate: no key. data: ' . $data);
|
logger('aes_encapsulate: no key. data: ' . $data);
|
||||||
|
@ -999,6 +999,7 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
|||||||
foreach($items as $item) {
|
foreach($items as $item) {
|
||||||
|
|
||||||
$is_reply = false;
|
$is_reply = false;
|
||||||
|
$send_downstream = false;
|
||||||
$parent_link = '';
|
$parent_link = '';
|
||||||
|
|
||||||
logger('processing ' . $item->get_id(), LOGGER_DEBUG);
|
logger('processing ' . $item->get_id(), LOGGER_DEBUG);
|
||||||
@ -1200,6 +1201,15 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
|||||||
$status = 202;
|
$status = 202;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The salmon endpoint sets this to indicate that we should send comments from
|
||||||
|
// interactive feeds (such as OStatus) downstream to our followers
|
||||||
|
// We do not want to set it for non-interactive feeds or conversations we do not own
|
||||||
|
|
||||||
|
if(array_key_exists('send_downstream',$importer) && intval($importer['send_downstream'])
|
||||||
|
&& ($parent_item['owner_xchan'] == $importer['channel_hash'])) {
|
||||||
|
$send_downstream = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if((! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'send_stream')) && (! $importer['system'])) {
|
if((! perm_is_allowed($importer['channel_id'],$contact['xchan_hash'],'send_stream')) && (! $importer['system'])) {
|
||||||
@ -1229,6 +1239,11 @@ function consume_feed($xml, $importer, &$contact, $pass = 0) {
|
|||||||
|
|
||||||
$xx = item_store($datarray);
|
$xx = item_store($datarray);
|
||||||
$r = $xx['item_id'];
|
$r = $xx['item_id'];
|
||||||
|
|
||||||
|
if($send_downstream) {
|
||||||
|
\Zotlabs\Daemon\Master::Summon(array('Notifier', 'comment', $r));
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1868,185 +1883,3 @@ function atom_entry($item, $type, $author, $owner, $comment = false, $cid = 0, $
|
|||||||
return $x['entry'];
|
return $x['entry'];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
*
|
|
||||||
* @param array $items
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function gen_asld($items) {
|
|
||||||
$ret = array();
|
|
||||||
if(! $items)
|
|
||||||
return $ret;
|
|
||||||
|
|
||||||
foreach($items as $item) {
|
|
||||||
$ret[] = i2asld($item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief
|
|
||||||
*
|
|
||||||
* @param array $i
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
function i2asld($i) {
|
|
||||||
|
|
||||||
if(! $i)
|
|
||||||
return array();
|
|
||||||
|
|
||||||
$ret = array();
|
|
||||||
|
|
||||||
$ret['@context'] = array( 'https://www.w3.org/ns/activitystreams', 'zot' => 'http://purl.org/zot/protocol');
|
|
||||||
|
|
||||||
if($i['verb']) {
|
|
||||||
if(strpos(dirname($i['verb'],'activitystrea.ms/schema/1.0'))) {
|
|
||||||
$ret['type'] = ucfirst(basename($i['verb']));
|
|
||||||
}
|
|
||||||
elseif(strpos(dirname($i['verb'],'purl.org/zot'))) {
|
|
||||||
$ret['type'] = 'zot:' . ucfirst(basename($i['verb']));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$ret['id'] = $i['plink'];
|
|
||||||
|
|
||||||
$ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME);
|
|
||||||
|
|
||||||
// we need to pass the parent into this
|
|
||||||
// if($i['id'] != $i['parent'] && $i['obj_type'] === ACTIVITY_OBJ_NOTE) {
|
|
||||||
// $ret['inReplyTo'] = asencode_note
|
|
||||||
// }
|
|
||||||
|
|
||||||
if($i['obj_type'] === ACTIVITY_OBJ_NOTE)
|
|
||||||
$ret['object'] = asencode_note($i);
|
|
||||||
|
|
||||||
$ret['actor'] = asencode_person($i['author']);
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
function asencode_note($i) {
|
|
||||||
|
|
||||||
$ret = array();
|
|
||||||
|
|
||||||
$ret['@type'] = 'Note';
|
|
||||||
$ret['id'] = $i['plink'];
|
|
||||||
if($i['title'])
|
|
||||||
$ret['title'] = bbcode($i['title']);
|
|
||||||
|
|
||||||
$ret['content'] = bbcode($i['body']);
|
|
||||||
$ret['zot:owner'] = asencode_person($i['owner']);
|
|
||||||
$ret['published'] = datetime_convert('UTC','UTC',$i['created'],ATOM_TIME);
|
|
||||||
if($i['created'] !== $i['edited'])
|
|
||||||
$ret['updated'] = datetime_convert('UTC','UTC',$i['edited'],ATOM_TIME);
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function asencode_person($p) {
|
|
||||||
$ret = [];
|
|
||||||
$ret['type'] = 'Person';
|
|
||||||
$ret['id'] = $p['xchan_url'];
|
|
||||||
$ret['name'] = $p['xchan_name'];
|
|
||||||
$ret['icon'] = [
|
|
||||||
[
|
|
||||||
'type' => 'Image',
|
|
||||||
'mediaType' => $p['xchan_photo_mimetype'],
|
|
||||||
'url' => $p['xchan_photo_l'],
|
|
||||||
'height' => 300,
|
|
||||||
'width' => 300,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'type' => 'Image',
|
|
||||||
'mediaType' => $p['xchan_photo_mimetype'],
|
|
||||||
'url' => $p['xchan_photo_m'],
|
|
||||||
'height' => 80,
|
|
||||||
'width' => 80,
|
|
||||||
],
|
|
||||||
[
|
|
||||||
'type' => 'Image',
|
|
||||||
'mediaType' => $p['xchan_photo_mimetype'],
|
|
||||||
'url' => $p['xchan_photo_l'],
|
|
||||||
'height' => 48,
|
|
||||||
'width' => 48,
|
|
||||||
]
|
|
||||||
];
|
|
||||||
$ret['url'] = [
|
|
||||||
'type' => 'Link',
|
|
||||||
'mediaType' => 'text/html',
|
|
||||||
'href' => $p['xchan_url']
|
|
||||||
];
|
|
||||||
|
|
||||||
if(array_key_exists('channel_id',$p)) {
|
|
||||||
$ret['inbox'] = z_root() . '/inbox/' . $p['channel_address'];
|
|
||||||
$ret['outbox'] = z_root() . '/outbox/' . $p['channel_address'];
|
|
||||||
$ret['me:magic_keys'] = [
|
|
||||||
[
|
|
||||||
'value' => salmon_key($p['channel_pubkey']),
|
|
||||||
'key_id' => base64url_encode(hash('sha256',salmon_key($p['channel_pubkey'])),true)
|
|
||||||
]
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$collections = get_xconfig($p['xchan_hash'],'activitystreams','collections',[]);
|
|
||||||
if($collections) {
|
|
||||||
$ret = array_merge($ret,$collections);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function activity_mapper($verb) {
|
|
||||||
|
|
||||||
$acts = [
|
|
||||||
'http://activitystrea.ms/schema/1.0/post' => 'Create',
|
|
||||||
'http://activitystrea.ms/schema/1.0/update' => 'Update',
|
|
||||||
'http://activitystrea.ms/schema/1.0/like' => 'Like',
|
|
||||||
'http://activitystrea.ms/schema/1.0/favorite' => 'Like',
|
|
||||||
'http://purl.org/zot/activity/dislike' => 'Dislike',
|
|
||||||
'http://activitystrea.ms/schema/1.0/tag' => 'Add',
|
|
||||||
'http://activitystrea.ms/schema/1.0/follow' => 'Follow',
|
|
||||||
'http://activitystrea.ms/schema/1.0/unfollow' => 'Unfollow',
|
|
||||||
];
|
|
||||||
|
|
||||||
|
|
||||||
if(array_key_exists($acts[$verb])) {
|
|
||||||
return $acts[$verb];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
function activity_obj_mapper($obj,$reverse = false) {
|
|
||||||
|
|
||||||
$objs = [
|
|
||||||
'http://activitystrea.ms/schema/1.0/note' => 'Note',
|
|
||||||
'http://activitystrea.ms/schema/1.0/comment' => 'Note',
|
|
||||||
'http://activitystrea.ms/schema/1.0/person' => 'Person',
|
|
||||||
'http://purl.org/zot/activity/profile' => 'Profile',
|
|
||||||
'http://activitystrea.ms/schema/1.0/photo' => 'Image',
|
|
||||||
'http://activitystrea.ms/schema/1.0/profile-photo' => 'Icon',
|
|
||||||
'http://activitystrea.ms/schema/1.0/event' => 'Event',
|
|
||||||
'http://activitystrea.ms/schema/1.0/wiki' => 'Document',
|
|
||||||
'http://purl.org/zot/activity/location' => 'Place',
|
|
||||||
'http://purl.org/zot/activity/chessgame' => 'Game',
|
|
||||||
'http://purl.org/zot/activity/tagterm' => 'zot:Tag',
|
|
||||||
'http://purl.org/zot/activity/thing' => 'zot:Thing',
|
|
||||||
'http://purl.org/zot/activity/file' => 'zot:File',
|
|
||||||
'http://purl.org/zot/activity/poke' => 'zot:Action',
|
|
||||||
'http://purl.org/zot/activity/react' => 'zot:Reaction',
|
|
||||||
'http://purl.org/zot/activity/mood' => 'zot:Mood',
|
|
||||||
|
|
||||||
];
|
|
||||||
|
|
||||||
if(array_key_exists($objs[$verb])) {
|
|
||||||
return $objs[$verb];
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
@ -84,6 +84,72 @@ function markdown_to_bb($s, $use_zrl = false, $options = []) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function bb_to_markdown_share($match) {
|
||||||
|
|
||||||
|
$matches = array();
|
||||||
|
$attributes = $match[1];
|
||||||
|
|
||||||
|
$author = "";
|
||||||
|
preg_match("/author='(.*?)'/ism", $attributes, $matches);
|
||||||
|
if ($matches[1] != "")
|
||||||
|
$author = urldecode($matches[1]);
|
||||||
|
|
||||||
|
$link = "";
|
||||||
|
preg_match("/link='(.*?)'/ism", $attributes, $matches);
|
||||||
|
if ($matches[1] != "")
|
||||||
|
$link = $matches[1];
|
||||||
|
|
||||||
|
$avatar = "";
|
||||||
|
preg_match("/avatar='(.*?)'/ism", $attributes, $matches);
|
||||||
|
if ($matches[1] != "")
|
||||||
|
$avatar = $matches[1];
|
||||||
|
|
||||||
|
$profile = "";
|
||||||
|
preg_match("/profile='(.*?)'/ism", $attributes, $matches);
|
||||||
|
if ($matches[1] != "")
|
||||||
|
$profile = $matches[1];
|
||||||
|
|
||||||
|
$posted = "";
|
||||||
|
preg_match("/posted='(.*?)'/ism", $attributes, $matches);
|
||||||
|
if ($matches[1] != "")
|
||||||
|
$posted = $matches[1];
|
||||||
|
|
||||||
|
// message_id is never used, do we still need it?
|
||||||
|
$message_id = "";
|
||||||
|
preg_match("/message_id='(.*?)'/ism", $attributes, $matches);
|
||||||
|
if ($matches[1] != "")
|
||||||
|
$message_id = $matches[1];
|
||||||
|
|
||||||
|
if(! $message_id) {
|
||||||
|
preg_match("/guid='(.*?)'/ism", $attributes, $matches);
|
||||||
|
if ($matches[1] != "")
|
||||||
|
$message_id = $matches[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
$reldate = datetime_convert('UTC', date_default_timezone_get(), $posted, 'r');
|
||||||
|
|
||||||
|
$headline = '';
|
||||||
|
|
||||||
|
if ($avatar != "")
|
||||||
|
$headline .= '[url=' . zid($profile) . '][img]' . $avatar . '[/img][/url]';
|
||||||
|
|
||||||
|
// Bob Smith wrote the following post 2 hours ago
|
||||||
|
|
||||||
|
$fmt = sprintf( t('%1$s wrote the following %2$s %3$s'),
|
||||||
|
'[url=' . zid($profile) . ']' . $author . '[/url]',
|
||||||
|
'[url=' . zid($link) . ']' . t('post') . '[/url]',
|
||||||
|
$reldate
|
||||||
|
);
|
||||||
|
|
||||||
|
$headline .= $fmt . "\n\n";
|
||||||
|
|
||||||
|
$text = $headline . trim($match[2]);
|
||||||
|
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function bb_to_markdown($Text) {
|
function bb_to_markdown($Text) {
|
||||||
|
|
||||||
@ -100,9 +166,12 @@ function bb_to_markdown($Text) {
|
|||||||
// Converting images with size parameters to simple images. Markdown doesn't know it.
|
// Converting images with size parameters to simple images. Markdown doesn't know it.
|
||||||
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text);
|
$Text = preg_replace("/\[img\=([0-9]*)x([0-9]*)\](.*?)\[\/img\]/ism", '[img]$3[/img]', $Text);
|
||||||
|
|
||||||
|
$Text = preg_replace_callback("/\[share(.*?)\](.*?)\[\/share\]/ism", 'bb_to_markdown_share', $Text);
|
||||||
|
|
||||||
|
|
||||||
call_hooks('bb_to_markdown_bb',$Text);
|
call_hooks('bb_to_markdown_bb',$Text);
|
||||||
|
|
||||||
|
|
||||||
// Convert it to HTML - don't try oembed
|
// Convert it to HTML - don't try oembed
|
||||||
$Text = bbcode($Text, $preserve_nl, false);
|
$Text = bbcode($Text, $preserve_nl, false);
|
||||||
|
|
||||||
|
@ -137,3 +137,83 @@ function xchan_fetch($arr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function xchan_keychange_table($table,$column,$oldxchan,$newxchan) {
|
||||||
|
$r = q("update $table set $column = '%s' where $column = '%s'",
|
||||||
|
dbesc($newxchan['xchan_hash']),
|
||||||
|
dbesc($oldxchan['xchan_hash'])
|
||||||
|
);
|
||||||
|
return $r;
|
||||||
|
}
|
||||||
|
|
||||||
|
function xchan_keychange_acl($table,$column,$oldxchan,$newxchan) {
|
||||||
|
|
||||||
|
$allow = (($table === 'channel') ? 'channel_allow_cid' : 'allow_cid');
|
||||||
|
$deny = (($table === 'channel') ? 'channel_deny_cid' : 'deny_cid');
|
||||||
|
|
||||||
|
|
||||||
|
$r = q("select $column, $allow, $deny from $table where ($allow like '%s' or $deny like '%s') ",
|
||||||
|
dbesc('<' . $oldxchan['xchan_hash'] . '>'),
|
||||||
|
dbesc('<' . $oldxchan['xchan_hash'] . '>')
|
||||||
|
);
|
||||||
|
|
||||||
|
if($r) {
|
||||||
|
foreach($r as $rv) {
|
||||||
|
$z = q("update $table set $allow = '%s', $deny = '%s' where $column = %d",
|
||||||
|
dbesc(str_replace('<' . $oldxchan['xchan_hash'] . '>', '<' . $newxchan['xchan_hash'] . '>',
|
||||||
|
$rv[$allow])),
|
||||||
|
dbesc(str_replace('<' . $oldxchan['xchan_hash'] . '>', '<' . $newxchan['xchan_hash'] . '>',
|
||||||
|
$rv[$deny])),
|
||||||
|
intval($rv[$column])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $z;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function xchan_change_key($oldx,$newx,$data) {
|
||||||
|
|
||||||
|
$tables = [
|
||||||
|
'abook' => 'abook_xchan',
|
||||||
|
'abconfig' => 'xchan',
|
||||||
|
'group_member' => 'xchan',
|
||||||
|
'chat' => 'chat_xchan',
|
||||||
|
'chatpresence' => 'cp_xchan',
|
||||||
|
'event' => 'event_xchan',
|
||||||
|
'item' => 'owner_xchan',
|
||||||
|
'item' => 'author_xchan',
|
||||||
|
'item' => 'source_xchan',
|
||||||
|
'mail' => 'from_xchan',
|
||||||
|
'mail' => 'to_xchan',
|
||||||
|
'shares' => 'share_xchan',
|
||||||
|
'source' => 'src_channel_xchan',
|
||||||
|
'source' => 'src_xchan',
|
||||||
|
'xchat' => 'xchat_xchan',
|
||||||
|
'xconfig' => 'xchan',
|
||||||
|
'xign' => 'xchan',
|
||||||
|
'xlink' => 'xlink_xchan',
|
||||||
|
'xprof' => 'xprof_hash',
|
||||||
|
'xtag' => 'xtag_hash'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
$acls = [
|
||||||
|
'channel' => 'channel_id',
|
||||||
|
'attach' => 'id',
|
||||||
|
'chatroom' => 'cr_id',
|
||||||
|
'event' => 'id',
|
||||||
|
'item' => 'id',
|
||||||
|
'menu_item' => 'mitem_id',
|
||||||
|
'obj' => 'obj_id',
|
||||||
|
'photo' => 'id'
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
foreach($tables as $k => $v) {
|
||||||
|
xchan_keychange_table($k,$v,$oldx,$newx);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($acls as $k => $v) {
|
||||||
|
xchan_keychange_acl($k,$v,$oldx,$newx);
|
||||||
|
}
|
||||||
|
}
|
235
include/zot.php
235
include/zot.php
@ -31,9 +31,9 @@ require_once('include/perm_upgrade.php');
|
|||||||
* @param string $channel_nick a unique nickname of controlling entity
|
* @param string $channel_nick a unique nickname of controlling entity
|
||||||
* @returns string
|
* @returns string
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function zot_new_uid($channel_nick) {
|
function zot_new_uid($channel_nick) {
|
||||||
$rawstr = z_root() . '/' . $channel_nick . '.' . mt_rand();
|
$rawstr = z_root() . '/' . $channel_nick . '.' . mt_rand();
|
||||||
|
|
||||||
return(base64url_encode(hash('whirlpool', $rawstr, true), true));
|
return(base64url_encode(hash('whirlpool', $rawstr, true), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,6 +49,7 @@ function zot_new_uid($channel_nick) {
|
|||||||
* @param string $guid
|
* @param string $guid
|
||||||
* @param string $guid_sig
|
* @param string $guid_sig
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function make_xchan_hash($guid, $guid_sig) {
|
function make_xchan_hash($guid, $guid_sig) {
|
||||||
return base64url_encode(hash('whirlpool', $guid . $guid_sig, true));
|
return base64url_encode(hash('whirlpool', $guid . $guid_sig, true));
|
||||||
}
|
}
|
||||||
@ -62,17 +63,17 @@ function make_xchan_hash($guid, $guid_sig) {
|
|||||||
* @param string $hash - xchan_hash
|
* @param string $hash - xchan_hash
|
||||||
* @returns array of hubloc (hub location structures)
|
* @returns array of hubloc (hub location structures)
|
||||||
* * \b hubloc_id int
|
* * \b hubloc_id int
|
||||||
* * \b hubloc_guid char(255)
|
* * \b hubloc_guid char(191)
|
||||||
* * \b hubloc_guid_sig text
|
* * \b hubloc_guid_sig text
|
||||||
* * \b hubloc_hash char(255)
|
* * \b hubloc_hash char(191)
|
||||||
* * \b hubloc_addr char(255)
|
* * \b hubloc_addr char(191)
|
||||||
* * \b hubloc_flags int
|
* * \b hubloc_flags int
|
||||||
* * \b hubloc_status int
|
* * \b hubloc_status int
|
||||||
* * \b hubloc_url char(255)
|
* * \b hubloc_url char(191)
|
||||||
* * \b hubloc_url_sig text
|
* * \b hubloc_url_sig text
|
||||||
* * \b hubloc_host char(255)
|
* * \b hubloc_host char(191)
|
||||||
* * \b hubloc_callback char(255)
|
* * \b hubloc_callback char(191)
|
||||||
* * \b hubloc_connect char(255)
|
* * \b hubloc_connect char(191)
|
||||||
* * \b hubloc_sitekey text
|
* * \b hubloc_sitekey text
|
||||||
* * \b hubloc_updated datetime
|
* * \b hubloc_updated datetime
|
||||||
* * \b hubloc_connected datetime
|
* * \b hubloc_connected datetime
|
||||||
@ -97,7 +98,7 @@ function zot_get_hublocs($hash) {
|
|||||||
* @param array $channel
|
* @param array $channel
|
||||||
* sender channel structure
|
* sender channel structure
|
||||||
* @param string $type
|
* @param string $type
|
||||||
* packet type: one of 'ping', 'pickup', 'purge', 'refresh', 'force_refresh', 'notify', 'auth_check'
|
* packet type: one of 'ping', 'pickup', 'purge', 'refresh', 'keychange', 'force_refresh', 'notify', 'auth_check'
|
||||||
* @param array $recipients
|
* @param array $recipients
|
||||||
* envelope information, array ( 'guid' => string, 'guid_sig' => string ); empty for public posts
|
* envelope information, array ( 'guid' => string, 'guid_sig' => string ); empty for public posts
|
||||||
* @param string $remote_key
|
* @param string $remote_key
|
||||||
@ -111,18 +112,21 @@ function zot_get_hublocs($hash) {
|
|||||||
*/
|
*/
|
||||||
function zot_build_packet($channel, $type = 'notify', $recipients = null, $remote_key = null, $methods = '', $secret = null, $extra = null) {
|
function zot_build_packet($channel, $type = 'notify', $recipients = null, $remote_key = null, $methods = '', $secret = null, $extra = null) {
|
||||||
|
|
||||||
|
$sig_method = get_config('system','signature_algorithm','sha256');
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
'type' => $type,
|
'type' => $type,
|
||||||
'sender' => [
|
'sender' => [
|
||||||
'guid' => $channel['channel_guid'],
|
'guid' => $channel['channel_guid'],
|
||||||
'guid_sig' => base64url_encode(rsa_sign($channel['channel_guid'],$channel['channel_prvkey'])),
|
'guid_sig' => base64url_encode(rsa_sign($channel['channel_guid'],$channel['channel_prvkey'],$sig_method)),
|
||||||
'url' => z_root(),
|
'url' => z_root(),
|
||||||
'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'])),
|
'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'],$sig_method)),
|
||||||
'sitekey' => get_config('system','pubkey')
|
'sitekey' => get_config('system','pubkey')
|
||||||
],
|
],
|
||||||
'callback' => '/post',
|
'callback' => '/post',
|
||||||
'version' => ZOT_REVISION,
|
'version' => ZOT_REVISION,
|
||||||
'encryption' => crypto_methods()
|
'encryption' => crypto_methods(),
|
||||||
|
'signing' => signing_methods()
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($recipients) {
|
if ($recipients) {
|
||||||
@ -134,7 +138,7 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot
|
|||||||
|
|
||||||
if ($secret) {
|
if ($secret) {
|
||||||
$data['secret'] = $secret;
|
$data['secret'] = $secret;
|
||||||
$data['secret_sig'] = base64url_encode(rsa_sign($secret,$channel['channel_prvkey']));
|
$data['secret_sig'] = base64url_encode(rsa_sign($secret,$channel['channel_prvkey'],$sig_method));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($extra) {
|
if ($extra) {
|
||||||
@ -529,7 +533,7 @@ function zot_gethub($arr, $multiple = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$limit = (($multiple) ? '' : ' limit 1 ');
|
$limit = (($multiple) ? '' : ' limit 1 ');
|
||||||
$sitekey = ((array_key_exists('sitekey',$arr) && $arr['sitekey']) ? " and hubloc_sitekey = '" . protect_sprintf($arr['sitekey']) . "' " : '');
|
$sitekey = ((array_key_exists('sitekey',$arr) && $arr['sitekey']) ? " and hubloc_sitekey = '" . dbesc(protect_sprintf($arr['sitekey'])) . "' " : '');
|
||||||
|
|
||||||
$r = q("select hubloc.*, site.site_crypto from hubloc left join site on hubloc_url = site_url
|
$r = q("select hubloc.*, site.site_crypto from hubloc left join site on hubloc_url = site_url
|
||||||
where hubloc_guid = '%s' and hubloc_guid_sig = '%s'
|
where hubloc_guid = '%s' and hubloc_guid_sig = '%s'
|
||||||
@ -575,6 +579,8 @@ function zot_register_hub($arr) {
|
|||||||
|
|
||||||
if($arr['url'] && $arr['url_sig'] && $arr['guid'] && $arr['guid_sig']) {
|
if($arr['url'] && $arr['url_sig'] && $arr['guid'] && $arr['guid_sig']) {
|
||||||
|
|
||||||
|
$sig_methods = ((array_key_exists('signing',$arr) && is_array($arr['signing'])) ? $arr['signing'] : [ 'sha256' ]);
|
||||||
|
|
||||||
$guid_hash = make_xchan_hash($arr['guid'],$arr['guid_sig']);
|
$guid_hash = make_xchan_hash($arr['guid'],$arr['guid_sig']);
|
||||||
|
|
||||||
$url = $arr['url'] . '/.well-known/zot-info/?f=&guid_hash=' . $guid_hash;
|
$url = $arr['url'] . '/.well-known/zot-info/?f=&guid_hash=' . $guid_hash;
|
||||||
@ -594,17 +600,18 @@ function zot_register_hub($arr) {
|
|||||||
* our current communication.
|
* our current communication.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if((rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$record['key']))
|
foreach($sig_methods as $method) {
|
||||||
&& (rsa_verify($arr['url'],base64url_decode($arr['url_sig']),$record['key']))
|
if((rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$record['key'],$method))
|
||||||
|
&& (rsa_verify($arr['url'],base64url_decode($arr['url_sig']),$record['key'],$method))
|
||||||
&& ($arr['guid'] === $record['guid'])
|
&& ($arr['guid'] === $record['guid'])
|
||||||
&& ($arr['guid_sig'] === $record['guid_sig'])) {
|
&& ($arr['guid_sig'] === $record['guid_sig'])) {
|
||||||
|
$c = import_xchan($record);
|
||||||
$c = import_xchan($record);
|
if($c['success'])
|
||||||
if($c['success'])
|
$result['success'] = true;
|
||||||
$result['success'] = true;
|
}
|
||||||
}
|
else {
|
||||||
else {
|
logger('zot_register_hub: failure to verify returned packet using ' . $method);
|
||||||
logger('zot_register_hub: failure to verify returned packet.');
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -657,8 +664,19 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
|
|||||||
|
|
||||||
$import_photos = false;
|
$import_photos = false;
|
||||||
|
|
||||||
if(! rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$arr['key'])) {
|
$sig_methods = ((array_key_exists('signing',$arr) && is_array($arr['signing'])) ? $arr['signing'] : [ 'sha256' ]);
|
||||||
logger('import_xchan: Unable to verify channel signature for ' . $arr['address']);
|
$verified = false;
|
||||||
|
|
||||||
|
foreach($sig_methods as $method) {
|
||||||
|
if(! rsa_verify($arr['guid'],base64url_decode($arr['guid_sig']),$arr['key'],$method)) {
|
||||||
|
logger('import_xchan: Unable to verify channel signature for ' . $arr['address'] . ' using ' . $method);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$verified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(! $verified) {
|
||||||
$ret['message'] = t('Unable to verify channel signature');
|
$ret['message'] = t('Unable to verify channel signature');
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
@ -917,7 +935,7 @@ function import_xchan($arr,$ud_flags = UPDATE_FLAGS_UPDATED, $ud_arr = null) {
|
|||||||
}
|
}
|
||||||
elseif(! $ud_flags) {
|
elseif(! $ud_flags) {
|
||||||
// nothing changed but we still need to update the updates record
|
// nothing changed but we still need to update the updates record
|
||||||
q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and not (ud_flags & %d)>0 ",
|
q("update updates set ud_flags = ( ud_flags | %d ) where ud_addr = '%s' and not (ud_flags & %d) > 0 ",
|
||||||
intval(UPDATE_FLAGS_UPDATED),
|
intval(UPDATE_FLAGS_UPDATED),
|
||||||
dbesc($address),
|
dbesc($address),
|
||||||
intval(UPDATE_FLAGS_UPDATED)
|
intval(UPDATE_FLAGS_UPDATED)
|
||||||
@ -2948,6 +2966,11 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
|
|||||||
if($packet)
|
if($packet)
|
||||||
logger('packet: ' . print_r($packet, true),LOGGER_DATA, LOG_DEBUG);
|
logger('packet: ' . print_r($packet, true),LOGGER_DATA, LOG_DEBUG);
|
||||||
|
|
||||||
|
$keychange = (($packet && array_key_exists('keychange',$packet)) ? true : false);
|
||||||
|
if($keychange) {
|
||||||
|
logger('keychange sync');
|
||||||
|
}
|
||||||
|
|
||||||
if(! $uid)
|
if(! $uid)
|
||||||
$uid = local_channel();
|
$uid = local_channel();
|
||||||
|
|
||||||
@ -2961,6 +2984,7 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
$channel = $r[0];
|
$channel = $r[0];
|
||||||
|
|
||||||
unset($channel['channel_password']);
|
unset($channel['channel_password']);
|
||||||
unset($channel['channel_salt']);
|
unset($channel['channel_salt']);
|
||||||
|
|
||||||
@ -2971,12 +2995,11 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(intval($channel['channel_removed']))
|
if(intval($channel['channel_removed']))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
$h = q("select hubloc.*, site.site_crypto from hubloc left join site on site_url = hubloc_url where hubloc_hash = '%s' and hubloc_deleted = 0",
|
$h = q("select hubloc.*, site.site_crypto from hubloc left join site on site_url = hubloc_url where hubloc_hash = '%s' and hubloc_deleted = 0",
|
||||||
dbesc($channel['channel_hash'])
|
dbesc(($keychange) ? $packet['keychange']['old_hash'] : $channel['channel_hash'])
|
||||||
);
|
);
|
||||||
|
|
||||||
if(! $h)
|
if(! $h)
|
||||||
@ -3031,7 +3054,15 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
|
|||||||
|
|
||||||
// don't pass these elements, they should not be synchronised
|
// don't pass these elements, they should not be synchronised
|
||||||
|
|
||||||
$disallowed = array('channel_id','channel_account_id','channel_primary','channel_prvkey','channel_address','channel_deleted','channel_removed','channel_system');
|
|
||||||
|
$disallowed = [
|
||||||
|
'channel_id','channel_account_id','channel_primary','channel_address',
|
||||||
|
'channel_deleted','channel_removed','channel_system'
|
||||||
|
];
|
||||||
|
|
||||||
|
if(! $keychange) {
|
||||||
|
$disallowed[] = 'channel_prvkey';
|
||||||
|
}
|
||||||
|
|
||||||
if(in_array($k,$disallowed))
|
if(in_array($k,$disallowed))
|
||||||
continue;
|
continue;
|
||||||
@ -3091,17 +3122,18 @@ function build_sync_packet($uid = 0, $packet = null, $groups_changed = false) {
|
|||||||
|
|
||||||
function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
||||||
|
|
||||||
|
|
||||||
require_once('include/import.php');
|
require_once('include/import.php');
|
||||||
|
|
||||||
/** @FIXME this will sync red structures (channel, pconfig and abook).
|
/** @FIXME this will sync red structures (channel, pconfig and abook).
|
||||||
Eventually we need to make this application agnostic. */
|
Eventually we need to make this application agnostic. */
|
||||||
|
|
||||||
$result = array();
|
$result = [];
|
||||||
|
|
||||||
|
$keychange = ((array_key_exists('keychange',$arr)) ? true : false);
|
||||||
|
|
||||||
foreach ($deliveries as $d) {
|
foreach ($deliveries as $d) {
|
||||||
$r = q("select * from channel where channel_hash = '%s' limit 1",
|
$r = q("select * from channel where channel_hash = '%s' limit 1",
|
||||||
dbesc($d['hash'])
|
dbesc(($keychange) ? $arr['keychange']['old_hash'] : $d['hash'])
|
||||||
);
|
);
|
||||||
|
|
||||||
if (! $r) {
|
if (! $r) {
|
||||||
@ -3120,6 +3152,94 @@ function process_channel_sync_delivery($sender, $arr, $deliveries) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($keychange) {
|
||||||
|
// verify the keychange operation
|
||||||
|
if(! rsa_verify($arr['channel']['channel_pubkey'],base64url_decode($arr['keychange']['new_sig']),$channel['channel_prvkey'])) {
|
||||||
|
logger('sync keychange: verification failed');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sig = base64url_encode(rsa_sign($channel['channel_guid'],$arr['channel']['channel_prvkey']));
|
||||||
|
$hash = make_xchan_hash($channel['channel_guid'],$sig);
|
||||||
|
|
||||||
|
|
||||||
|
$r = q("update channel set channel_prvkey = '%s', channel_pubkey = '%s', channel_guid_sig = '%s',
|
||||||
|
channel_hash = '%s' where channel_id = %d",
|
||||||
|
dbesc($arr['channel']['channel_prvkey']),
|
||||||
|
dbesc($arr['channel']['channel_pubkey']),
|
||||||
|
dbesc($sig),
|
||||||
|
dbesc($hash),
|
||||||
|
intval($channel['channel_id'])
|
||||||
|
);
|
||||||
|
if(! $r) {
|
||||||
|
logger('keychange sync: channel update failed');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = q("select * from channel where channel_id = %d",
|
||||||
|
intval($channel['channel_id'])
|
||||||
|
);
|
||||||
|
|
||||||
|
if(! $r) {
|
||||||
|
logger('keychange sync: channel retrieve failed');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$channel = $r[0];
|
||||||
|
|
||||||
|
$h = q("select * from hubloc where hubloc_hash = '%s' and hubloc_url = '%s' ",
|
||||||
|
dbesc($arr['keychange']['old_hash']),
|
||||||
|
dbesc(z_root())
|
||||||
|
);
|
||||||
|
|
||||||
|
if($h) {
|
||||||
|
foreach($h as $hv) {
|
||||||
|
$hv['hubloc_guid_sig'] = $sig;
|
||||||
|
$hv['hubloc_hash'] = $hash;
|
||||||
|
$hv['hubloc_url_sig'] = base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey']));
|
||||||
|
hubloc_store_lowlevel($hv);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$x = q("select * from xchan where xchan_hash = '%s' ",
|
||||||
|
dbesc($arr['keychange']['old_hash'])
|
||||||
|
);
|
||||||
|
|
||||||
|
$check = q("select * from xchan where xchan_hash = '%s'",
|
||||||
|
dbesc($hash)
|
||||||
|
);
|
||||||
|
|
||||||
|
if(($x) && (! $check)) {
|
||||||
|
$oldxchan = $x[0];
|
||||||
|
foreach($x as $xv) {
|
||||||
|
$xv['xchan_guid_sig'] = $sig;
|
||||||
|
$xv['xchan_hash'] = $hash;
|
||||||
|
$xv['xchan_pubkey'] = $channel['channel_pubkey'];
|
||||||
|
xchan_store_lowlevel($xv);
|
||||||
|
$newxchan = $xv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$a = q("select * from abook where abook_xchan = '%s' and abook_self = 1",
|
||||||
|
dbesc($arr['keychange']['old_hash'])
|
||||||
|
);
|
||||||
|
|
||||||
|
if($a) {
|
||||||
|
q("update abook set abook_xchan = '%s' where abook_id = %d",
|
||||||
|
dbesc($hash),
|
||||||
|
intval($a[0]['abook_id'])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
xchan_change_key($oldxchan,$newxchan,$arr['keychange']);
|
||||||
|
|
||||||
|
// keychange operations can end up in a confused state if you try and sync anything else
|
||||||
|
// besides the channel keys, so ignore any other packets.
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if(array_key_exists('config',$arr) && is_array($arr['config']) && count($arr['config'])) {
|
if(array_key_exists('config',$arr) && is_array($arr['config']) && count($arr['config'])) {
|
||||||
foreach($arr['config'] as $cat => $k) {
|
foreach($arr['config'] as $cat => $k) {
|
||||||
foreach($arr['config'][$cat] as $k => $v)
|
foreach($arr['config'][$cat] as $k => $v)
|
||||||
@ -3757,11 +3877,57 @@ function zot_reply_message_request($data) {
|
|||||||
json_return_and_die($ret);
|
json_return_and_die($ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function zot_rekey_request($sender,$data) {
|
||||||
|
|
||||||
|
$ret = array('success' => false);
|
||||||
|
|
||||||
|
// newsig is newkey signed with oldkey
|
||||||
|
|
||||||
|
// The original xchan will remain. In Zot/Receiver we will have imported the new xchan and hubloc to verify
|
||||||
|
// the packet authenticity. What we will do now is verify that the keychange operation was signed by the
|
||||||
|
// oldkey, and if so change all the abook, abconfig, group, and permission elements which reference the
|
||||||
|
// old xchan_hash.
|
||||||
|
|
||||||
|
if((! $data['old_key']) && (! $data['new_key']) && (! $data['new_sig']))
|
||||||
|
json_return_and_die($ret);
|
||||||
|
|
||||||
|
$oldhash = make_xchan_hash($data['old_guid'],$data['old_guid_sig']);
|
||||||
|
|
||||||
|
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||||
|
dbesc($oldhash)
|
||||||
|
);
|
||||||
|
|
||||||
|
if(! $r) {
|
||||||
|
json_return_and_die($ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
$xchan = $r[0];
|
||||||
|
|
||||||
|
if(! rsa_verify($data['new_key'],base64url_decode($data['new_sig']),$xchan['xchan_pubkey'])) {
|
||||||
|
json_return_and_die($ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
$newhash = make_xchan_hash($sender['guid'],$sender['guid_sig']);
|
||||||
|
|
||||||
|
$r = q("select * from xchan where xchan_hash = '%s' limit 1",
|
||||||
|
dbesc($newhash)
|
||||||
|
);
|
||||||
|
|
||||||
|
$newxchan = $r[0];
|
||||||
|
|
||||||
|
xchan_change_key($xchan,$newxchan,$data);
|
||||||
|
|
||||||
|
$ret['success'] = true;
|
||||||
|
json_return_and_die($ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function zotinfo($arr) {
|
function zotinfo($arr) {
|
||||||
|
|
||||||
$ret = array('success' => false);
|
$ret = array('success' => false);
|
||||||
|
|
||||||
|
$sig_method = get_config('system','signature_algorithm','sha256');
|
||||||
|
|
||||||
$zhash = ((x($arr,'guid_hash')) ? $arr['guid_hash'] : '');
|
$zhash = ((x($arr,'guid_hash')) ? $arr['guid_hash'] : '');
|
||||||
$zguid = ((x($arr,'guid')) ? $arr['guid'] : '');
|
$zguid = ((x($arr,'guid')) ? $arr['guid'] : '');
|
||||||
$zguid_sig = ((x($arr,'guid_sig')) ? $arr['guid_sig'] : '');
|
$zguid_sig = ((x($arr,'guid_sig')) ? $arr['guid_sig'] : '');
|
||||||
@ -3925,7 +4091,7 @@ function zotinfo($arr) {
|
|||||||
// Communication details
|
// Communication details
|
||||||
|
|
||||||
if($token)
|
if($token)
|
||||||
$ret['signed_token'] = base64url_encode(rsa_sign('token.' . $token,$e['channel_prvkey']));
|
$ret['signed_token'] = base64url_encode(rsa_sign('token.' . $token,$e['channel_prvkey'],$sig_method));
|
||||||
|
|
||||||
|
|
||||||
$ret['guid'] = $e['xchan_guid'];
|
$ret['guid'] = $e['xchan_guid'];
|
||||||
@ -3994,7 +4160,7 @@ function zotinfo($arr) {
|
|||||||
|
|
||||||
$ret['site'] = array();
|
$ret['site'] = array();
|
||||||
$ret['site']['url'] = z_root();
|
$ret['site']['url'] = z_root();
|
||||||
$ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),$e['channel_prvkey']));
|
$ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(),$e['channel_prvkey'],$sig_method));
|
||||||
$ret['site']['zot_auth'] = z_root() . '/magic';
|
$ret['site']['zot_auth'] = z_root() . '/magic';
|
||||||
|
|
||||||
$dirmode = get_config('system','directory_mode');
|
$dirmode = get_config('system','directory_mode');
|
||||||
@ -4012,6 +4178,7 @@ function zotinfo($arr) {
|
|||||||
|
|
||||||
|
|
||||||
$ret['site']['encryption'] = crypto_methods();
|
$ret['site']['encryption'] = crypto_methods();
|
||||||
|
$ret['site']['signing'] = signing_methods();
|
||||||
|
|
||||||
// hide detailed site information if you're off the grid
|
// hide detailed site information if you're off the grid
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user