diff options
-rw-r--r-- | Zotlabs/Daemon/Gprobe.php | 5 | ||||
-rw-r--r-- | Zotlabs/Module/Chanview.php | 9 | ||||
-rw-r--r-- | Zotlabs/Module/Magic.php | 8 | ||||
-rw-r--r-- | Zotlabs/Module/Mail.php | 7 | ||||
-rw-r--r-- | Zotlabs/Module/Probe.php | 16 | ||||
-rw-r--r-- | Zotlabs/Module/Regdir.php | 13 | ||||
-rw-r--r-- | Zotlabs/Zot/Auth.php | 8 | ||||
-rw-r--r-- | Zotlabs/Zot/Finger.php | 130 | ||||
-rw-r--r-- | include/dir_fns.php | 5 | ||||
-rw-r--r-- | include/follow.php | 6 | ||||
-rw-r--r-- | include/socgraph.php | 8 | ||||
-rw-r--r-- | include/zot.php | 6 | ||||
-rwxr-xr-x | util/fresh | 4 |
13 files changed, 173 insertions, 52 deletions
diff --git a/Zotlabs/Daemon/Gprobe.php b/Zotlabs/Daemon/Gprobe.php index 8141739be..43cce93c3 100644 --- a/Zotlabs/Daemon/Gprobe.php +++ b/Zotlabs/Daemon/Gprobe.php @@ -22,9 +22,8 @@ class Gprobe { ); if(! $r) { - $x = zot_finger($url,null); - if($x['success']) { - $j = json_decode($x['body'],true); + $j = \Zotlabs\Zot\Finger::run($url,null); + if($j['success']) { $y = import_xchan($j); } } diff --git a/Zotlabs/Module/Chanview.php b/Zotlabs/Module/Chanview.php index f70444816..36fbbb864 100644 --- a/Zotlabs/Module/Chanview.php +++ b/Zotlabs/Module/Chanview.php @@ -62,18 +62,15 @@ class Chanview extends \Zotlabs\Web\Controller { } if($_REQUEST['address']) { - $ret = zot_finger($_REQUEST['address'],null); - if($ret['success']) { - $j = json_decode($ret['body'],true); - if($j) - import_xchan($j); + $j = \Zotlabs\Zot\Finger::run($_REQUEST['address'],null); + if($j['success']) { + import_xchan($j); $r = q("select * from xchan where xchan_addr = '%s' limit 1", dbesc($_REQUEST['address']) ); if($r) \App::$poi = $r[0]; } - } } diff --git a/Zotlabs/Module/Magic.php b/Zotlabs/Module/Magic.php index 63db4a317..6798f72a9 100644 --- a/Zotlabs/Module/Magic.php +++ b/Zotlabs/Module/Magic.php @@ -47,11 +47,9 @@ class Magic extends \Zotlabs\Web\Controller { * */ - $ret = zot_finger((($addr) ? $addr : '[system]@' . $parsed['host']),null); - if($ret['success']) { - $j = json_decode($ret['body'],true); - if($j) - import_xchan($j); + $j = \Zotlabs\Zot\Finger::run((($addr) ? $addr : '[system]@' . $parsed['host']),null); + if($j['success']) { + import_xchan($j); // Now try again diff --git a/Zotlabs/Module/Mail.php b/Zotlabs/Module/Mail.php index e6487d681..3dbfa8d71 100644 --- a/Zotlabs/Module/Mail.php +++ b/Zotlabs/Module/Mail.php @@ -32,17 +32,16 @@ class Mail extends \Zotlabs\Web\Controller { if(! $recipient) { $channel = \App::get_channel(); - $ret = zot_finger($rstr,$channel); + $j = \Zotlabs\Zot\Finger::run($rstr,$channel); - if(! $ret['success']) { + if(! $j['success']) { notice( t('Unable to lookup recipient.') . EOL); return; } - $j = json_decode($ret['body'],true); logger('message_post: lookup: ' . $url . ' ' . print_r($j,true)); - if(! ($j['success'] && $j['guid'])) { + if(! $j['guid']) { notice( t('Unable to communicate with requested channel.')); return; } diff --git a/Zotlabs/Module/Probe.php b/Zotlabs/Module/Probe.php index 79abe9819..dda792131 100644 --- a/Zotlabs/Module/Probe.php +++ b/Zotlabs/Module/Probe.php @@ -20,17 +20,17 @@ class Probe extends \Zotlabs\Web\Controller { $channel = \App::get_channel(); $addr = trim($_GET['addr']); $do_import = ((intval($_GET['import']) && is_site_admin()) ? true : false); - $res = zot_finger($addr,$channel,false); + + $j = \Zotlabs\Zot\Finger::run($addr,$channel,false); + + // $res = zot_finger($addr,$channel,false); + $o .= '<pre>'; - if($res['success']) - $j = json_decode($res['body'],true); - else { + if(! $j['success']) { $o .= sprintf( t('Fetching URL returns error: %1$s'),$res['error'] . "\r\n\r\n"); $o .= "<strong>https connection failed. Trying again with auto failover to http.</strong>\r\n\r\n"; - $res = zot_finger($addr,$channel,true); - if($res['success']) - $j = json_decode($res['body'],true); - else + $j = \Zotlabs\Zot\Finger::run($addr,$channel,true); + if(! $j['success']) $o .= sprintf( t('Fetching URL returns error: %1$s'),$res['error'] . "\r\n\r\n"); } diff --git a/Zotlabs/Module/Regdir.php b/Zotlabs/Module/Regdir.php index 65f8daf67..48a7cc16d 100644 --- a/Zotlabs/Module/Regdir.php +++ b/Zotlabs/Module/Regdir.php @@ -60,14 +60,11 @@ class Regdir extends \Zotlabs\Web\Controller { json_return_and_die($result); } - $f = zot_finger('[system]@' . $m['host']); - if($f['success']) { - $j = json_decode($f['body'],true); - if($j['success'] && $j['guid']) { - $x = import_xchan($j); - if($x['success']) { - $result['success'] = true; - } + $j = \Zotlabs\Zot\Finger::run('[system]@' . $m['host']); + if($j['success'] && $j['guid']) { + $x = import_xchan($j); + if($x['success']) { + $result['success'] = true; } } diff --git a/Zotlabs/Zot/Auth.php b/Zotlabs/Zot/Auth.php index f764172fa..0837be21a 100644 --- a/Zotlabs/Zot/Auth.php +++ b/Zotlabs/Zot/Auth.php @@ -80,11 +80,9 @@ class Auth { if(! $x) { // finger them if they can't be found. - $ret = zot_finger($address, null); - if ($ret['success']) { - $j = json_decode($ret['body'], true); - if($j) - import_xchan($j); + $j = Finger::run($address, null); + if ($j['success']) { + import_xchan($j); $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' order by hubloc_id desc", dbesc($address) diff --git a/Zotlabs/Zot/Finger.php b/Zotlabs/Zot/Finger.php new file mode 100644 index 000000000..27ba6ddca --- /dev/null +++ b/Zotlabs/Zot/Finger.php @@ -0,0 +1,130 @@ +<?php + +namespace Zotlabs\Zot; + + +class Finger { + + static private $token; + + /** + * @brief Look up information about channel. + * + * @param string $webbie + * does not have to be host qualified e.g. 'foo' is treated as 'foo\@thishub' + * @param array $channel + * (optional), if supplied permissions will be enumerated specifically for $channel + * @param boolean $autofallback + * fallback/failover to http if https connection cannot be established. Default is true. + * + * @return array see z_post_url() and \ref mod/zfinger.php + */ + + static public function run($webbie, $channel = null, $autofallback = true) { + + $ret = array('success' => false); + + self::$token = random_string(); + + if (strpos($webbie,'@') === false) { + $address = $webbie; + $host = App::get_hostname(); + } else { + $address = substr($webbie,0,strpos($webbie,'@')); + $host = substr($webbie,strpos($webbie,'@')+1); + } + + $xchan_addr = $address . '@' . $host; + + if ((! $address) || (! $xchan_addr)) { + logger('zot_finger: no address :' . $webbie); + return $ret; + } + + logger('using xchan_addr: ' . $xchan_addr, LOGGER_DATA, LOG_DEBUG); + + // potential issue here; the xchan_addr points to the primary hub. + // The webbie we were called with may not, so it might not be found + // unless we query for hubloc_addr instead of xchan_addr + + $r = q("select xchan.*, hubloc.* from xchan + left join hubloc on xchan_hash = hubloc_hash + where xchan_addr = '%s' and hubloc_primary = 1 limit 1", + dbesc($xchan_addr) + ); + + if ($r) { + $url = $r[0]['hubloc_url']; + + if ($r[0]['hubloc_network'] && $r[0]['hubloc_network'] !== 'zot') { + logger('zot_finger: alternate network: ' . $webbie); + logger('url: '.$url.', net: '.var_export($r[0]['hubloc_network'],true), LOGGER_DATA, LOG_DEBUG); + return $ret; + } + } + else { + $url = 'https://' . $host; + } + + $rhs = '/.well-known/zot-info'; + $https = ((strpos($url,'https://') === 0) ? true : false); + + logger('zot_finger: ' . $address . ' at ' . $url, LOGGER_DEBUG); + + if ($channel) { + $postvars = array( + 'address' => $address, + 'target' => $channel['channel_guid'], + 'target_sig' => $channel['channel_guid_sig'], + 'key' => $channel['channel_pubkey'], + 'token' => self::$token + ); + + $result = z_post_url($url . $rhs,$postvars); + + if ((! $result['success']) && ($autofallback)) { + if ($https) { + logger('zot_finger: https failed. falling back to http'); + $result = z_post_url('http://' . $host . $rhs,$postvars); + } + } + } + else { + $rhs .= '?f=&address=' . urlencode($address) . '&token=' . self::$token; + + $result = z_fetch_url($url . $rhs); + if ((! $result['success']) && ($autofallback)) { + if ($https) { + logger('zot_finger: https failed. falling back to http'); + $result = z_fetch_url('http://' . $host . $rhs); + } + } + } + + if(! $result['success']) { + logger('zot_finger: no results'); + return $ret; + } + + $x = json_decode($result['body'],true); + if($x) { + $signed_token = $x['signed_token']; + if($signed_token) { + $valid = rsa_verify(self::$token,base64url_decode($signed_token),$x['key']); + if(! $valid) { + logger('invalid signed token: ' . $url . $rhs, LOGGER_NORMAL, LOG_WARN); + return $ret; + } + } + else { + logger('No signed token from ' . $url . $rhs, LOGGER_NORMAL, LOG_WARN); + // after 2017-01-01 this will be a hard error unless you over-ride it. + if((time() > 1483228800) && (! get_config('system','allow_unsigned_zotfinger'))) + return $ret; + } + } + + return $x; + } + +}
\ No newline at end of file diff --git a/include/dir_fns.php b/include/dir_fns.php index 1c3149081..4e300663c 100644 --- a/include/dir_fns.php +++ b/include/dir_fns.php @@ -69,9 +69,8 @@ function check_upstream_directory() { if ($directory) { $h = parse_url($directory); if ($h) { - $x = zot_finger('[system]@' . $h['host']); - if ($x['success']) { - $j = json_decode($x['body'], true); + $j = Zotlabs\Zot\Finger::run('[system]@' . $h['host']); + if ($j['success']) { if (array_key_exists('site', $j) && array_key_exists('directory_mode', $j['site'])) { if ($j['site']['directory_mode'] === 'normal') { $isadir = false; diff --git a/include/follow.php b/include/follow.php index e4f7e8557..dd43c7c4c 100644 --- a/include/follow.php +++ b/include/follow.php @@ -56,11 +56,11 @@ function new_contact($uid,$url,$channel,$interactive = false, $confirm = false) if($arr['channel']['success']) $ret = $arr['channel']; elseif(! $is_http) - $ret = zot_finger($url,$channel); + $ret = Zotlabs\Zot\Finger::run($url,$channel); - if($ret && $ret['success']) { + if($ret && is_array($ret) && $ret['success']) { $is_red = true; - $j = json_decode($ret['body'],true); + $j = $ret; } $my_perms = get_channel_default_perms($uid); diff --git a/include/socgraph.php b/include/socgraph.php index 1b1bccf20..dffaa8923 100644 --- a/include/socgraph.php +++ b/include/socgraph.php @@ -152,11 +152,9 @@ function poco_load($xchan = '', $url = null) { if(($x !== false) && (! count($x))) { if($address) { if($network === 'zot') { - $z = zot_finger($address,null); - if($z['success']) { - $j = json_decode($z['body'],true); - if($j) - import_xchan($j); + $j = Zotlabs\Zot\Finger::run($address,null); + if($j['success']) { + import_xchan($j); } $x = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1", dbesc($hash) diff --git a/include/zot.php b/include/zot.php index 54a3fe640..f5fb87e12 100644 --- a/include/zot.php +++ b/include/zot.php @@ -3672,6 +3672,8 @@ function zotinfo($arr) { $zsig = ((x($arr,'target_sig')) ? $arr['target_sig'] : ''); $zkey = ((x($arr,'key')) ? $arr['key'] : ''); $mindate = ((x($arr,'mindate')) ? $arr['mindate'] : ''); + $token = ((x($arr,'token')) ? $arr['token'] : ''); + $feed = ((x($arr,'feed')) ? intval($arr['feed']) : 0); if($ztarget) { @@ -3816,6 +3818,10 @@ function zotinfo($arr) { // Communication details + if($token) + $ret['signed_token'] = base64url_encode(rsa_sign($token,$e['channel_prvkey'])); + + $ret['guid'] = $e['xchan_guid']; $ret['guid_sig'] = $e['xchan_guid_sig']; $ret['key'] = $e['xchan_pubkey']; diff --git a/util/fresh b/util/fresh index c70f1cac9..9d74ea584 100755 --- a/util/fresh +++ b/util/fresh @@ -68,9 +68,9 @@ function process_command($line) { case 'finger': if(argv(1)) { - $x = zot_finger(argv(1),$channel); + $x = Zotlabs\Zot\Finger::run(argv(1),$channel); if($x['success']) - echo jindent($x['body']); + echo jindent($x); } break; |