コード例 #1
0
ファイル: channel.php プロジェクト: phellmes/hubzilla
/**
 * @brief
 *
 * If somebody arrives at our site using a zat, authenticate them
 *
 */
function zat_init()
{
    if (local_channel() || remote_channel()) {
        return;
    }
    $r = q("select * from atoken where atoken_token = '%s' limit 1", dbesc($_REQUEST['zat']));
    if ($r) {
        $xchan = atoken_xchan($r[0]);
        atoken_login($xchan);
    }
}
コード例 #2
0
ファイル: Acl.php プロジェクト: einervonvielen/hubzilla
 function init()
 {
     //	logger('mod_acl: ' . print_r($_REQUEST,true));
     $start = x($_REQUEST, 'start') ? $_REQUEST['start'] : 0;
     $count = x($_REQUEST, 'count') ? $_REQUEST['count'] : 500;
     $search = x($_REQUEST, 'search') ? $_REQUEST['search'] : '';
     $type = x($_REQUEST, 'type') ? $_REQUEST['type'] : '';
     $noforums = x($_REQUEST, 'n') ? $_REQUEST['n'] : false;
     // $type =
     //  ''   =>  standard ACL request
     //  'g'  =>  Groups only ACL request
     //  'c'  =>  Connections only ACL request or editor (textarea) mention request
     // $_REQUEST['search'] contains ACL search text.
     // $type =
     //  'm'  =>  autocomplete private mail recipient (checks post_mail permission)
     //  'a'  =>  autocomplete connections (mod_connections, mod_poke, mod_sources, mod_photos)
     //  'x'  =>  nav search bar autocomplete (match any xchan)
     // $_REQUEST['query'] contains autocomplete search text.
     // List of channels whose connections to also suggest,
     // e.g. currently viewed channel or channels mentioned in a post
     $extra_channels = x($_REQUEST, 'extra_channels') ? $_REQUEST['extra_channels'] : array();
     // The different autocomplete libraries use different names for the search text
     // parameter. Internaly we'll use $search to represent the search text no matter
     // what request variable it was attached to.
     if (array_key_exists('query', $_REQUEST)) {
         $search = $_REQUEST['query'];
     }
     if (!local_channel() && !($type == 'x' || $type == 'c')) {
         killme();
     }
     if ($search) {
         $sql_extra = " AND `name` LIKE " . protect_sprintf("'%" . dbesc($search) . "%'") . " ";
         $sql_extra2 = "AND ( xchan_name LIKE " . protect_sprintf("'%" . dbesc($search) . "%'") . " OR xchan_addr LIKE " . protect_sprintf("'%" . dbesc($search) . (strpos($search, '@') === false ? "%@%'" : "%'")) . ") ";
         // This horrible mess is needed because position also returns 0 if nothing is found.
         // Would be MUCH easier if it instead returned a very large value
         // Otherwise we could just
         // order by LEAST(POSITION($search IN xchan_name),POSITION($search IN xchan_addr)).
         $order_extra2 = "CASE WHEN xchan_name LIKE " . protect_sprintf("'%" . dbesc($search) . "%'") . " then POSITION('" . dbesc($search) . "' IN xchan_name) else position('" . dbesc($search) . "' IN xchan_addr) end, ";
         $col = strpos($search, '@') !== false ? 'xchan_addr' : 'xchan_name';
         $sql_extra3 = "AND {$col} like " . protect_sprintf("'%" . dbesc($search) . "%'") . " ";
     } else {
         $sql_extra = $sql_extra2 = $sql_extra3 = "";
     }
     $groups = array();
     $contacts = array();
     if ($type == '' || $type == 'g') {
         $r = q("SELECT `groups`.`id`, `groups`.`hash`, `groups`.`gname`\n\t\t\t\t\tFROM `groups`,`group_member` \n\t\t\t\t\tWHERE `groups`.`deleted` = 0 AND `groups`.`uid` = %d \n\t\t\t\t\tAND `group_member`.`gid`=`groups`.`id`\n\t\t\t\t\t{$sql_extra}\n\t\t\t\t\tGROUP BY `groups`.`id`\n\t\t\t\t\tORDER BY `groups`.`gname` \n\t\t\t\t\tLIMIT %d OFFSET %d", intval(local_channel()), intval($count), intval($start));
         if ($r) {
             foreach ($r as $g) {
                 //		logger('acl: group: ' . $g['gname'] . ' members: ' . group_get_members_xchan($g['id']));
                 $groups[] = array("type" => "g", "photo" => "images/twopeople.png", "name" => $g['gname'], "id" => $g['id'], "xid" => $g['hash'], "uids" => group_get_members_xchan($g['id']), "link" => '');
             }
         }
     }
     if ($type == '' || $type == 'c') {
         $extra_channels_sql = '';
         // Only include channels who allow the observer to view their permissions
         foreach ($extra_channels as $channel) {
             if (perm_is_allowed(intval($channel), get_observer_hash(), 'view_contacts')) {
                 $extra_channels_sql .= "," . intval($channel);
             }
         }
         $extra_channels_sql = substr($extra_channels_sql, 1);
         // Remove initial comma
         // Getting info from the abook is better for local users because it contains info about permissions
         if (local_channel()) {
             if ($extra_channels_sql != '') {
                 $extra_channels_sql = " OR (abook_channel IN ({$extra_channels_sql})) and abook_hidden = 0 ";
             }
             $r2 = null;
             $r1 = q("select * from atoken where atoken_uid = %d", intval(local_channel()));
             if ($r1) {
                 require_once 'include/security.php';
                 $r2 = array();
                 foreach ($r1 as $rr) {
                     $x = atoken_xchan($rr);
                     $r2[] = ['id' => 'a' . $rr['atoken_id'], 'hash' => $x['xchan_hash'], 'name' => $x['xchan_name'], 'micro' => $x['xchan_photo_m'], 'url' => z_root(), 'nick' => $x['xchan_addr'], 'abook_their_perms' => 0, 'abook_flags' => 0, 'abook_self' => 0];
                 }
             }
             $r = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self \n\t\t\t\t\tFROM abook left join xchan on abook_xchan = xchan_hash \n\t\t\t\t\tWHERE (abook_channel = %d {$extra_channels_sql}) AND abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 {$sql_extra2} order by {$order_extra2} xchan_name asc", intval(local_channel()));
             if ($r2) {
                 $r = array_merge($r2, $r);
             }
         } else {
             // Visitors
             $r = q("SELECT xchan_hash as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self\n\t\t\t\t\tFROM xchan left join xlink on xlink_link = xchan_hash\n\t\t\t\t\tWHERE xlink_xchan  = '%s' AND xchan_deleted = 0 {$sql_extra2} order by {$order_extra2} xchan_name asc", dbesc(get_observer_hash()));
             // Find contacts of extra channels
             // This is probably more complicated than it needs to be
             if ($extra_channels_sql) {
                 // Build a list of hashes that we got previously so we don't get them again
                 $known_hashes = array("'" . get_observer_hash() . "'");
                 if ($r) {
                     foreach ($r as $rr) {
                         $known_hashes[] = "'" . $rr['hash'] . "'";
                     }
                 }
                 $known_hashes_sql = 'AND xchan_hash not in (' . join(',', $known_hashes) . ')';
                 $r2 = q("SELECT abook_id as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, abook_their_perms, abook_flags, abook_self \n\t\t\t\t\t\tFROM abook left join xchan on abook_xchan = xchan_hash \n\t\t\t\t\t\tWHERE abook_channel IN ({$extra_channels_sql}) {$known_hashes_sql} AND abook_blocked = 0 and abook_pending = 0 and abook_hidden = 0 and xchan_deleted = 0 {$sql_extra2} order by {$order_extra2} xchan_name asc");
                 if ($r2) {
                     $r = array_merge($r, $r2);
                 }
                 // Sort accoring to match position, then alphabetically. This could be avoided if the above two SQL queries could be combined into one, and the sorting could be done on the SQl server (like in the case of a local user)
                 $matchpos = function ($x) use($search) {
                     $namepos = strpos($x['name'], $search);
                     $nickpos = strpos($x['nick'], $search);
                     // Use a large position if not found
                     return min($namepos === false ? 9999 : $namepos, $nickpos === false ? 9999 : $nickpos);
                 };
                 // This could be made simpler if PHP supported stable sorting
                 usort($r, function ($a, $b) use($matchpos) {
                     $pos1 = $matchpos($a);
                     $pos2 = $matchpos($b);
                     if ($pos1 == $pos2) {
                         // Order alphabetically if match position is the same
                         if ($a['name'] == $b['name']) {
                             return 0;
                         } else {
                             return $a['name'] < $b['name'] ? -1 : 1;
                         }
                     }
                     return $pos1 < $pos2 ? -1 : 1;
                 });
             }
         }
         if (intval(get_config('system', 'taganyone')) || intval(get_pconfig(local_channel(), 'system', 'taganyone'))) {
             if (count($r) < 100 && $type == 'c') {
                 $r2 = q("SELECT substr(xchan_hash,1,18) as id, xchan_hash as hash, xchan_name as name, xchan_photo_s as micro, xchan_url as url, xchan_addr as nick, 0 as abook_their_perms, 0 as abook_flags, 0 as abook_self \n\t\t\t\t\t\tFROM xchan \n\t\t\t\t\t\tWHERE xchan_deleted = 0 {$sql_extra2} order by {$order_extra2} xchan_name asc");
                 if ($r2) {
                     $r = array_merge($r, $r2);
                 }
             }
         }
     } elseif ($type == 'm') {
         $r = q("SELECT xchan_hash as hash, xchan_name as name, xchan_addr as nick, xchan_photo_s as micro, xchan_url as url \n\t\t\t\tFROM abook left join xchan on abook_xchan = xchan_hash\n\t\t\t\tWHERE abook_channel = %d and ( (abook_their_perms = null) or (abook_their_perms & %d )>0)\n\t\t\t\tand xchan_deleted = 0\n\t\t\t\t{$sql_extra3}\n\t\t\t\tORDER BY `xchan_name` ASC ", intval(local_channel()), intval(PERMS_W_MAIL));
     } elseif ($type == 'a') {
         $r = q("SELECT abook_id as id, xchan_name as name, xchan_hash as hash, xchan_addr as nick, xchan_photo_s as micro, xchan_network as network, xchan_url as url, xchan_addr as attag , abook_their_perms FROM abook left join xchan on abook_xchan = xchan_hash\n\t\t\t\tWHERE abook_channel = %d\n\t\t\t\tand xchan_deleted = 0\n\t\t\t\t{$sql_extra3}\n\t\t\t\tORDER BY xchan_name ASC ", intval(local_channel()));
     } elseif ($type == 'x') {
         $r = $this->navbar_complete($a);
         $contacts = array();
         if ($r) {
             foreach ($r as $g) {
                 $contacts[] = array("photo" => $g['photo'], "name" => $g['name'], "nick" => $g['address']);
             }
         }
         $o = array('start' => $start, 'count' => $count, 'items' => $contacts);
         echo json_encode($o);
         killme();
     } else {
         $r = array();
     }
     if ($r) {
         foreach ($r as $g) {
             // remove RSS feeds from ACLs - they are inaccessible
             if (strpos($g['hash'], '/') && $type != 'a') {
                 continue;
             }
             if ($g['abook_their_perms'] & PERMS_W_TAGWALL && $type == 'c' && !$noforums) {
                 $contacts[] = array("type" => "c", "photo" => "images/twopeople.png", "name" => $g['name'] . '+', "id" => $g['id'] . '+', "xid" => $g['hash'], "link" => $g['nick'], "nick" => substr($g['nick'], 0, strpos($g['nick'], '@')), "self" => intval($g['abook_self']) ? 'abook-self' : '', "taggable" => 'taggable', "label" => t('network'));
             }
             $contacts[] = array("type" => "c", "photo" => $g['micro'], "name" => $g['name'], "id" => $g['id'], "xid" => $g['hash'], "link" => $g['nick'], "nick" => $g['nick'] ? substr($g['nick'], 0, strpos($g['nick'], '@')) : t('RSS'), "self" => intval($g['abook_self']) ? 'abook-self' : '', "taggable" => '', "label" => '');
         }
     }
     $items = array_merge($groups, $contacts);
     $o = array('start' => $start, 'count' => $count, 'items' => $items);
     echo json_encode($o);
     killme();
 }
コード例 #3
0
ファイル: Lockview.php プロジェクト: BlaBlaNet/hubzilla
 function get()
 {
     $atokens = array();
     if (local_channel()) {
         $at = q("select * from atoken where atoken_uid = %d", intval(local_channel()));
         if ($at) {
             foreach ($at as $t) {
                 $atokens[] = atoken_xchan($t);
             }
         }
     }
     $type = argc() > 1 ? argv(1) : 0;
     if (is_numeric($type)) {
         $item_id = intval($type);
         $type = 'item';
     } else {
         $item_id = argc() > 2 ? intval(argv(2)) : 0;
     }
     if (!$item_id) {
         killme();
     }
     if (!in_array($type, array('item', 'photo', 'event', 'menu_item', 'chatroom'))) {
         killme();
     }
     //we have different naming in in menu_item table and chatroom table
     switch ($type) {
         case 'menu_item':
             $id = 'mitem_id';
             break;
         case 'chatroom':
             $id = 'cr_id';
             break;
         default:
             $id = 'id';
             break;
     }
     $r = q("SELECT * FROM %s WHERE {$id} = %d LIMIT 1", dbesc($type), intval($item_id));
     if (!$r) {
         killme();
     }
     $item = $r[0];
     //we have different naming in in menu_item table and chatroom table
     switch ($type) {
         case 'menu_item':
             $uid = $item['mitem_channel_id'];
             break;
         case 'chatroom':
             $uid = $item['cr_uid'];
             break;
         default:
             $uid = $item['uid'];
             break;
     }
     if ($uid != local_channel()) {
         echo '<li>' . t('Remote privacy information not available.') . '</li>';
         killme();
     }
     if ($item['item_private'] == 1 && !strlen($item['allow_cid']) && !strlen($item['allow_gid']) && !strlen($item['deny_cid']) && !strlen($item['deny_gid'])) {
         // if the post is private, but public_policy is blank ("visible to the internet"), and there aren't any
         // specific recipients, we're the recipient of a post with "bcc" or targeted recipients; so we'll just show it
         // as unknown specific recipients. The sender will have the visibility list and will fall through to the
         // next section.
         echo '<li>' . translate_scope(!$item['public_policy'] ? 'specific' : $item['public_policy']) . '</li>';
         killme();
     }
     $allowed_users = expand_acl($item['allow_cid']);
     $allowed_groups = expand_acl($item['allow_gid']);
     $deny_users = expand_acl($item['deny_cid']);
     $deny_groups = expand_acl($item['deny_gid']);
     $o = '<li>' . t('Visible to:') . '</li>';
     $l = array();
     stringify_array_elms($allowed_groups, true);
     stringify_array_elms($allowed_users, true);
     stringify_array_elms($deny_groups, true);
     stringify_array_elms($deny_users, true);
     if (count($allowed_groups)) {
         $r = q("SELECT gname FROM `groups` WHERE hash IN ( " . implode(', ', $allowed_groups) . " )");
         if ($r) {
             foreach ($r as $rr) {
                 $l[] = '<li><b>' . $rr['gname'] . '</b></li>';
             }
         }
     }
     if (count($allowed_users)) {
         $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $allowed_users) . " )");
         if ($r) {
             foreach ($r as $rr) {
                 $l[] = '<li>' . $rr['xchan_name'] . '</li>';
             }
         }
         if ($atokens) {
             foreach ($atokens as $at) {
                 if (in_array("'" . $at['xchan_hash'] . "'", $allowed_users)) {
                     $l[] = '<li>' . $at['xchan_name'] . '</li>';
                 }
             }
         }
     }
     if (count($deny_groups)) {
         $r = q("SELECT gname FROM `groups` WHERE hash IN ( " . implode(', ', $deny_groups) . " )");
         if ($r) {
             foreach ($r as $rr) {
                 $l[] = '<li><b><strike>' . $rr['gname'] . '</strike></b></li>';
             }
         }
     }
     if (count($deny_users)) {
         $r = q("SELECT xchan_name FROM xchan WHERE xchan_hash IN ( " . implode(', ', $deny_users) . " )");
         if ($r) {
             foreach ($r as $rr) {
                 $l[] = '<li><strike>' . $rr['xchan_name'] . '</strike></li>';
             }
         }
         if ($atokens) {
             foreach ($atokens as $at) {
                 if (in_array("'" . $at['xchan_hash'] . "'", $deny_users)) {
                     $l[] = '<li><strike>' . $at['xchan_name'] . '</strike></li>';
                 }
             }
         }
     }
     echo $o . implode($l);
     killme();
 }
コード例 #4
0
ファイル: security.php プロジェクト: BlaBlaNet/hubzilla
function atoken_abook($uid, $xchan_hash)
{
    if (substr($xchan_hash, 16, 1) != '.') {
        return false;
    }
    $r = q("select channel_hash from channel where channel_id = %d limit 1", intval($uid));
    if (!$r) {
        return false;
    }
    $x = q("select * from atoken where atoken_uid = %d and atoken_name = '%s'", intval($uid), dbesc(substr($xchan_hash, 17)));
    if ($x) {
        $xchan = atoken_xchan($x[0]);
        $xchan['abook_blocked'] = 0;
        $xchan['abook_ignored'] = 0;
        $xchan['abook_pending'] = 0;
        return $xchan;
    }
    return false;
}
コード例 #5
0
ファイル: auth.php プロジェクト: BlaBlaNet/hubzilla
/**
 * @brief Verify login credentials.
 *
 * If system.authlog is set a log entry will be added for failed login
 * attempts.
 *
 * @param string $login
 *  The login to verify (channel address, account email or guest login token).
 * @param string $pass
 *  The provided password to verify.
 * @return array|null
 *  Returns account record on success, null on failure.
 *  The return array is dependent on the login mechanism.
 *    $ret['account'] will be set if either an email or channel address validation was successful (local login).
 *    $ret['channel'] will be set if a channel address validation was successful.
 *    $ret['xchan'] will be set if a guest access token validation was successful. 
 *   Keys will exist for invalid return arrays but will be set to null. 
 *   This function does not perform a login. It merely validates systems passwords and tokens.  
 *
 */
function account_verify_password($login, $pass)
{
    $ret = ['account' => null, 'channel' => null, 'xchan' => null];
    $email_verify = get_config('system', 'verify_email');
    $register_policy = get_config('system', 'register_policy');
    if (!$login) {
        return null;
    }
    $account = null;
    $channel = null;
    $xchan = null;
    if (!strpos($login, '@')) {
        $channel = channelx_by_nick($login);
        if (!$channel) {
            $x = q("select * from atoken where atoken_name = '%s' and atoken_token = '%s' limit 1", dbesc($login), dbesc($pass));
            if ($x) {
                $ret['xchan'] = atoken_xchan($x[0]);
                atoken_create_xchan($ret['xchan']);
                return $ret;
            }
        }
    }
    if ($channel) {
        $where = " where account_id = " . intval($channel['channel_account_id']) . " ";
    } else {
        $where = " where account_email = '" . dbesc($login) . "' ";
    }
    $a = q("select * from account {$where}");
    if (!$a) {
        return null;
    }
    $account = $a[0];
    // Currently we only verify email address if there is an open registration policy.
    // This isn't because of any policy - it's because the workflow gets too complicated if
    // you have to verify the email and then go through the account approval workflow before
    // letting them login.
    if ($email_verify && $register_policy == REGISTER_OPEN && $account['account_flags'] & ACCOUNT_UNVERIFIED) {
        logger('email verification required for ' . $login);
        return null;
    }
    if ($account['account_flags'] == ACCOUNT_OK && hash('whirlpool', $account['account_salt'] . $pass) === $account['account_password']) {
        logger('password verified for ' . $login);
        $ret['account'] = $account;
        if ($channel) {
            $ret['channel'] = $channel;
        }
        return $ret;
    }
    $error = 'password failed for ' . $login;
    logger($error);
    if ($account['account_flags'] & ACCOUNT_UNVERIFIED) {
        logger('Account is unverified. account_flags = ' . $account['account_flags']);
    }
    if ($account['account_flags'] & ACCOUNT_BLOCKED) {
        logger('Account is blocked. account_flags = ' . $account['account_flags']);
    }
    if ($account['account_flags'] & ACCOUNT_EXPIRED) {
        logger('Account is expired. account_flags = ' . $account['account_flags']);
    }
    if ($account['account_flags'] & ACCOUNT_REMOVED) {
        logger('Account is removed. account_flags = ' . $account['account_flags']);
    }
    if ($account['account_flags'] & ACCOUNT_PENDING) {
        logger('Account is pending. account_flags = ' . $account['account_flags']);
    }
    log_failed_login($error);
    return null;
}