From 2de1285121b5f0260699a93249bab11dc74edec5 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 16 Jan 2018 18:15:58 -0800 Subject: z6 deliver --- include/zot.php | 79 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 8 deletions(-) (limited to 'include/zot.php') diff --git a/include/zot.php b/include/zot.php index 8e3d03ad8..1ab858480 100644 --- a/include/zot.php +++ b/include/zot.php @@ -211,8 +211,19 @@ function zot_best_algorithm($methods) { * @param array $data * @return array see z_post_url() for returned data format */ -function zot_zot($url, $data) { - return z_post_url($url, array('data' => $data)); +function zot_zot($url, $data, $channel = null) { + + $headers = []; + + if($channel) { + $headers['X-Zot-Token'] = random_string(); + $hash = \Zotlabs\Web\HTTPSig::generate_digest($data,false); + $headers['X-Zot-Digest'] = 'SHA-256=' . $hash; + \Zotlabs\Web\HTTPSig::create_sig('',$headers,$channel['channel_prvkey'],'acct:' . $channel['channel_address'] . '@' . \App::get_hostname(),false,true,'sha512'); + } + + $redirects = 0; + return z_post_url($url, array('data' => $data),$redirects,((is_empty($headers)) ? [] : [ 'headers' => $headers ])); } /** @@ -4967,21 +4978,73 @@ function zot_reply_refresh($sender, $recipients) { } +function zot6_check_sig() { + + $ret = [ 'success' => false ]; + + foreach([ 'REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION' ] as $head) { + if(array_key_exists($head,$_SERVER) && substr(trim($_SERVER[$head]),0,9) === 'Signature') { + if($head !== 'HTTP_AUTHORIZATION') { + $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER[$head]; + continue; + } + + $sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER[$head]); + if($sigblock) { + $keyId = $sigblock['keyId']; + + if($keyId) { + $r = q("select hubloc.*, site_crypto from hubloc left join site on hubloc_url = site_url + where hubloc_addr = '%s' ", + dbesc(str_replace('acct:','',$keyId)) + ); + if($r) { + foreach($r as $hubloc) { + $verified = \Zotlabs\Web\HTTPSig::verify('',$hubloc['xchan_pubkey']); + if($verified && $verified['header_signed'] && $verified['header_valid'] && $verified['content_signed'] && $verified['content_valid']) { + $ret['hubloc'] = $hubloc; + $ret['success'] = true; + return $ret; + } + } + } + } + } + } + } + + return $ret; +} + function zot_reply_notify($data) { $ret = array('success' => false); logger('notify received from ' . $data['sender']['url']); - $async = get_config('system','queued_fetch'); + // handle zot6 delivery - if($async) { - // add to receive queue - // qreceive_add($data); + $zret = zot6_check_sig(); + if($zret['success'] && $zret['hubloc'] && $zret['hubloc']['hubloc_guid'] === $data['sender']['guid']) { + logger('zot6_delivery'); + logger('zot6_data: ' . print_r($data,true),LOGGER_DATA); + $x = zot_import($data,$data['sender']['url']); + if($x) { + $x = crypto_encapsulate(json_encode($x),$zret['hubloc']['hubloc_sitekey'],zot_best_algorithm($zret['hubloc']['site_crypto'])); + $ret['delivery_report'] = $x; + } } else { - $x = zot_fetch($data); - $ret['delivery_report'] = $x; + $async = get_config('system','queued_fetch'); + + if($async) { + // add to receive queue + // qreceive_add($data); + } + else { + $x = zot_fetch($data); + $ret['delivery_report'] = $x; + } } $ret['success'] = true; -- cgit v1.2.3 From 05de59d4ad174cb106c3a5b5890732af51730384 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Tue, 16 Jan 2018 20:08:10 -0800 Subject: initial z6 delivery --- include/zot.php | 50 +++++++++++++++++++++++--------------------------- 1 file changed, 23 insertions(+), 27 deletions(-) (limited to 'include/zot.php') diff --git a/include/zot.php b/include/zot.php index 1ab858480..d97fe8113 100644 --- a/include/zot.php +++ b/include/zot.php @@ -219,11 +219,11 @@ function zot_zot($url, $data, $channel = null) { $headers['X-Zot-Token'] = random_string(); $hash = \Zotlabs\Web\HTTPSig::generate_digest($data,false); $headers['X-Zot-Digest'] = 'SHA-256=' . $hash; - \Zotlabs\Web\HTTPSig::create_sig('',$headers,$channel['channel_prvkey'],'acct:' . $channel['channel_address'] . '@' . \App::get_hostname(),false,true,'sha512'); + $h = \Zotlabs\Web\HTTPSig::create_sig('',$headers,$channel['channel_prvkey'],'acct:' . $channel['channel_address'] . '@' . \App::get_hostname(),false,false,'sha512'); } $redirects = 0; - return z_post_url($url, array('data' => $data),$redirects,((is_empty($headers)) ? [] : [ 'headers' => $headers ])); + return z_post_url($url, array('data' => $data),$redirects,((empty($h)) ? [] : [ 'headers' => $h ])); } /** @@ -4982,30 +4982,26 @@ function zot6_check_sig() { $ret = [ 'success' => false ]; - foreach([ 'REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION' ] as $head) { - if(array_key_exists($head,$_SERVER) && substr(trim($_SERVER[$head]),0,9) === 'Signature') { - if($head !== 'HTTP_AUTHORIZATION') { - $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER[$head]; - continue; - } - - $sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER[$head]); - if($sigblock) { - $keyId = $sigblock['keyId']; - - if($keyId) { - $r = q("select hubloc.*, site_crypto from hubloc left join site on hubloc_url = site_url - where hubloc_addr = '%s' ", - dbesc(str_replace('acct:','',$keyId)) - ); - if($r) { - foreach($r as $hubloc) { - $verified = \Zotlabs\Web\HTTPSig::verify('',$hubloc['xchan_pubkey']); - if($verified && $verified['header_signed'] && $verified['header_valid'] && $verified['content_signed'] && $verified['content_valid']) { - $ret['hubloc'] = $hubloc; - $ret['success'] = true; - return $ret; - } +logger('server: ' . print_r($_SERVER,true)); + + if(array_key_exists('HTTP_SIGNATURE',$_SERVER)) { +logger('parsing signature header'); + $sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER['HTTP_SIGNATURE']); + if($sigblock) { + $keyId = $sigblock['keyId']; + + if($keyId) { + $r = q("select hubloc.*, site_crypto from hubloc left join site on hubloc_url = site_url + where hubloc_addr = '%s' ", + dbesc(str_replace('acct:','',$keyId)) + ); + if($r) { + foreach($r as $hubloc) { + $verified = \Zotlabs\Web\HTTPSig::verify('',$hubloc['xchan_pubkey']); + if($verified && $verified['header_signed'] && $verified['header_valid'] && $verified['content_signed'] && $verified['content_valid']) { + $ret['hubloc'] = $hubloc; + $ret['success'] = true; + return $ret; } } } @@ -5028,7 +5024,7 @@ function zot_reply_notify($data) { if($zret['success'] && $zret['hubloc'] && $zret['hubloc']['hubloc_guid'] === $data['sender']['guid']) { logger('zot6_delivery'); logger('zot6_data: ' . print_r($data,true),LOGGER_DATA); - $x = zot_import($data,$data['sender']['url']); + $x = zot_import([ 'body' => json_encode($data) ],$data['sender']['url']); if($x) { $x = crypto_encapsulate(json_encode($x),$zret['hubloc']['hubloc_sitekey'],zot_best_algorithm($zret['hubloc']['site_crypto'])); $ret['delivery_report'] = $x; -- cgit v1.2.3 From 3a0db39fa05668831e7661ac6edaabfd09d864e2 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 7 Feb 2018 18:38:10 -0800 Subject: more zot6 delivery work --- include/zot.php | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) (limited to 'include/zot.php') diff --git a/include/zot.php b/include/zot.php index d97fe8113..e8ed827e2 100644 --- a/include/zot.php +++ b/include/zot.php @@ -158,6 +158,85 @@ function zot_build_packet($channel, $type = 'notify', $recipients = null, $remot return json_encode($data); } + +/** + * @brief Builds a zot6 notification packet. + * + * Builds a zot6 notification packet that you can either store in the queue with + * a message array or call zot_zot to immediately zot it to the other side. + * + * @param array $channel + * sender channel structure + * @param string $type + * packet type: one of 'ping', 'pickup', 'purge', 'refresh', 'keychange', 'force_refresh', 'notify', 'auth_check' + * @param array $recipients + * envelope information, array ( 'guid' => string, 'guid_sig' => string ); empty for public posts + * @param string $remote_key + * optional public site key of target hub used to encrypt entire packet + * NOTE: remote_key and encrypted packets are required for 'auth_check' packets, optional for all others + * @param string $methods + * optional comma separated list of encryption methods @ref zot_best_algorithm() + * @param string $secret + * random string, required for packets which require verification/callback + * e.g. 'pickup', 'purge', 'notify', 'auth_check'. Packet types 'ping', 'force_refresh', and 'refresh' do not require verification + * @param string $extra + * @returns string json encoded zot packet + */ +function zot6_build_packet($channel, $type = 'notify', $recipients = null, $msg = '', $remote_key = null, $methods = '', $secret = null, $extra = null) { + + $sig_method = get_config('system','signature_algorithm','sha256'); + + $data = [ + 'type' => $type, + 'sender' => [ + 'guid' => $channel['channel_guid'], + 'guid_sig' => base64url_encode(rsa_sign($channel['channel_guid'],$channel['channel_prvkey'],$sig_method)), + 'url' => z_root(), + 'url_sig' => base64url_encode(rsa_sign(z_root(),$channel['channel_prvkey'],$sig_method)), + 'sitekey' => get_config('system','pubkey') + ], + 'callback' => '/post', + 'version' => Zotlabs\Lib\System::get_zot_revision(), + 'encryption' => crypto_methods(), + 'signing' => signing_methods() + ]; + + if ($recipients) { + for ($x = 0; $x < count($recipients); $x ++) + unset($recipients[$x]['hash']); + + $data['recipients'] = $recipients; + } + + if($msg) { + $data['msg'] = $msg; + } + + if ($secret) { + $data['secret'] = preg_replace('/[^0-9a-fA-F]/','',$secret); + $data['secret_sig'] = base64url_encode(rsa_sign($secret,$channel['channel_prvkey'],$sig_method)); + } + + if ($extra) { + foreach ($extra as $k => $v) + $data[$k] = $v; + } + + logger('zot6_build_packet: ' . print_r($data,true), LOGGER_DATA, LOG_DEBUG); + + // Hush-hush ultra top-secret mode + + if($remote_key) { + $algorithm = zot_best_algorithm($methods); + $data = crypto_encapsulate(json_encode($data),$remote_key, $algorithm); + } + + return json_encode($data); +} + + + + /** * @brief Choose best encryption function from those available on both sites. * @@ -5024,7 +5103,12 @@ function zot_reply_notify($data) { if($zret['success'] && $zret['hubloc'] && $zret['hubloc']['hubloc_guid'] === $data['sender']['guid']) { logger('zot6_delivery'); logger('zot6_data: ' . print_r($data,true),LOGGER_DATA); - $x = zot_import([ 'body' => json_encode($data) ],$data['sender']['url']); + $import = [ 'pickup' => [ [ 'notify' => $data, 'message' => $data['msg'] ] ] ]; + unset($import['pickup'][0]['notify']['msg']); + + logger('import: ' . print_r($import,true), LOGGER_DATA); + + $x = zot_import([ 'body' => json_encode($import) ],$data['sender']['url']); if($x) { $x = crypto_encapsulate(json_encode($x),$zret['hubloc']['hubloc_sitekey'],zot_best_algorithm($zret['hubloc']['site_crypto'])); $ret['delivery_report'] = $x; -- cgit v1.2.3 From 5057a4bd4cfa34ef9821889e8b11707f495d64f0 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 7 Feb 2018 19:15:56 -0800 Subject: zot6 delivery work --- include/zot.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/zot.php') diff --git a/include/zot.php b/include/zot.php index e8ed827e2..b44991fab 100644 --- a/include/zot.php +++ b/include/zot.php @@ -5101,10 +5101,10 @@ function zot_reply_notify($data) { $zret = zot6_check_sig(); if($zret['success'] && $zret['hubloc'] && $zret['hubloc']['hubloc_guid'] === $data['sender']['guid']) { - logger('zot6_delivery'); + logger('zot6_delivery',LOGGER_DEBUG); logger('zot6_data: ' . print_r($data,true),LOGGER_DATA); - $import = [ 'pickup' => [ [ 'notify' => $data, 'message' => $data['msg'] ] ] ]; - unset($import['pickup'][0]['notify']['msg']); + $import = [ 'success' => true, 'pickup' => [ [ 'notify' => $data, 'message' => json_decode($data['msg'],true) ] ] ]; + // unset($import['pickup'][0]['notify']['msg']); logger('import: ' . print_r($import,true), LOGGER_DATA); -- cgit v1.2.3 From b21a5c3ce902c4c88b2bb3dcae5d63a93e25479c Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 7 Feb 2018 20:17:32 -0800 Subject: compatibility: fallback to legacy zot if OWA succeeds but no data['msg'] is present --- include/zot.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/zot.php') diff --git a/include/zot.php b/include/zot.php index b44991fab..5fb18d5a7 100644 --- a/include/zot.php +++ b/include/zot.php @@ -5100,7 +5100,7 @@ function zot_reply_notify($data) { // handle zot6 delivery $zret = zot6_check_sig(); - if($zret['success'] && $zret['hubloc'] && $zret['hubloc']['hubloc_guid'] === $data['sender']['guid']) { + if($zret['success'] && $zret['hubloc'] && $zret['hubloc']['hubloc_guid'] === $data['sender']['guid'] && $data['msg']) { logger('zot6_delivery',LOGGER_DEBUG); logger('zot6_data: ' . print_r($data,true),LOGGER_DATA); $import = [ 'success' => true, 'pickup' => [ [ 'notify' => $data, 'message' => json_decode($data['msg'],true) ] ] ]; -- cgit v1.2.3 From 6cf2e9945a08451e3d53b6e79002843e9cdb8dc6 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Wed, 7 Feb 2018 21:53:47 -0800 Subject: encrypt the httpsig for zot6 transport --- include/zot.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/zot.php') diff --git a/include/zot.php b/include/zot.php index 5fb18d5a7..c00caebb4 100644 --- a/include/zot.php +++ b/include/zot.php @@ -288,9 +288,11 @@ function zot_best_algorithm($methods) { * * @param string $url * @param array $data + * @param array $channel (optional if using zot6 delivery) + * @param array $crypto (optional if encrypted httpsig, requires hubloc_sitekey and site_crypto elements) * @return array see z_post_url() for returned data format */ -function zot_zot($url, $data, $channel = null) { +function zot_zot($url, $data, $channel = null,$crypto = null) { $headers = []; @@ -298,7 +300,7 @@ function zot_zot($url, $data, $channel = null) { $headers['X-Zot-Token'] = random_string(); $hash = \Zotlabs\Web\HTTPSig::generate_digest($data,false); $headers['X-Zot-Digest'] = 'SHA-256=' . $hash; - $h = \Zotlabs\Web\HTTPSig::create_sig('',$headers,$channel['channel_prvkey'],'acct:' . $channel['channel_address'] . '@' . \App::get_hostname(),false,false,'sha512'); + $h = \Zotlabs\Web\HTTPSig::create_sig('',$headers,$channel['channel_prvkey'],'acct:' . $channel['channel_address'] . '@' . \App::get_hostname(),false,false,'sha512',(($crypto) ? $crypto['hubloc_sitekey'] : ''), (($crypto) ? zot_best_algorithm($crypto['site_crypto']) : '')); } $redirects = 0; -- cgit v1.2.3 From 635c5e532bd945fe50dc3fae73e4da005158e3de Mon Sep 17 00:00:00 2001 From: zotlabs Date: Thu, 8 Feb 2018 15:32:54 -0800 Subject: z6 testing --- include/zot.php | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/zot.php') diff --git a/include/zot.php b/include/zot.php index c00caebb4..16b0a1c8e 100644 --- a/include/zot.php +++ b/include/zot.php @@ -296,6 +296,8 @@ function zot_zot($url, $data, $channel = null,$crypto = null) { $headers = []; +logger('crypto: ' . print_r($crypto,true)); + if($channel) { $headers['X-Zot-Token'] = random_string(); $hash = \Zotlabs\Web\HTTPSig::generate_digest($data,false); -- cgit v1.2.3 From cd1e5d417167836ee5ac64d042815b377c22b694 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Thu, 8 Feb 2018 16:22:10 -0800 Subject: zot6 testing --- include/zot.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'include/zot.php') diff --git a/include/zot.php b/include/zot.php index 16b0a1c8e..331ec35e3 100644 --- a/include/zot.php +++ b/include/zot.php @@ -296,8 +296,6 @@ function zot_zot($url, $data, $channel = null,$crypto = null) { $headers = []; -logger('crypto: ' . print_r($crypto,true)); - if($channel) { $headers['X-Zot-Token'] = random_string(); $hash = \Zotlabs\Web\HTTPSig::generate_digest($data,false); @@ -5107,18 +5105,24 @@ function zot_reply_notify($data) { if($zret['success'] && $zret['hubloc'] && $zret['hubloc']['hubloc_guid'] === $data['sender']['guid'] && $data['msg']) { logger('zot6_delivery',LOGGER_DEBUG); logger('zot6_data: ' . print_r($data,true),LOGGER_DATA); + + $ret['collected'] = true; + $import = [ 'success' => true, 'pickup' => [ [ 'notify' => $data, 'message' => json_decode($data['msg'],true) ] ] ]; - // unset($import['pickup'][0]['notify']['msg']); + unset($import['pickup'][0]['notify']['msg']); logger('import: ' . print_r($import,true), LOGGER_DATA); - $x = zot_import([ 'body' => json_encode($import) ],$data['sender']['url']); + $x = zot_import([ 'success' => true, 'body' => json_encode($import) ], $data['sender']['url']); if($x) { $x = crypto_encapsulate(json_encode($x),$zret['hubloc']['hubloc_sitekey'],zot_best_algorithm($zret['hubloc']['site_crypto'])); $ret['delivery_report'] = $x; } } else { + + // handle traditional zot delivery + $async = get_config('system','queued_fetch'); if($async) { -- cgit v1.2.3 From 9f5d44fa32b1ef9e103f98dcf7d68bfef1fdd94f Mon Sep 17 00:00:00 2001 From: zotlabs Date: Thu, 8 Feb 2018 16:30:44 -0800 Subject: turn the logs down again --- include/zot.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/zot.php') diff --git a/include/zot.php b/include/zot.php index 331ec35e3..1a9909de1 100644 --- a/include/zot.php +++ b/include/zot.php @@ -5063,10 +5063,9 @@ function zot6_check_sig() { $ret = [ 'success' => false ]; -logger('server: ' . print_r($_SERVER,true)); + logger('server: ' . print_r($_SERVER,true), LOGGER_DATA); if(array_key_exists('HTTP_SIGNATURE',$_SERVER)) { -logger('parsing signature header'); $sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER['HTTP_SIGNATURE']); if($sigblock) { $keyId = $sigblock['keyId']; -- cgit v1.2.3 From 3dfafb710c901cd78b75681e39156a9f018b1ac9 Mon Sep 17 00:00:00 2001 From: zotlabs Date: Thu, 8 Feb 2018 21:32:18 -0800 Subject: cosmetic --- include/zot.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/zot.php') diff --git a/include/zot.php b/include/zot.php index 1a9909de1..1042f09d9 100644 --- a/include/zot.php +++ b/include/zot.php @@ -5108,9 +5108,8 @@ function zot_reply_notify($data) { $ret['collected'] = true; $import = [ 'success' => true, 'pickup' => [ [ 'notify' => $data, 'message' => json_decode($data['msg'],true) ] ] ]; - unset($import['pickup'][0]['notify']['msg']); - logger('import: ' . print_r($import,true), LOGGER_DATA); + logger('zot6_import: ' . print_r($import,true), LOGGER_DATA); $x = zot_import([ 'success' => true, 'body' => json_encode($import) ], $data['sender']['url']); if($x) { -- cgit v1.2.3