aboutsummaryrefslogtreecommitdiffstats
path: root/mod
diff options
context:
space:
mode:
authorredmatrix <redmatrix@redmatrix.me>2015-09-21 20:20:16 -0700
committerredmatrix <redmatrix@redmatrix.me>2015-09-21 20:20:16 -0700
commit8c16f12d7a8dab8def506cc5cd94105abb6e4fbb (patch)
tree2f869c378a719922ac47a2e1d1d6051bdb86b823 /mod
parenta679081993945d409cf88b6442610ad5b3dbd8b5 (diff)
downloadvolse-hubzilla-8c16f12d7a8dab8def506cc5cd94105abb6e4fbb.tar.gz
volse-hubzilla-8c16f12d7a8dab8def506cc5cd94105abb6e4fbb.tar.bz2
volse-hubzilla-8c16f12d7a8dab8def506cc5cd94105abb6e4fbb.zip
issue #52 - try all matching hublocs for remote auth, not just the "best one".
Diffstat (limited to 'mod')
-rw-r--r--mod/post.php263
1 files changed, 135 insertions, 128 deletions
diff --git a/mod/post.php b/mod/post.php
index 908b9eb1d..a429dc33a 100644
--- a/mod/post.php
+++ b/mod/post.php
@@ -119,7 +119,7 @@ function post_init(&$a) {
}
// 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' order by hubloc_id desc limit 1",
+ $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' order by hubloc_id desc",
dbesc($address)
);
@@ -130,7 +130,7 @@ function post_init(&$a) {
$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' order by hubloc_id desc limit 1",
+ $x = q("select * from hubloc left join xchan on xchan_hash = hubloc_hash where hubloc_addr = '%s' order by hubloc_id desc",
dbesc($address)
);
}
@@ -146,161 +146,169 @@ function post_init(&$a) {
goaway($desturl);
}
- logger('mod_zot: auth request received from ' . $x[0]['hubloc_addr'] );
- // check credentials and access
+ foreach($x as $xx) {
+ logger('mod_zot: auth request received from ' . $xx['hubloc_addr'] );
- // If they are already authenticated and haven't changed credentials,
- // we can save an expensive network round trip and improve performance.
+ // check credentials and access
- $remote = remote_channel();
- $result = null;
- $remote_service_class = '';
- $remote_level = 0;
- $remote_hub = $x[0]['hubloc_url'];
- $DNT = 0;
+ // If they are already authenticated and haven't changed credentials,
+ // we can save an expensive network round trip and improve performance.
- // Also check that they are coming from the same site as they authenticated with originally.
+ $remote = remote_channel();
+ $result = null;
+ $remote_service_class = '';
+ $remote_level = 0;
+ $remote_hub = $xx['hubloc_url'];
+ $DNT = 0;
- $already_authed = ((($remote) && ($x[0]['hubloc_hash'] == $remote) && ($x[0]['hubloc_url'] === $_SESSION['remote_hub'])) ? true : false);
- if($delegate && $delegate !== $_SESSION['delegate_channel'])
- $already_authed = false;
+ // Also check that they are coming from the same site as they authenticated with originally.
- $j = array();
+ $already_authed = ((($remote) && ($xx['hubloc_hash'] == $remote) && ($xx['hubloc_url'] === $_SESSION['remote_hub'])) ? true : false);
+ if($delegate && $delegate !== $_SESSION['delegate_channel'])
+ $already_authed = false;
- if (! $already_authed) {
+ $j = array();
- // Auth packets MUST use ultra top-secret hush-hush mode - e.g. the entire packet is encrypted using the site private key
- // The actual channel sending the packet ($c[0]) is not important, but this provides a generic zot packet with a sender
- // which can be verified
-
- $p = zot_build_packet($c[0],$type = 'auth_check', array(array('guid' => $x[0]['hubloc_guid'],'guid_sig' => $x[0]['hubloc_guid_sig'])), $x[0]['hubloc_sitekey'], $sec);
- if ($test) {
- $ret['message'] .= 'auth check packet created using sitekey ' . $x[0]['hubloc_sitekey'] . EOL;
- $ret['message'] .= 'packet contents: ' . $p . EOL;
- }
-
- $result = zot_zot($x[0]['hubloc_callback'],$p);
+ if (! $already_authed) {
- if (! $result['success']) {
- logger('mod_zot: auth_check callback failed.');
+ // Auth packets MUST use ultra top-secret hush-hush mode - e.g. the entire packet is encrypted using the site private key
+ // The actual channel sending the packet ($c[0]) is not important, but this provides a generic zot packet with a sender
+ // which can be verified
+
+ $p = zot_build_packet($c[0],$type = 'auth_check', array(array('guid' => $xx['hubloc_guid'],'guid_sig' => $xx['hubloc_guid_sig'])), $xx['hubloc_sitekey'], $sec);
if ($test) {
- $ret['message'] .= 'auth check request to your site returned .' . print_r($result, true) . EOL;
- json_return_and_die($ret);
- }
-
- goaway($desturl);
- }
- $j = json_decode($result['body'], true);
- if (! $j) {
- logger('mod_zot: auth_check json data malformed.');
- if($test) {
- $ret['message'] .= 'json malformed: ' . $result['body'] . EOL;
- json_return_and_die($ret);
+ $ret['message'] .= 'auth check packet created using sitekey ' . $xx['hubloc_sitekey'] . EOL;
+ $ret['message'] .= 'packet contents: ' . $p . EOL;
}
- }
- }
- if ($test) {
- $ret['message'] .= 'auth check request returned .' . print_r($j, true) . EOL;
- }
+ $result = zot_zot($xx['hubloc_callback'],$p);
- if ($already_authed || $j['success']) {
- if ($j['success']) {
- // legit response, but we do need to check that this wasn't answered by a man-in-middle
- if (! rsa_verify($sec . $x[0]['xchan_hash'],base64url_decode($j['confirm']),$x[0]['xchan_pubkey'])) {
- logger('mod_zot: auth: final confirmation failed.');
+ if (! $result['success']) {
+ logger('mod_zot: auth_check callback failed.');
if ($test) {
- $ret['message'] .= 'final confirmation failed. ' . $sec . print_r($j,true) . print_r($x[0],true);
- json_return_and_die($ret);
+ $ret['message'] .= 'auth check request to your site returned .' . print_r($result, true) . EOL;
+ continue;
}
-
- goaway($desturl);
+ continue;
}
- if (array_key_exists('service_class',$j))
- $remote_service_class = $j['service_class'];
- if (array_key_exists('level',$j))
- $remote_level = $j['level'];
- if (array_key_exists('DNT',$j))
- $DNT = $j['DNT'];
+ $j = json_decode($result['body'], true);
+ if (! $j) {
+ logger('mod_zot: auth_check json data malformed.');
+ if($test) {
+ $ret['message'] .= 'json malformed: ' . $result['body'] . EOL;
+ continue;
+ }
+ }
+ }
+
+ if ($test) {
+ $ret['message'] .= 'auth check request returned .' . print_r($j, true) . EOL;
}
- // everything is good... maybe
- if(local_channel()) {
- // tell them to logout if they're logged in locally as anything but the target remote account
- // in which case just shut up because they don't need to be doing this at all.
+ if ($already_authed || $j['success']) {
+ if ($j['success']) {
+ // legit response, but we do need to check that this wasn't answered by a man-in-middle
+ if (! rsa_verify($sec . $xx['xchan_hash'],base64url_decode($j['confirm']),$xx['xchan_pubkey'])) {
+ logger('mod_zot: auth: final confirmation failed.');
+ if ($test) {
+ $ret['message'] .= 'final confirmation failed. ' . $sec . print_r($j,true) . print_r($xx,true);
+ continue;
+ }
- if ($a->channel['channel_hash'] != $x[0]['xchan_hash']) {
- logger('mod_zot: auth: already authenticated locally as somebody else.');
- notice( t('Remote authentication blocked. You are logged into this site locally. Please logout and retry.') . EOL);
- if ($test) {
- $ret['message'] .= 'already logged in locally with a conflicting identity.' . EOL;
- json_return_and_die($ret);
+ continue;
}
+ if (array_key_exists('service_class',$j))
+ $remote_service_class = $j['service_class'];
+ if (array_key_exists('level',$j))
+ $remote_level = $j['level'];
+ if (array_key_exists('DNT',$j))
+ $DNT = $j['DNT'];
+ }
+ // everything is good... maybe
+ if(local_channel()) {
+
+ // tell them to logout if they're logged in locally as anything but the target remote account
+ // in which case just shut up because they don't need to be doing this at all.
+
+ if ($a->channel['channel_hash'] != $xx['xchan_hash']) {
+ logger('mod_zot: auth: already authenticated locally as somebody else.');
+ notice( t('Remote authentication blocked. You are logged into this site locally. Please logout and retry.') . EOL);
+ if ($test) {
+ $ret['message'] .= 'already logged in locally with a conflicting identity.' . EOL;
+ continue;
+ }
+ }
+ continue;
}
- goaway($desturl);
- }
- // log them in
+ // log them in
- if ($test) {
- $ret['success'] = true;
- $ret['message'] .= 'Authentication Success!' . EOL;
- json_return_and_die($ret);
- }
+ if ($test) {
+ $ret['success'] = true;
+ $ret['message'] .= 'Authentication Success!' . EOL;
+ json_return_and_die($ret);
+ }
- $delegation_success = false;
- if ($delegate) {
- $r = q("select * from channel left join xchan on channel_hash = xchan_hash where xchan_addr = '%s' limit 1",
- dbesc($delegate)
- );
- if ($r && intval($r[0]['channel_id'])) {
- $allowed = perm_is_allowed($r[0]['channel_id'],$x[0]['xchan_hash'],'delegate');
- if ($allowed) {
- $_SESSION['delegate_channel'] = $r[0]['channel_id'];
- $_SESSION['delegate'] = $x[0]['xchan_hash'];
- $_SESSION['account_id'] = intval($r[0]['channel_account_id']);
- require_once('include/security.php');
- change_channel($r[0]['channel_id']);
- $delegation_success = true;
+ $delegation_success = false;
+ if ($delegate) {
+ $r = q("select * from channel left join xchan on channel_hash = xchan_hash where xchan_addr = '%s' limit 1",
+ dbesc($delegate)
+ );
+ if ($r && intval($r[0]['channel_id'])) {
+ $allowed = perm_is_allowed($r[0]['channel_id'],$xx['xchan_hash'],'delegate');
+ if ($allowed) {
+ $_SESSION['delegate_channel'] = $r[0]['channel_id'];
+ $_SESSION['delegate'] = $xx['xchan_hash'];
+ $_SESSION['account_id'] = intval($r[0]['channel_account_id']);
+ require_once('include/security.php');
+ change_channel($r[0]['channel_id']);
+ $delegation_success = true;
+ }
}
}
- }
- $_SESSION['authenticated'] = 1;
- if (! $delegation_success) {
- $_SESSION['visitor_id'] = $x[0]['xchan_hash'];
- $_SESSION['my_url'] = $x[0]['xchan_url'];
- $_SESSION['my_address'] = $address;
- $_SESSION['remote_service_class'] = $remote_service_class;
- $_SESSION['remote_level'] = $remote_level;
- $_SESSION['remote_hub'] = $remote_hub;
- $_SESSION['DNT'] = $DNT;
+ $_SESSION['authenticated'] = 1;
+ if (! $delegation_success) {
+ $_SESSION['visitor_id'] = $xx['xchan_hash'];
+ $_SESSION['my_url'] = $xx['xchan_url'];
+ $_SESSION['my_address'] = $address;
+ $_SESSION['remote_service_class'] = $remote_service_class;
+ $_SESSION['remote_level'] = $remote_level;
+ $_SESSION['remote_hub'] = $remote_hub;
+ $_SESSION['DNT'] = $DNT;
+ }
+
+ $arr = array('xchan' => $xx, 'url' => $desturl, 'session' => $_SESSION);
+ call_hooks('magic_auth_success',$arr);
+ $a->set_observer($xx);
+ require_once('include/security.php');
+ $a->set_groups(init_groups_visitor($_SESSION['visitor_id']));
+ info(sprintf( t('Welcome %s. Remote authentication successful.'),$xx['xchan_name']));
+ logger('mod_zot: auth success from ' . $xx['xchan_addr']);
+ q("update hubloc set hubloc_status = (hubloc_status | %d ) where hubloc_id = %d ",
+ intval(HUBLOC_WORKS),
+ intval($xx['hubloc_id'])
+ );
+ } else {
+ if ($test) {
+ $ret['message'] .= 'auth failure. ' . print_r($_REQUEST,true) . print_r($j,true) . EOL;
+ continue;
+ }
+ logger('mod_zot: magic-auth failure - not authenticated: ' . $xx['xchan_addr']);
+ q("update hubloc set hubloc_status = (hubloc_status | %d ) where hubloc_id = %d ",
+ intval(HUBLOC_RECEIVE_ERROR),
+ intval($xx['hubloc_id'])
+ );
}
- $arr = array('xchan' => $x[0], 'url' => $desturl, 'session' => $_SESSION);
- call_hooks('magic_auth_success',$arr);
- $a->set_observer($x[0]);
- require_once('include/security.php');
- $a->set_groups(init_groups_visitor($_SESSION['visitor_id']));
- info(sprintf( t('Welcome %s. Remote authentication successful.'),$x[0]['xchan_name']));
- logger('mod_zot: auth success from ' . $x[0]['xchan_addr']);
- q("update hubloc set hubloc_status = (hubloc_status | %d ) where hubloc_id = %d ",
- intval(HUBLOC_WORKS),
- intval($x[0]['hubloc_id'])
- );
- } else {
if ($test) {
- $ret['message'] .= 'auth failure. ' . print_r($_REQUEST,true) . print_r($j,true) . EOL;
- json_return_and_die($ret);
+ $ret['message'] .= 'auth failure fallthrough ' . print_r($_REQUEST,true) . print_r($j,true) . EOL;
+ continue;
}
- logger('mod_zot: magic-auth failure - not authenticated: ' . $x[0]['xchan_addr']);
- q("update hubloc set hubloc_status = (hubloc_status | %d ) where hubloc_id = %d ",
- intval(HUBLOC_RECEIVE_ERROR),
- intval($x[0]['hubloc_id'])
- );
}
+
/**
* @FIXME we really want to save the return_url in the session before we
* visit rmagic. This does however prevent a recursion if you visit
@@ -308,14 +316,13 @@ function post_init(&$a) {
* But z_root() probably isn't where you really want to go.
*/
+ if(strstr($desturl,z_root() . '/rmagic'))
+ goaway(z_root());
+
if ($test) {
- $ret['message'] .= 'auth failure fallthrough ' . print_r($_REQUEST,true) . print_r($j,true) . EOL;
json_return_and_die($ret);
}
- if(strstr($desturl,z_root() . '/rmagic'))
- goaway(z_root());
-
goaway($desturl);
}
}