issue #52 - try all matching hublocs for remote auth, not just the "best one".

This commit is contained in:
redmatrix 2015-09-21 20:20:16 -07:00
parent a679081993
commit 8c16f12d7a
2 changed files with 139 additions and 132 deletions

View File

@ -119,7 +119,7 @@ function post_init(&$a) {
} }
// Try and find a hubloc for the person attempting to auth // 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) dbesc($address)
); );
@ -130,7 +130,7 @@ function post_init(&$a) {
$j = json_decode($ret['body'], true); $j = json_decode($ret['body'], true);
if ($j) if ($j)
import_xchan($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) dbesc($address)
); );
} }
@ -146,7 +146,9 @@ function post_init(&$a) {
goaway($desturl); goaway($desturl);
} }
logger('mod_zot: auth request received from ' . $x[0]['hubloc_addr'] );
foreach($x as $xx) {
logger('mod_zot: auth request received from ' . $xx['hubloc_addr'] );
// check credentials and access // check credentials and access
@ -157,12 +159,12 @@ function post_init(&$a) {
$result = null; $result = null;
$remote_service_class = ''; $remote_service_class = '';
$remote_level = 0; $remote_level = 0;
$remote_hub = $x[0]['hubloc_url']; $remote_hub = $xx['hubloc_url'];
$DNT = 0; $DNT = 0;
// Also check that they are coming from the same site as they authenticated with originally. // Also check that they are coming from the same site as they authenticated with originally.
$already_authed = ((($remote) && ($x[0]['hubloc_hash'] == $remote) && ($x[0]['hubloc_url'] === $_SESSION['remote_hub'])) ? true : false); $already_authed = ((($remote) && ($xx['hubloc_hash'] == $remote) && ($xx['hubloc_url'] === $_SESSION['remote_hub'])) ? true : false);
if($delegate && $delegate !== $_SESSION['delegate_channel']) if($delegate && $delegate !== $_SESSION['delegate_channel'])
$already_authed = false; $already_authed = false;
@ -174,29 +176,28 @@ function post_init(&$a) {
// The actual channel sending the packet ($c[0]) is not important, but this provides a generic zot packet with a sender // 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 // 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); $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) { if ($test) {
$ret['message'] .= 'auth check packet created using sitekey ' . $x[0]['hubloc_sitekey'] . EOL; $ret['message'] .= 'auth check packet created using sitekey ' . $xx['hubloc_sitekey'] . EOL;
$ret['message'] .= 'packet contents: ' . $p . EOL; $ret['message'] .= 'packet contents: ' . $p . EOL;
} }
$result = zot_zot($x[0]['hubloc_callback'],$p); $result = zot_zot($xx['hubloc_callback'],$p);
if (! $result['success']) { if (! $result['success']) {
logger('mod_zot: auth_check callback failed.'); logger('mod_zot: auth_check callback failed.');
if ($test) { if ($test) {
$ret['message'] .= 'auth check request to your site returned .' . print_r($result, true) . EOL; $ret['message'] .= 'auth check request to your site returned .' . print_r($result, true) . EOL;
json_return_and_die($ret); continue;
} }
continue;
goaway($desturl);
} }
$j = json_decode($result['body'], true); $j = json_decode($result['body'], true);
if (! $j) { if (! $j) {
logger('mod_zot: auth_check json data malformed.'); logger('mod_zot: auth_check json data malformed.');
if($test) { if($test) {
$ret['message'] .= 'json malformed: ' . $result['body'] . EOL; $ret['message'] .= 'json malformed: ' . $result['body'] . EOL;
json_return_and_die($ret); continue;
} }
} }
} }
@ -208,14 +209,14 @@ function post_init(&$a) {
if ($already_authed || $j['success']) { if ($already_authed || $j['success']) {
if ($j['success']) { if ($j['success']) {
// legit response, but we do need to check that this wasn't answered by a man-in-middle // 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'])) { if (! rsa_verify($sec . $xx['xchan_hash'],base64url_decode($j['confirm']),$xx['xchan_pubkey'])) {
logger('mod_zot: auth: final confirmation failed.'); logger('mod_zot: auth: final confirmation failed.');
if ($test) { if ($test) {
$ret['message'] .= 'final confirmation failed. ' . $sec . print_r($j,true) . print_r($x[0],true); $ret['message'] .= 'final confirmation failed. ' . $sec . print_r($j,true) . print_r($xx,true);
json_return_and_die($ret); continue;
} }
goaway($desturl); continue;
} }
if (array_key_exists('service_class',$j)) if (array_key_exists('service_class',$j))
$remote_service_class = $j['service_class']; $remote_service_class = $j['service_class'];
@ -230,15 +231,15 @@ function post_init(&$a) {
// tell them to logout if they're logged in locally as anything but the target remote account // 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. // in which case just shut up because they don't need to be doing this at all.
if ($a->channel['channel_hash'] != $x[0]['xchan_hash']) { if ($a->channel['channel_hash'] != $xx['xchan_hash']) {
logger('mod_zot: auth: already authenticated locally as somebody else.'); 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); notice( t('Remote authentication blocked. You are logged into this site locally. Please logout and retry.') . EOL);
if ($test) { if ($test) {
$ret['message'] .= 'already logged in locally with a conflicting identity.' . EOL; $ret['message'] .= 'already logged in locally with a conflicting identity.' . EOL;
json_return_and_die($ret); continue;
} }
} }
goaway($desturl); continue;
} }
// log them in // log them in
@ -255,10 +256,10 @@ function post_init(&$a) {
dbesc($delegate) dbesc($delegate)
); );
if ($r && intval($r[0]['channel_id'])) { if ($r && intval($r[0]['channel_id'])) {
$allowed = perm_is_allowed($r[0]['channel_id'],$x[0]['xchan_hash'],'delegate'); $allowed = perm_is_allowed($r[0]['channel_id'],$xx['xchan_hash'],'delegate');
if ($allowed) { if ($allowed) {
$_SESSION['delegate_channel'] = $r[0]['channel_id']; $_SESSION['delegate_channel'] = $r[0]['channel_id'];
$_SESSION['delegate'] = $x[0]['xchan_hash']; $_SESSION['delegate'] = $xx['xchan_hash'];
$_SESSION['account_id'] = intval($r[0]['channel_account_id']); $_SESSION['account_id'] = intval($r[0]['channel_account_id']);
require_once('include/security.php'); require_once('include/security.php');
change_channel($r[0]['channel_id']); change_channel($r[0]['channel_id']);
@ -269,8 +270,8 @@ function post_init(&$a) {
$_SESSION['authenticated'] = 1; $_SESSION['authenticated'] = 1;
if (! $delegation_success) { if (! $delegation_success) {
$_SESSION['visitor_id'] = $x[0]['xchan_hash']; $_SESSION['visitor_id'] = $xx['xchan_hash'];
$_SESSION['my_url'] = $x[0]['xchan_url']; $_SESSION['my_url'] = $xx['xchan_url'];
$_SESSION['my_address'] = $address; $_SESSION['my_address'] = $address;
$_SESSION['remote_service_class'] = $remote_service_class; $_SESSION['remote_service_class'] = $remote_service_class;
$_SESSION['remote_level'] = $remote_level; $_SESSION['remote_level'] = $remote_level;
@ -278,29 +279,36 @@ function post_init(&$a) {
$_SESSION['DNT'] = $DNT; $_SESSION['DNT'] = $DNT;
} }
$arr = array('xchan' => $x[0], 'url' => $desturl, 'session' => $_SESSION); $arr = array('xchan' => $xx, 'url' => $desturl, 'session' => $_SESSION);
call_hooks('magic_auth_success',$arr); call_hooks('magic_auth_success',$arr);
$a->set_observer($x[0]); $a->set_observer($xx);
require_once('include/security.php'); require_once('include/security.php');
$a->set_groups(init_groups_visitor($_SESSION['visitor_id'])); $a->set_groups(init_groups_visitor($_SESSION['visitor_id']));
info(sprintf( t('Welcome %s. Remote authentication successful.'),$x[0]['xchan_name'])); info(sprintf( t('Welcome %s. Remote authentication successful.'),$xx['xchan_name']));
logger('mod_zot: auth success from ' . $x[0]['xchan_addr']); logger('mod_zot: auth success from ' . $xx['xchan_addr']);
q("update hubloc set hubloc_status = (hubloc_status | %d ) where hubloc_id = %d ", q("update hubloc set hubloc_status = (hubloc_status | %d ) where hubloc_id = %d ",
intval(HUBLOC_WORKS), intval(HUBLOC_WORKS),
intval($x[0]['hubloc_id']) intval($xx['hubloc_id'])
); );
} else { } else {
if ($test) { if ($test) {
$ret['message'] .= 'auth failure. ' . print_r($_REQUEST,true) . print_r($j,true) . EOL; $ret['message'] .= 'auth failure. ' . print_r($_REQUEST,true) . print_r($j,true) . EOL;
json_return_and_die($ret); continue;
} }
logger('mod_zot: magic-auth failure - not authenticated: ' . $x[0]['xchan_addr']); logger('mod_zot: magic-auth failure - not authenticated: ' . $xx['xchan_addr']);
q("update hubloc set hubloc_status = (hubloc_status | %d ) where hubloc_id = %d ", q("update hubloc set hubloc_status = (hubloc_status | %d ) where hubloc_id = %d ",
intval(HUBLOC_RECEIVE_ERROR), intval(HUBLOC_RECEIVE_ERROR),
intval($x[0]['hubloc_id']) intval($xx['hubloc_id'])
); );
} }
if ($test) {
$ret['message'] .= 'auth failure fallthrough ' . print_r($_REQUEST,true) . print_r($j,true) . EOL;
continue;
}
}
/** /**
* @FIXME we really want to save the return_url in the session before we * @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 * 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. * But z_root() probably isn't where you really want to go.
*/ */
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')) if(strstr($desturl,z_root() . '/rmagic'))
goaway(z_root()); goaway(z_root());
if ($test) {
json_return_and_die($ret);
}
goaway($desturl); goaway($desturl);
} }
} }

View File

@ -1 +1 @@
2015-09-20.1161 2015-09-21.1162