Merge branch 'origin' into 'japanese'

Update 4.0.3

See merge request harukin/core!54
This commit is contained in:
harukin 2019-04-28 18:00:17 +09:00
commit b9f1cb2021
14 changed files with 179 additions and 57 deletions

View File

@ -1,3 +1,14 @@
Hubzilla 4.0.3 (2019-04-26)
- Add attachments to zot6 event objects
- Add zot6 to federated transports
- Update import/export to handle zot6 hublocs and xchans
- Update fix_system_urls() to handle zot6 hublocs
- Fix infinite loop using postgres as backend
- Fix magic auth in combination with zot6
- Fix check for required PHP version
- Diaspora: favour diaspora protocol identities over others with same hubloc or xchan address
Hubzilla 4.0.2 (2019-04-08) Hubzilla 4.0.2 (2019-04-08)
- Port cdav calendar to fullcalendar version 4 - Port cdav calendar to fullcalendar version 4
- Fix perms_pending not evaluated correctly - Fix perms_pending not evaluated correctly

View File

@ -3107,7 +3107,11 @@ class Libzot {
foreach($arr as $v) { foreach($arr as $v) {
if($v[$check] === 'zot6') { if($v[$check] === 'zot6') {
return $v;
}
}
foreach($arr as $v) {
if($v[$check] === 'zot') {
return $v; return $v;
} }
} }

View File

@ -280,8 +280,9 @@ class Import extends \Zotlabs\Web\Controller {
// replace any existing xchan we may have on this site if we're seizing control // replace any existing xchan we may have on this site if we're seizing control
$r = q("delete from xchan where xchan_hash = '%s'", $r = q("delete from xchan where ( xchan_hash = '%s' or xchan_hash = '%s' ) ",
dbesc($channel['channel_hash']) dbesc($channel['channel_hash']),
dbesc($channel['channel_portable_id'])
); );
$r = xchan_store_lowlevel( $r = xchan_store_lowlevel(
@ -303,6 +304,30 @@ class Import extends \Zotlabs\Web\Controller {
'xchan_name_date' => datetime_convert() 'xchan_name_date' => datetime_convert()
] ]
); );
if($channel['channel_portable_id']) {
$r = xchan_store_lowlevel(
[
'xchan_hash' => \Zotlabs\Lib\Libzot::make_xchan_hash($channel['channel_guid'],$channel['channel_pubkey']),
'xchan_guid' => $channel['channel_guid'],
'xchan_guid_sig' => 'sha256.' . $channel['channel_guid_sig'],
'xchan_pubkey' => $channel['channel_pubkey'],
'xchan_photo_l' => z_root() . "/photo/profile/l/" . $channel['channel_id'],
'xchan_photo_m' => z_root() . "/photo/profile/m/" . $channel['channel_id'],
'xchan_photo_s' => z_root() . "/photo/profile/s/" . $channel['channel_id'],
'xchan_addr' => channel_reddress($channel),
'xchan_url' => z_root() . '/channel/' . $channel['channel_address'],
'xchan_connurl' => z_root() . '/poco/' . $channel['channel_address'],
'xchan_follow' => z_root() . '/follow?f=&url=%s',
'xchan_name' => $channel['channel_name'],
'xchan_network' => 'zot6',
'xchan_photo_date' => datetime_convert(),
'xchan_name_date' => datetime_convert()
]
);
}
} }
logger('import step 6'); logger('import step 6');
@ -312,11 +337,21 @@ class Import extends \Zotlabs\Web\Controller {
if($xchans) { if($xchans) {
foreach($xchans as $xchan) { foreach($xchans as $xchan) {
if($xchan['xchan_network'] === 'zot') {
$hash = make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_guid_sig']); $hash = make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_guid_sig']);
if($xchan['xchan_network'] === 'zot' && $hash !== $xchan['xchan_hash']) { if($hash !== $xchan['xchan_hash']) {
logger('forged xchan: ' . print_r($xchan,true)); logger('forged xchan: ' . print_r($xchan,true));
continue; continue;
} }
}
if($xchan['xchan_network'] === 'zot6') {
$zhash = \Zotlabs\Lib\Libzot::make_xchan_hash($xchan['xchan_guid'],$xchan['xchan_pubkey']);
if($zhash !== $xchan['xchan_hash']) {
logger('forged xchan: ' . print_r($xchan,true));
continue;
}
}
if(! array_key_exists('xchan_hidden',$xchan)) { if(! array_key_exists('xchan_hidden',$xchan)) {
$xchan['xchan_hidden'] = (($xchan['xchan_flags'] & 0x0001) ? 1 : 0); $xchan['xchan_hidden'] = (($xchan['xchan_flags'] & 0x0001) ? 1 : 0);

View File

@ -169,8 +169,8 @@ class Magic extends \Zotlabs\Web\Controller {
$token = $j['token']; $token = $j['token'];
} }
$x = strpbrk($dest,'?&'); $strp = strpbrk($dest,'?&');
$args = (($x) ? '&owt=' . $token : '?f=&owt=' . $token) . (($delegate) ? '&delegate=1' : ''); $args = (($strp) ? '&owt=' . $token : '?f=&owt=' . $token) . (($delegate) ? '&delegate=1' : '');
goaway($dest . $args); goaway($dest . $args);
} }
} }

View File

@ -30,12 +30,29 @@ class Owa extends \Zotlabs\Web\Controller {
$keyId = $sigblock['keyId']; $keyId = $sigblock['keyId'];
if($keyId) { if($keyId) {
// Hubzilla connections can have both zot and zot6 hublocs
// The connections will usually be zot so match those first
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash $r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) ", where ( hubloc_addr = '%s' or hubloc_id_url = '%s' ) and hubloc_network = 'zot' ",
dbesc(str_replace('acct:','',$keyId)), dbesc(str_replace('acct:','',$keyId)),
dbesc($keyId) dbesc($keyId)
); );
if(! $r) {
// If nothing was found, try searching on any network
if (! $r) {
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
where ( hubloc_addr = '%s' or hubloc_id_url = '%s' )",
dbesc(str_replace('acct:','',$keyId)),
dbesc($keyId)
);
}
// If nothing was found on any network, use network discovery and create a new record
if (! $r) {
$found = discover_by_webbie(str_replace('acct:','',$keyId)); $found = discover_by_webbie(str_replace('acct:','',$keyId));
if($found) { if($found) {
$r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash $r = q("select * from hubloc left join xchan on hubloc_hash = xchan_hash
@ -45,7 +62,8 @@ class Owa extends \Zotlabs\Web\Controller {
); );
} }
} }
if($r) {
if ($r) {
foreach($r as $hubloc) { foreach($r as $hubloc) {
$verified = \Zotlabs\Web\HTTPSig::verify(file_get_contents('php://input'),$hubloc['xchan_pubkey']); $verified = \Zotlabs\Web\HTTPSig::verify(file_get_contents('php://input'),$hubloc['xchan_pubkey']);
if($verified && $verified['header_signed'] && $verified['header_valid']) { if($verified && $verified['header_signed'] && $verified['header_valid']) {
@ -53,7 +71,7 @@ class Owa extends \Zotlabs\Web\Controller {
logger('OWA success: ' . $hubloc['hubloc_addr'],LOGGER_DATA); logger('OWA success: ' . $hubloc['hubloc_addr'],LOGGER_DATA);
$ret['success'] = true; $ret['success'] = true;
$token = random_string(32); $token = random_string(32);
\Zotlabs\Lib\Verify::create('owt',0,$token,$hubloc['hubloc_addr']); \Zotlabs\Lib\Verify::create('owt',0,$token,$hubloc['hubloc_network'] . ',' . $hubloc['hubloc_addr']);
$result = ''; $result = '';
openssl_public_encrypt($token,$result,$hubloc['xchan_pubkey']); openssl_public_encrypt($token,$result,$hubloc['xchan_pubkey']);
$ret['encrypted_token'] = base64url_encode($result); $ret['encrypted_token'] = base64url_encode($result);

View File

@ -377,7 +377,7 @@ class Setup extends \Zotlabs\Web\Controller {
if(version_compare(PHP_VERSION, '7.1') < 0) { if(version_compare(PHP_VERSION, '7.1') < 0) {
$help .= t('PHP version 7.1 or greater is required.'); $help .= t('PHP version 7.1 or greater is required.');
$this->check_add($checks, t('PHP version'), false, false, $help); $this->check_add($checks, t('PHP version'), false, true, $help);
} }
if(strlen($phpath)) { if(strlen($phpath)) {

View File

@ -128,7 +128,7 @@ class Wfinger extends \Zotlabs\Web\Controller {
'http://webfinger.net/ns/name' => $r[0]['channel_name'], 'http://webfinger.net/ns/name' => $r[0]['channel_name'],
'http://xmlns.com/foaf/0.1/name' => $r[0]['channel_name'], 'http://xmlns.com/foaf/0.1/name' => $r[0]['channel_name'],
'https://w3id.org/security/v1#publicKeyPem' => $r[0]['xchan_pubkey'], 'https://w3id.org/security/v1#publicKeyPem' => $r[0]['xchan_pubkey'],
'http://purl.org/zot/federation' => 'zot' 'http://purl.org/zot/federation' => 'zot,zot6'
]; ];
foreach($aliases as $alias) foreach($aliases as $alias)

View File

@ -50,7 +50,7 @@ require_once('include/attach.php');
require_once('include/bbcode.php'); require_once('include/bbcode.php');
define ( 'PLATFORM_NAME', 'hubzilla' ); define ( 'PLATFORM_NAME', 'hubzilla' );
define ( 'STD_VERSION', '4.0.2' ); define ( 'STD_VERSION', '4.0.3' );
define ( 'ZOT_REVISION', '6.0a' ); define ( 'ZOT_REVISION', '6.0a' );
define ( 'DB_UPDATE_VERSION', 1231 ); define ( 'DB_UPDATE_VERSION', 1231 );
@ -1507,12 +1507,13 @@ function fix_system_urls($oldurl, $newurl) {
dbesc($rv['xchan_hash']) dbesc($rv['xchan_hash'])
); );
$y = q("update hubloc set hubloc_addr = '%s', hubloc_url = '%s', hubloc_url_sig = '%s', hubloc_host = '%s', hubloc_callback = '%s' where hubloc_hash = '%s' and hubloc_url = '%s'", $y = q("update hubloc set hubloc_addr = '%s', hubloc_url = '%s', hubloc_id_url = '%s', hubloc_url_sig = '%s', hubloc_host = '%s', hubloc_callback = '%s' where hubloc_hash = '%s' and hubloc_url = '%s'",
dbesc($channel_address . '@' . $rhs), dbesc($channel_address . '@' . $rhs),
dbesc($newurl), dbesc($newurl),
dbesc(base64url_encode(rsa_sign($newurl,$c[0]['channel_prvkey']))), dbesc(str_replace($oldurl,$newurl,$rv['hubloc_id_url'])),
dbesc(($rv['hubloc_network'] === 'zot6') ? \Zotlabs\Lib\Libzot::sign($newurl,$c[0]['channel_prvkey']) : base64url_encode(rsa_sign($newurl,$c[0]['channel_prvkey']))),
dbesc($newhost), dbesc($newhost),
dbesc($newurl . '/post'), dbesc(($rv['hubloc_network'] === 'zot6') ? $newurl . '/zot' : $newurl . '/post'),
dbesc($rv['xchan_hash']), dbesc($rv['xchan_hash']),
dbesc($oldurl) dbesc($oldurl)
); );

View File

@ -873,6 +873,13 @@ function identity_basic_export($channel_id, $sections = null) {
$ret['abook'][$x]['abconfig'] = $abconfig; $ret['abook'][$x]['abconfig'] = $abconfig;
translate_abook_perms_outbound($ret['abook'][$x]); translate_abook_perms_outbound($ret['abook'][$x]);
} }
// pick up the zot6 xchan and hublocs also
if($ret['channel']['channel_portable_id']) {
$xchans[] = $ret['channel']['channel_portable_id'];
}
stringify_array_elms($xchans); stringify_array_elms($xchans);
} }
@ -1812,13 +1819,16 @@ function zid_init() {
call_hooks('zid_init', $arr); call_hooks('zid_init', $arr);
if(! local_channel()) { if(! local_channel()) {
$r = q("select * from hubloc where hubloc_addr = '%s' order by hubloc_connected desc limit 1", $r = q("select * from hubloc where hubloc_addr = '%s' order by hubloc_connected desc",
dbesc($tmp_str) dbesc($tmp_str)
); );
if(! $r) { if(! $r) {
Master::Summon(array('Gprobe',bin2hex($tmp_str))); Master::Summon(array('Gprobe',bin2hex($tmp_str)));
} }
if($r && remote_channel() && remote_channel() === $r[0]['hubloc_hash']) if($r) {
$r = zot_record_preferred($r);
}
if($r && remote_channel() && remote_channel() === $r['hubloc_hash'])
return; return;
logger('Not authenticated. Invoking reverse magic-auth for ' . $tmp_str); logger('Not authenticated. Invoking reverse magic-auth for ' . $tmp_str);
@ -1826,8 +1836,8 @@ function zid_init() {
$query = App::$query_string; $query = App::$query_string;
$query = str_replace(array('?zid=','&zid='),array('?rzid=','&rzid='),$query); $query = str_replace(array('?zid=','&zid='),array('?rzid=','&rzid='),$query);
$dest = '/' . $query; $dest = '/' . $query;
if($r && ($r[0]['hubloc_url'] != z_root()) && (! strstr($dest,'/magic')) && (! strstr($dest,'/rmagic'))) { if($r && ($r['hubloc_url'] != z_root()) && (! strstr($dest,'/magic')) && (! strstr($dest,'/rmagic'))) {
goaway($r[0]['hubloc_url'] . '/magic' . '?f=&rev=1&owa=1&bdest=' . bin2hex(z_root() . $dest)); goaway($r['hubloc_url'] . '/magic' . '?f=&rev=1&owa=1&bdest=' . bin2hex(z_root() . $dest));
} }
else else
logger('No hubloc found.'); logger('No hubloc found.');

View File

@ -161,22 +161,16 @@ class dba_pdo extends dba_driver {
} }
function unescapebin($str) { function unescapebin($str) {
if($this->driver_dbtype === 'pgsql' && (! is_null($str))) { if($this->driver_dbtype === 'pgsql') {
$x = ''; if(gettype($str) === 'resource') {
while(! feof($str)) { $str = stream_get_contents($str);
$x .= fread($str,8192);
} }
if(substr($x,0,2) === '\\x') { if(substr($str,0,2) === '\\x') {
$x = hex2bin(substr($x,2)); $str = hex2bin(substr($str,2));
} }
return $x;
} }
else {
return $str; return $str;
} }
}
function getdriver() { function getdriver() {
return 'pdo'; return 'pdo';

View File

@ -4,8 +4,11 @@
* @brief Event related functions. * @brief Event related functions.
*/ */
use Sabre\VObject; use Sabre\VObject;
use Zotlabs\Lib\Activity;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
use Ramsey\Uuid\Exception\UnsatisfiedDependencyException; use Ramsey\Uuid\Exception\UnsatisfiedDependencyException;
@ -65,7 +68,7 @@ function format_event_html($ev) {
} }
function format_event_obj($jobject) { function format_event_obj($jobject) {
$event = array(); $event = [];
$object = json_decode($jobject,true); $object = json_decode($jobject,true);
@ -1046,6 +1049,7 @@ function event_store_item($arr, $event) {
'location' => $arr['location'], 'location' => $arr['location'],
'adjust' => $arr['adjust'], 'adjust' => $arr['adjust'],
'content' => format_event_bbcode($arr), 'content' => format_event_bbcode($arr),
'attachment' => Activity::encode_attachment($r[0]),
'author' => array( 'author' => array(
'name' => $r[0]['xchan_name'], 'name' => $r[0]['xchan_name'],
'address' => $r[0]['xchan_addr'], 'address' => $r[0]['xchan_addr'],
@ -1200,6 +1204,7 @@ function event_store_item($arr, $event) {
'location' => $arr['location'], 'location' => $arr['location'],
'adjust' => $arr['adjust'], 'adjust' => $arr['adjust'],
'content' => format_event_bbcode($arr), 'content' => format_event_bbcode($arr),
'attachment' => Activity::encode_attachment($item_arr),
'author' => array( 'author' => array(
'name' => $x[0]['xchan_name'], 'name' => $x[0]['xchan_name'],
'address' => $x[0]['xchan_addr'], 'address' => $x[0]['xchan_addr'],

View File

@ -157,7 +157,7 @@ function get_all_perms($uid, $observer_xchan, $check_siteblock = true, $default_
// If we're still here, we have an observer, check the network. // If we're still here, we have an observer, check the network.
if($channel_perm & PERMS_NETWORK) { if($channel_perm & PERMS_NETWORK) {
if($x && $x[0]['xchan_network'] === 'zot') { if($x && in_array($x[0]['xchan_network'],[ 'zot','zot6'])) {
$ret[$perm_name] = true; $ret[$perm_name] = true;
continue; continue;
} }
@ -321,6 +321,14 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock =
dbesc($observer_xchan) dbesc($observer_xchan)
); );
if($y) { if($y) {
// This requires an explanation and the effects are subtle.
// The following line creates a fake connection, and this allows
// access tokens to have specific permissions even though they are
// not actual connections.
// The existence of this fake entry must be checked when dealing
// with connection related permissions.
$x = array(pseudo_abook($y[0])); $x = array(pseudo_abook($y[0]));
} }
} }
@ -349,6 +357,7 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock =
return true; return true;
// If it's an unauthenticated observer, we only need to see if PERMS_PUBLIC is set // If it's an unauthenticated observer, we only need to see if PERMS_PUBLIC is set
// We just did that.
if(! $observer_xchan) { if(! $observer_xchan) {
return false; return false;
@ -357,7 +366,7 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock =
// If we're still here, we have an observer, check the network. // If we're still here, we have an observer, check the network.
if($channel_perm & PERMS_NETWORK) { if($channel_perm & PERMS_NETWORK) {
if (($x && $x[0]['xchan_network'] === 'zot') || ($y && $y[0]['xchan_network'] === 'zot')) if ($x && in_array($x[0]['xchan_network'], ['zot','zot6']))
return true; return true;
} }
@ -373,8 +382,7 @@ function perm_is_allowed($uid, $observer_xchan, $permission, $check_siteblock =
return false; return false;
} }
// From here on we require that the observer be a connection and // From here on we require that the observer be a connection or pseudo connection
// handle whether we're allowing any, approved or specific ones
if(! $x) { if(! $x) {
return false; return false;

View File

@ -1,5 +1,6 @@
<?php <?php
use Zotlabs\Lib\Verify;
function is_matrix_url($url) { function is_matrix_url($url) {
@ -270,34 +271,45 @@ function red_zrlify_img_callback($matches) {
*/ */
function owt_init($token) { function owt_init($token) {
\Zotlabs\Lib\Verify::purge('owt', '3 MINUTE'); Verify::purge('owt', '3 MINUTE');
$ob_hash = \Zotlabs\Lib\Verify::get_meta('owt', 0, $token); $key = Verify::get_meta('owt', 0, $token);
if($ob_hash === false) { if($key === false) {
return;
}
$parts = explode(',',$key,2);
if(count($parts) < 2) {
return; return;
} }
$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_network = '%s' and hubloc_addr = '%s' order by hubloc_id desc",
dbesc($ob_hash) dbesc($parts[0]),
dbesc($parts[1])
); );
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); // @todo check that this is still needed. Discovery should have been performed in the Owa module.
$j = \Zotlabs\Zot\Finger::run($parts[1], null);
if ($j['success']) { if ($j['success']) {
import_xchan($j); 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_network = '%s' and hubloc_addr = '%s' order by hubloc_id desc",
dbesc($ob_hash) dbesc($parts[0]),
dbesc($parts[1])
); );
} }
} }
if(! $r) { if(! $r) {
logger('owt: unable to finger ' . $ob_hash); logger('owt: unable to finger ' . $key);
return; return;
} }
$hubloc = $r[0]; $hubloc = $r[0];
$_SESSION['authenticated'] = 1; $_SESSION['authenticated'] = 1;
@ -332,7 +344,7 @@ function owt_init($token) {
$arr = [ $arr = [
'xchan' => $hubloc, 'xchan' => $hubloc,
'url' => \App::$query_string, 'url' => App::$query_string,
'session' => $_SESSION 'session' => $_SESSION
]; ];
/** /**
@ -344,11 +356,11 @@ function owt_init($token) {
*/ */
call_hooks('magic_auth_success', $arr); call_hooks('magic_auth_success', $arr);
\App::set_observer($hubloc); App::set_observer($hubloc);
require_once('include/security.php'); require_once('include/security.php');
\App::set_groups(init_groups_visitor($_SESSION['visitor_id'])); App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
if(! get_config('system', 'hide_owa_greeting')) if(! get_config('system', 'hide_owa_greeting'))
info(sprintf( t('OpenWebAuth: %1$s welcomes %2$s'),\App::get_hostname(), $hubloc['xchan_name'])); info(sprintf( t('OpenWebAuth: %1$s welcomes %2$s'),App::get_hostname(), $hubloc['xchan_name']));
logger('OpenWebAuth: auth success from ' . $hubloc['xchan_addr']); logger('OpenWebAuth: auth success from ' . $hubloc['xchan_addr']);
} }
@ -384,7 +396,9 @@ function observer_auth($ob_hash) {
return; return;
} }
$hubloc = $r[0]; // Note: this has no Libzot namespace so prefers zot over zot6
$hubloc = zot_record_preferred($r);
$_SESSION['authenticated'] = 1; $_SESSION['authenticated'] = 1;
@ -395,8 +409,8 @@ function observer_auth($ob_hash) {
$_SESSION['remote_hub'] = $hubloc['hubloc_url']; $_SESSION['remote_hub'] = $hubloc['hubloc_url'];
$_SESSION['DNT'] = 1; $_SESSION['DNT'] = 1;
\App::set_observer($hubloc); App::set_observer($hubloc);
require_once('include/security.php'); require_once('include/security.php');
\App::set_groups(init_groups_visitor($_SESSION['visitor_id'])); App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
} }

View File

@ -5270,3 +5270,25 @@ function zot_reply_notify($data) {
$ret['success'] = true; $ret['success'] = true;
json_return_and_die($ret); json_return_and_die($ret);
} }
function zot_record_preferred($arr, $check = 'hubloc_network') {
if(! $arr) {
return $arr;
}
foreach($arr as $v) {
if($v[$check] === 'zot') {
return $v;
}
}
foreach($arr as $v) {
if($v[$check] === 'zot6') {
return $v;
}
}
return $arr[0];
}