aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--boot.php9
-rw-r--r--include/auth.php21
-rw-r--r--include/zot.php11
-rw-r--r--mod/magic.php119
-rw-r--r--mod/post.php151
5 files changed, 232 insertions, 79 deletions
diff --git a/boot.php b/boot.php
index 63c7325ea..5dddb6404 100644
--- a/boot.php
+++ b/boot.php
@@ -454,7 +454,7 @@ if(! class_exists('App')) {
private $widgets = array(); // widgets for this page
-
+ public $groups;
public $language;
public $module_loaded = false;
public $query_string;
@@ -749,6 +749,13 @@ if(! class_exists('App')) {
$this->apps = $arr;
}
+ function set_groups($g) {
+ $this->groups = $g;
+ }
+
+ function get_groups() {
+ return $this->groups;
+ }
function set_widget($title,$html, $location = 'aside') {
$this->widgets[] = array('title' => $title, 'html' => $html, 'location' => $location);
diff --git a/include/auth.php b/include/auth.php
index c12432449..75a450dc8 100644
--- a/include/auth.php
+++ b/include/auth.php
@@ -64,14 +64,19 @@ if((isset($_SESSION)) && (x($_SESSION,'authenticated')) && ((! (x($_POST,'auth-p
goaway(z_root());
}
-// if(x($_SESSION,'visitor_id') && (! x($_SESSION,'uid'))) {
-// $r = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1",
-// intval($_SESSION['visitor_id'])
-// );
-// if(count($r)) {
-// $a->contact = $r[0];
-// }
-// }
+ if(x($_SESSION,'visitor_id') && (! x($_SESSION,'uid'))) {
+ $r = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' limit 1",
+ dbesc($_SESSION['visitor_id'])
+ );
+ if($r) {
+ get_app()->set_observer($r[0]);
+ }
+ else {
+ unset($_SESSION['visitor_id']);
+ unset($_SESSION['authenticated']);
+ }
+ $a->set_groups(init_groups_visitor($_SESSION['visitor_id']));
+ }
if(x($_SESSION,'uid') || x($_SESSION,'account_id')) {
diff --git a/include/zot.php b/include/zot.php
index fc1241ff2..38bac5e93 100644
--- a/include/zot.php
+++ b/include/zot.php
@@ -101,18 +101,13 @@ function zot_build_packet($channel,$type = 'notify',$recipients = null, $remote_
'version' => ZOT_REVISION
);
- // These fields are present when using magic auth
-
- if(array_key_exists('token',$channel)) {
- $data['sender']['token'] = $channel['token'];
- $data['sender']['token_sig'] = $channel['token_sig'];
- }
-
if($recipients)
$data['recipients'] = $recipients;
- if($secret)
+ if($secret) {
$data['secret'] = $secret;
+ $data['secret_sig'] = base64url_encode(rsa_sign($secret,$channel['channel_prvkey']));
+ }
logger('zot_build_packet: ' . print_r($data,true));
diff --git a/mod/magic.php b/mod/magic.php
index 2ea686b1b..c5aeb4c8e 100644
--- a/mod/magic.php
+++ b/mod/magic.php
@@ -4,58 +4,74 @@
function magic_init(&$a) {
- $url = ((x($_REQUEST,'url')) ? $_REQUEST['url'] : '');
$addr = ((x($_REQUEST,'addr')) ? $_REQUEST['addr'] : '');
$hash = ((x($_REQUEST,'hash')) ? $_REQUEST['hash'] : '');
$dest = ((x($_REQUEST,'dest')) ? $_REQUEST['dest'] : '');
+ if($hash) {
+ $x = q("select xchan.xchan_url, hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash
+ where hublock_hash = '%s' and (hubloc_flags & %d) limit 1",
+ intval(HUBLOC_FLAGS_PRIMARY)
+ );
+ }
+ elseif($addr) {
+ $x = q("select hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash
+ where xchan_addr = '%s' and (hubloc_flags & %d) limit 1",
+ dbesc($addr),
+ intval(HUBLOC_FLAGS_PRIMARY)
+ );
+ }
- if(local_user()) {
-
- if($hash) {
- $x = q("select xchan.xchan_url, hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash
- where hublock_hash = '%s' and (hubloc_flags & %d) limit 1",
- intval(HUBLOC_FLAGS_PRIMARY)
- );
- }
- elseif($addr) {
- $x = q("select hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash
- where xchan_addr = '%s' and (hubloc_flags & %d) limit 1",
- dbesc($addr),
- intval(HUBLOC_FLAGS_PRIMARY)
- );
+ if(! $x) {
+
+ // Finger them if they've never been seen here before
+
+ if($addr) {
+ $ret = zot_finger($addr,null);
+ if($ret['success']) {
+ $j = json_decode($ret['body'],true);
+ if($j)
+ import_xchan($j);
+ $x = q("select hubloc.* from xchan left join hubloc on xchan_hash = hubloc_hash
+ where xchan_addr = '%s' and (hubloc_flags & %d) limit 1",
+ dbesc($addr),
+ intval(HUBLOC_FLAGS_PRIMARY)
+ );
+ }
}
+ }
- if(! $x) {
- notice( t('Channel not found.') . EOL);
- return;
- }
+ if(! $x) {
+ notice( t('Channel not found.') . EOL);
+ return;
+ }
- if($x[0]['hubloc_url'] === z_root()) {
- $webbie = substr($x[0]['hubloc_addr'],0,strpos('@',$x[0]['hubloc_addr']));
- switch($dest) {
- case 'channel':
- $desturl = z_root() . '/channel/' . $webbie;
- break;
- case 'photos':
- $desturl = z_root() . '/photos/' . $webbie;
- break;
- case 'profile':
- $desturl = z_root() . '/profile/' . $webbie;
- break;
- default:
- $desturl = $dest;
- break;
- }
- // We are already authenticated on this site and a registered observer.
- // Just redirect.
- goaway($desturl);
+ if($x[0]['hubloc_url'] === z_root()) {
+ $webbie = substr($x[0]['hubloc_addr'],0,strpos('@',$x[0]['hubloc_addr']));
+ switch($dest) {
+ case 'channel':
+ $desturl = z_root() . '/channel/' . $webbie;
+ break;
+ case 'photos':
+ $desturl = z_root() . '/photos/' . $webbie;
+ break;
+ case 'profile':
+ $desturl = z_root() . '/profile/' . $webbie;
+ break;
+ default:
+ $desturl = $dest;
+ break;
}
+ // We are already authenticated on this site and a registered observer.
+ // Just redirect.
+ goaway($desturl);
+ }
- $channel = $a->get_channel();
+ if(local_user()) {
+ $channel = $a->get_channel();
$token = random_string();
- $token_sig = rsa_sign($token,$channel['channel_prvkey']);
+ $token_sig = base64url_encode(rsa_sign($token,$channel['channel_prvkey']));
$channel['token'] = $token;
$channel['token_sig'] = $token_sig;
@@ -73,25 +89,12 @@ function magic_init(&$a) {
dbesc(datetime_convert())
);
- $packet = zot_build_packet($channel,'auth',$recip,$x[0]['hubloc_sitekey'],$hash);
- $result = zot_zot($x[0]['hubloc_callback'],$packet);
- if($result['success']) {
- $j = json_decode($result['body'],true);
- if($j['iv']) {
- $y = aes_unencapsulate($j,$channel['prvkey']);
- $j = json_decode($y,true);
- }
- if($j['token'] && $j['ticket'] && $j['token'] === $token) {
- $r = q("delete from verify where token = '%s' and type = '%s' and channel = %d limit 1",
- dbesc($token),
- dbesc('auth'),
- intval($channel['channel_id'])
- );
- goaway($x[0]['callback'] . '?f=&ticket=' . $ticket . '&dest=' . $dest);
- }
- }
- goaway($dest);
+ goaway($x[0]['hubloc_callback'] . '/' . substr($x[0]['hubloc_addr'],0,strpos($x[0]['hubloc_addr'],'@'))
+ . '/?f=&auth=' . $channel['channel_address'] . '@' . $a->get_hostname()
+ . '&sec=' . $token . '&dest=' . $dest . '&version=' . ZOT_REVISION);
}
+ if(strpos($dest,'/'))
+ goaway($dest);
goaway(z_root());
}
diff --git a/mod/post.php b/mod/post.php
index ee21f2ffb..bfcc99022 100644
--- a/mod/post.php
+++ b/mod/post.php
@@ -6,6 +6,110 @@
require_once('include/zot.php');
+
+
+function post_init(&$a) {
+
+ // All other access to this endpoint is via the post method.
+ // Here we will pick out the magic auth params which arrive
+ // as a get request.
+
+ if(argc() > 1) {
+
+ $webbie = argv(1);
+
+ if(array_key_exists('auth',$_REQUEST)) {
+
+ $address = $_REQUEST['auth'];
+ $dest = $_REQUEST['dest'];
+ $sec = $_REQUEST['sec'];
+ $version = $_REQUEST['version'];
+
+ switch($dest) {
+ case 'channel':
+ $desturl = z_root() . '/channel/' . $webbie;
+ break;
+ case 'photos':
+ $desturl = z_root() . '/photos/' . $webbie;
+ break;
+ case 'profile':
+ $desturl = z_root() . '/profile/' . $webbie;
+ break;
+ default:
+ $desturl = $dest;
+ break;
+ }
+ $c = q("select * from channel where channel_address = '%s' limit 1",
+ dbesc($webbie)
+ );
+ if(! $c) {
+ logger('mod_zot: auth: unable to find channel ' . $webbie);
+ // They'll get a notice when they hit the page, we don't need two.
+ goaway($desturl);
+ }
+
+ // Try and find a hubloc for the person attempting to auth
+ $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' limit 1",
+ dbesc($address)
+ );
+
+ if(! $x) {
+ // finger them if they can't be found.
+ $ret = zot_finger($addr,null);
+ if($ret['success']) {
+ $j = json_decode($ret['body'],true);
+ if($j)
+ import_xchan($j);
+ $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' limit 1",
+ dbesc($address)
+ );
+ }
+ }
+ if(! $x)
+ goaway($desturl);
+
+ // check credentials and access
+
+ // Auth packets MUST use ultra top-secret hush-hush mode
+
+ $p = zot_build_packet($c[0],$type = 'auth_check',array('guid' => $x[0]['hubloc_guid'],'guid_sig' => $x[0]['hubloc_guid_sig']), $x[0]['hubloc_prvkey'], $sec);
+ $result = zot_zot($x[0]['hubloc_url'],$p);
+
+ if($result['success']) {
+ $j = json_decode($result['body'],true);
+ if($j['result']) {
+ // everything is good... maybe
+ if(local_user()) {
+ notice( t('Remote authentication blocked. You are logged into this site locally. Please logout and retry') . EOL);
+ goaway($desturl);
+ }
+ // log them in
+ $_SESSION['authenticated'] = 1;
+ $_SESSION['visitor_id'] = $x[0]['xchan_hash'];
+ $a->set_observer($x[0]);
+ $a->set_groups(init_groups_visitor($_SESSION['visitor_id']));
+ notice(sprintf( t('Welcome %s. Remote authentication successful.'),$x[0]['xchan_name']));
+ }
+ }
+
+
+
+
+
+
+ goaway($desturl);
+ }
+
+ logger('mod_zot: invalid args: ' . print_r($a->argv,true));
+ killme();
+ }
+
+ return;
+}
+
+
+
+
function post_post(&$a) {
@@ -165,12 +269,51 @@ function post_post(&$a) {
}
- if($msgtype === 'auth') {
- logger('mod_post: auth: ' . print_r($data,true));
-
+ if($msgtype === 'auth_check') {
+ $arr = $data['sender'];
+ $sender_hash = base64url_encode(hash('whirlpool',$arr['guid'] . $arr['guid_sig'], true));
+ $y = q("select xchan_pubkey from xchan where xchan_hash = '%s' limit 1",
+ dbesc($sender_hash)
+ );
+ if((! $y) || (! rsa_verify($data['secret'],$data['secret_sig'],$y[0]['xchan_pubkey']))) {
+ logger('mod_zot: auth_check: sender not found or secret_sig invalid.');
+ json_return_and_die($ret);
+ }
+ if($data['recipients']) {
+
+ $arr = $data['recipients'][0];
+ $recip_hash = base64url_encode(hash('whirlpool',$arr['guid'] . $arr['guid_sig'], true));
+ $c = q("select channel_id from channel where channel_hash = '%s' limit 1",
+ dbesc($recip_hash)
+ );
+ if(! $c) {
+ logger('mod_zot: auth_check: recipient channel not found.');
+ json_return_and_die($ret);
+ }
+ $z = q("select id from verify where channel = %d and type = 'auth' and token = '%s' limit 1",
+ intval($c[0]['channel_id']),
+ dbesc($data['secret'])
+ );
+ if(! $z) {
+ logger('mod_zot: auth_check: verification key not found.');
+ json_return_and_die($ret);
+ }
+ $r = q("delete from verify where id = %d limit 1",
+ intval($z[0]['id'])
+ );
+
+ $ret['result'] = true;
+ json_return_and_die($ret);
+
+ }
+ json_return_and_die($ret);
}
-}
+ // catchall
+ json_return_and_die($ret);
+
+
+}