Example #1
0
 function get()
 {
     $noid = get_config('system', 'disable_openid');
     if ($noid) {
         goaway(z_root());
     }
     logger('mod_openid ' . print_r($_REQUEST, true), LOGGER_DATA);
     if (x($_REQUEST, 'openid_mode')) {
         $openid = new LightOpenID(z_root());
         if ($openid->validate()) {
             logger('openid: validate');
             $authid = normalise_openid($_REQUEST['openid_identity']);
             if (!strlen($authid)) {
                 logger(t('OpenID protocol error. No ID returned.') . EOL);
                 goaway(z_root());
             }
             $x = match_openid($authid);
             if ($x) {
                 $r = q("select * from channel where channel_id = %d limit 1", intval($x));
                 if ($r) {
                     $y = q("select * from account where account_id = %d limit 1", intval($r[0]['channel_account_id']));
                     if ($y) {
                         foreach ($y as $record) {
                             if ($record['account_flags'] == ACCOUNT_OK || $record['account_flags'] == ACCOUNT_UNVERIFIED) {
                                 logger('mod_openid: openid success for ' . $x[0]['channel_name']);
                                 $_SESSION['uid'] = $r[0]['channel_id'];
                                 $_SESSION['account_id'] = $r[0]['channel_account_id'];
                                 $_SESSION['authenticated'] = true;
                                 authenticate_success($record, $r[0], true, true, true, true);
                                 goaway(z_root());
                             }
                         }
                     }
                 }
             }
             // Successful OpenID login - but we can't match it to an existing account.
             // See if they've got an xchan
             $r = q("select * from xconfig left join xchan on xchan_hash = xconfig.xchan where cat = 'system' and k = 'openid' and v = '%s' limit 1", dbesc($authid));
             if ($r) {
                 $_SESSION['authenticated'] = 1;
                 $_SESSION['visitor_id'] = $r[0]['xchan_hash'];
                 $_SESSION['my_url'] = $r[0]['xchan_url'];
                 $_SESSION['my_address'] = $r[0]['xchan_addr'];
                 $arr = array('xchan' => $r[0], 'session' => $_SESSION);
                 call_hooks('magic_auth_openid_success', $arr);
                 \App::set_observer($r[0]);
                 require_once 'include/security.php';
                 \App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
                 info(sprintf(t('Welcome %s. Remote authentication successful.'), $r[0]['xchan_name']));
                 logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']);
                 if ($_SESSION['return_url']) {
                     goaway($_SESSION['return_url']);
                 }
                 goaway(z_root());
             }
             // no xchan...
             // create one.
             // We should probably probe the openid url and figure out if they have any kind of
             // social presence we might be able to scrape some identifying info from.
             $name = $authid;
             $url = trim($_REQUEST['openid_identity'], '/');
             if (strpos($url, 'http') === false) {
                 $url = 'https://' . $url;
             }
             $pphoto = z_root() . '/' . get_default_profile_photo();
             $parsed = @parse_url($url);
             if ($parsed) {
                 $host = $parsed['host'];
             }
             $attr = $openid->getAttributes();
             if (is_array($attr) && count($attr)) {
                 foreach ($attr as $k => $v) {
                     if ($k === 'namePerson/friendly') {
                         $nick = notags(trim($v));
                     }
                     if ($k === 'namePerson/first') {
                         $first = notags(trim($v));
                     }
                     if ($k === 'namePerson') {
                         $name = notags(trim($v));
                     }
                     if ($k === 'contact/email') {
                         $addr = notags(trim($v));
                     }
                     if ($k === 'media/image/aspect11') {
                         $photosq = trim($v);
                     }
                     if ($k === 'media/image/default') {
                         $photo_other = trim($v);
                     }
                 }
             }
             if (!$nick) {
                 if ($first) {
                     $nick = $first;
                 } else {
                     $nick = $name;
                 }
             }
             require_once 'library/urlify/URLify.php';
             $x = strtolower(\URLify::transliterate($nick));
             if ($nick & $host) {
                 $addr = $nick . '@' . $host;
             }
             $network = 'unknown';
             if ($photosq) {
                 $pphoto = $photosq;
             } elseif ($photo_other) {
                 $pphoto = $photo_other;
             }
             $mimetype = guess_image_type($pphoto);
             $x = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_mimetype,\n\t                xchan_photo_l, xchan_addr, xchan_url, xchan_connurl, xchan_follow, xchan_connpage, xchan_name, xchan_network, xchan_photo_date, \n\t\t\t\t\txchan_name_date, xchan_hidden)\n\t                values ( '%s', '%s', '%s', '%s' , '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', 1) ", dbesc($url), dbesc(''), dbesc(''), dbesc(''), dbesc($mimetype), dbesc($pphoto), dbesc($addr), dbesc($url), dbesc(''), dbesc(''), dbesc(''), dbesc($name), dbesc($network), dbesc(datetime_convert()), dbesc(datetime_convert()));
             if ($x) {
                 $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($url));
                 if ($r) {
                     $photos = import_xchan_photo($pphoto, $url);
                     if ($photos) {
                         $z = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', \n\t\t\t\t\t\t\t\txchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbesc(datetime_convert()), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($url));
                     }
                     set_xconfig($url, 'system', 'openid', $authid);
                     $_SESSION['authenticated'] = 1;
                     $_SESSION['visitor_id'] = $r[0]['xchan_hash'];
                     $_SESSION['my_url'] = $r[0]['xchan_url'];
                     $_SESSION['my_address'] = $r[0]['xchan_addr'];
                     $arr = array('xchan' => $r[0], 'session' => $_SESSION);
                     call_hooks('magic_auth_openid_success', $arr);
                     \App::set_observer($r[0]);
                     info(sprintf(t('Welcome %s. Remote authentication successful.'), $r[0]['xchan_name']));
                     logger('mod_openid: remote auth success from ' . $r[0]['xchan_addr']);
                     if ($_SESSION['return_url']) {
                         goaway($_SESSION['return_url']);
                     }
                     goaway(z_root());
                 }
             }
         }
     }
     notice(t('Login failed.') . EOL);
     goaway(z_root());
     // NOTREACHED
 }
Example #2
0
/**
 * @brief Change to another channel with current logged-in account.
 *
 * @param int $change_channel The channel_id of the channel you want to change to
 *
 * @return bool|array false or channel record of the new channel
 */
function change_channel($change_channel)
{
    $ret = false;
    if ($change_channel) {
        $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and channel_account_id = %d and channel_removed = 0 limit 1", intval($change_channel), intval(get_account_id()));
        // It's not there.  Is this an administrator, and is this the sys channel?
        if (is_developer()) {
            if (!$r) {
                if (is_site_admin()) {
                    $r = q("select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and channel_system = 1 and channel_removed = 0 limit 1", intval($change_channel));
                }
            }
        }
        if ($r) {
            $hash = $r[0]['channel_hash'];
            $_SESSION['uid'] = intval($r[0]['channel_id']);
            App::set_channel($r[0]);
            $_SESSION['theme'] = $r[0]['channel_theme'];
            $_SESSION['mobile_theme'] = get_pconfig(local_channel(), 'system', 'mobile_theme');
            date_default_timezone_set($r[0]['channel_timezone']);
            $ret = $r[0];
        }
        $x = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($hash));
        if ($x) {
            $_SESSION['my_url'] = $x[0]['xchan_url'];
            $_SESSION['my_address'] = $r[0]['channel_address'] . '@' . App::get_hostname();
            App::set_observer($x[0]);
            App::set_perms(get_all_perms(local_channel(), $hash));
        }
        if (!is_dir('store/' . $r[0]['channel_address'])) {
            @os_mkdir('store/' . $r[0]['channel_address'], STORAGE_DEFAULT_PERMISSIONS, true);
        }
        $arr = ['channel_id' => $change_channel, 'chanx' => $ret];
        call_hooks('change_channel', $arr);
    }
    return $ret;
}
Example #3
0
 function Verify($channel, $hubloc)
 {
     logger('auth request received from ' . $hubloc['hubloc_addr']);
     $this->remote = remote_channel();
     $this->remote_service_class = '';
     $this->remote_level = 0;
     $this->remote_hub = $hubloc['hubloc_url'];
     $this->dnt = 0;
     // check credentials and access
     // 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.
     $already_authed = remote_channel() && $hubloc['hubloc_hash'] == remote_channel() && $hubloc['hubloc_url'] === $_SESSION['remote_hub'] ? true : false;
     if ($this->delegate && $this->delegate !== $_SESSION['delegate_channel']) {
         $already_authed = false;
     }
     if ($already_authed) {
         return true;
     }
     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 (\App::$channel['channel_hash'] == $hubloc['xchan_hash']) {
             return true;
         } else {
             logger('already authenticated locally as somebody else.');
             notice(t('Remote authentication blocked. You are logged into this site locally. Please logout and retry.') . EOL);
             if ($this->test) {
                 $this->Debug('already logged in locally with a conflicting identity.');
                 return false;
             }
         }
         return false;
     }
     // 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($channel, $type = 'auth_check', array(array('guid' => $hubloc['hubloc_guid'], 'guid_sig' => $hubloc['hubloc_guid_sig'])), $hubloc['hubloc_sitekey'], $this->sec);
     $this->Debug('auth check packet created using sitekey ' . $hubloc['hubloc_sitekey']);
     $this->Debug('packet contents: ' . $p);
     $result = zot_zot($hubloc['hubloc_callback'], $p);
     if (!$result['success']) {
         logger('auth_check callback failed.');
         if ($this->test) {
             $this->Debug('auth check request to your site returned .' . print_r($result, true));
         }
         return false;
     }
     $j = json_decode($result['body'], true);
     if (!$j) {
         logger('auth_check json data malformed.');
         if ($this->test) {
             $this->Debug('json malformed: ' . $result['body']);
         }
         return false;
     }
     $this->Debug('auth check request returned .' . print_r($j, true));
     if (!$j['success']) {
         return false;
     }
     // legit response, but we do need to check that this wasn't answered by a man-in-middle
     if (!rsa_verify($this->sec . $hubloc['xchan_hash'], base64url_decode($j['confirm']), $hubloc['xchan_pubkey'])) {
         logger('final confirmation failed.');
         if ($this->test) {
             $this->Debug('final confirmation failed. ' . $sec . print_r($j, true) . print_r($hubloc, true));
         }
         return false;
     }
     if (array_key_exists('service_class', $j)) {
         $this->remote_service_class = $j['service_class'];
     }
     if (array_key_exists('level', $j)) {
         $this->remote_level = $j['level'];
     }
     if (array_key_exists('DNT', $j)) {
         $this->dnt = $j['DNT'];
     }
     // log them in
     if ($this->test) {
         // testing only - return the success result
         $this->test_results['success'] = true;
         $this->Debug('Authentication Success!');
         $this->Finalise();
     }
     $_SESSION['authenticated'] = 1;
     // check for delegation and if all is well, log them in locally with delegation restrictions
     $this->delegate_success = false;
     if ($this->delegate) {
         $r = q("select * from channel left join xchan on channel_hash = xchan_hash where xchan_addr = '%s' limit 1", dbesc($this->delegate));
         if ($r && intval($r[0]['channel_id'])) {
             $allowed = perm_is_allowed($r[0]['channel_id'], $hubloc['xchan_hash'], 'delegate');
             if ($allowed) {
                 $_SESSION['delegate_channel'] = $r[0]['channel_id'];
                 $_SESSION['delegate'] = $hubloc['xchan_hash'];
                 $_SESSION['account_id'] = intval($r[0]['channel_account_id']);
                 require_once 'include/security.php';
                 // this will set the local_channel authentication in the session
                 change_channel($r[0]['channel_id']);
                 $this->delegate_success = true;
             }
         }
     }
     if (!$this->delegate_success) {
         // normal visitor (remote_channel) login session credentials
         $_SESSION['visitor_id'] = $hubloc['xchan_hash'];
         $_SESSION['my_url'] = $hubloc['xchan_url'];
         $_SESSION['my_address'] = $this->address;
         $_SESSION['remote_service_class'] = $this->remote_service_class;
         $_SESSION['remote_level'] = $this->remote_level;
         $_SESSION['remote_hub'] = $this->remote_hub;
         $_SESSION['DNT'] = $this->dnt;
     }
     $arr = array('xchan' => $hubloc, 'url' => $this->desturl, 'session' => $_SESSION);
     call_hooks('magic_auth_success', $arr);
     \App::set_observer($hubloc);
     require_once 'include/security.php';
     \App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
     info(sprintf(t('Welcome %s. Remote authentication successful.'), $hubloc['xchan_name']));
     logger('mod_zot: auth success from ' . $hubloc['xchan_addr']);
     $this->success = true;
     return true;
 }
Example #4
0
             $_SESSION['last_login_date'] = datetime_convert();
             unset($_SESSION['visitor_id']);
             // no longer a visitor
             authenticate_success($x[0], null, true, true);
         }
     }
     if (array_key_exists('atoken', $_SESSION)) {
         $y = q("select * from atoken where atoken_id = %d limit 1", intval($_SESSION['atoken']));
         if ($y) {
             $r = array(atoken_xchan($y[0]));
         }
     } else {
         $r = q("select * from xchan left join hubloc on xchan_hash = hubloc_hash where xchan_hash = '%s' limit 1", dbesc($_SESSION['visitor_id']));
     }
     if ($r) {
         App::set_observer($r[0]);
     } else {
         unset($_SESSION['visitor_id']);
         unset($_SESSION['authenticated']);
     }
     App::set_groups(init_groups_visitor($_SESSION['visitor_id']));
 }
 // already logged in user returning
 if (x($_SESSION, 'uid') || x($_SESSION, 'account_id')) {
     App::$session->return_check();
     $r = q("select * from account where account_id = %d limit 1", intval($_SESSION['account_id']));
     if ($r && ($r[0]['account_flags'] == ACCOUNT_OK || $r[0]['account_flags'] == ACCOUNT_UNVERIFIED)) {
         App::$account = $r[0];
         $login_refresh = false;
         if (!x($_SESSION, 'last_login_date')) {
             $_SESSION['last_login_date'] = datetime_convert('UTC', 'UTC');