Esempio n. 1
0
function handle_pubsubhubbub()
{
    global $a, $db;
    logger('start');
    // We'll push to each subscriber that has push > 0,
    // i.e. there has been an update (set in notifier.php).
    $r = q("SELECT * FROM `push_subscriber` WHERE `push` > 0");
    foreach ($r as $rr) {
        $params = get_feed_for($a, '', $rr['nickname'], $rr['last_update'], 0, true);
        $hmac_sig = hash_hmac("sha1", $params, $rr['secret']);
        $headers = array("Content-type: application/atom+xml", sprintf("Link: <%s>;rel=hub," . "<%s>;rel=self", $a->get_baseurl() . '/pubsubhubbub', $rr['topic']), "X-Hub-Signature: sha1=" . $hmac_sig);
        logger('POST ' . print_r($headers, true) . "\n" . $params, LOGGER_DEBUG);
        post_url($rr['callback_url'], $params, $headers);
        $ret = $a->get_curl_code();
        if ($ret >= 200 && $ret <= 299) {
            logger('successfully pushed to ' . $rr['callback_url']);
            // set last_update to "now", and reset push=0
            $date_now = datetime_convert('UTC', 'UTC', 'now', 'Y-m-d H:i:s');
            q("UPDATE `push_subscriber` SET `push` = 0, last_update = '%s' WHERE id = %d", dbesc($date_now), intval($rr['id']));
        } else {
            logger('error when pushing to ' . $rr['callback_url'] . ' HTTP: ' . $ret);
            // we use the push variable also as a counter, if we failed we
            // increment this until some upper limit where we give up
            $new_push = intval($rr['push']) + 1;
            if ($new_push > 30) {
                // OK, let's give up
                $new_push = 0;
            }
            q("UPDATE `push_subscriber` SET `push` = %d WHERE id = %d", $new_push, intval($rr['id']));
        }
    }
    logger('done');
}
Esempio n. 2
0
function push_notifier_process(&$a, &$b)
{
    logger('push_notifier_process');
    if (!$b['normal_mode']) {
        return;
    }
    if ($b['private'] || $b['packet_type'] !== 'undefined' || $b['mail']) {
        return;
    }
    if (!$b['top_level_post']) {
        return;
    }
    // find push_subscribers following this $owner
    $channel = $b['channel'];
    // allow subscriptions either by http or https, as gnu-social has been known to subscribe
    // to the wrong one.
    $r = q("select * from push_subscriber where topic like '%s'", dbesc('%://' . App::get_hostname() . '/feed/' . $channel['channel_address']));
    if (!$r) {
        return;
    }
    foreach ($r as $rr) {
        $feed = get_feed_for($channel, '', array('begin' => $rr['last_update']));
        $hmac_sig = hash_hmac("sha1", $feed, $rr['secret']);
        $slap = array('sig' => $hmac_sig, 'topic' => $rr['topic'], 'body' => $feed);
        // Check for public post and create atom wrapper and stick in queue
        // also need queue driver for 'push' since we need to set some extra headers
        $hash = random_string();
        queue_insert(array('hash' => $hash, 'account_id' => $channel['channel_account_id'], 'channel_id' => $channel['channel_id'], 'driver' => 'push', 'posturl' => $rr['callback_url'], 'notify' => '', 'msg' => json_encode($slap)));
        $b['queued'][] = $hash;
    }
}
Esempio n. 3
0
/**
 * @brief Generate an Atom feed.
 *
 * @param array $channel
 * @param array $params
 */
function get_public_feed($channel, $params)
{
    $type = 'xml';
    $begin = NULL_DATE;
    $end = '';
    $start = 0;
    $records = 40;
    $direction = 'desc';
    $pages = 0;
    if (!$params) {
        $params = array();
    }
    $params['type'] = x($params, 'type') ? $params['type'] : 'xml';
    $params['begin'] = x($params, 'begin') ? $params['begin'] : NULL_DATE;
    $params['end'] = x($params, 'end') ? $params['end'] : datetime_convert('UTC', 'UTC', 'now');
    $params['start'] = x($params, 'start') ? $params['start'] : 0;
    $params['records'] = x($params, 'records') ? $params['records'] : 40;
    $params['direction'] = x($params, 'direction') ? $params['direction'] : 'desc';
    $params['pages'] = x($params, 'pages') ? intval($params['pages']) : 0;
    $params['top'] = x($params, 'top') ? intval($params['top']) : 0;
    $params['cat'] = x($params, 'cat') ? $params['cat'] : '';
    // put a sane lower limit on feed requests if not specified
    //	if($params['begin'] === NULL_DATE)
    //		$params['begin'] = datetime_convert('UTC','UTC','now - 1 month');
    switch ($params['type']) {
        case 'json':
            header("Content-type: application/atom+json");
            break;
        case 'xml':
        default:
            header("Content-type: application/atom+xml");
            break;
    }
    return get_feed_for($channel, get_observer_hash(), $params);
}
Esempio n. 4
0
function dfrn_poll_post(&$a)
{
    $dfrn_id = x($_POST, 'dfrn_id') ? $_POST['dfrn_id'] : '';
    $challenge = x($_POST, 'challenge') ? $_POST['challenge'] : '';
    $url = x($_POST, 'url') ? $_POST['url'] : '';
    $sec = x($_POST, 'sec') ? $_POST['sec'] : '';
    $ptype = x($_POST, 'type') ? $_POST['type'] : '';
    $dfrn_version = x($_POST, 'dfrn_version') ? (double) $_POST['dfrn_version'] : 2.0;
    $perm = x($_POST, 'perm') ? $_POST['perm'] : 'r';
    if ($ptype === 'profile-check') {
        if (strlen($challenge) && strlen($sec)) {
            logger('dfrn_poll: POST: profile-check');
            q("DELETE FROM `profile_check` WHERE `expire` < " . intval(time()));
            $r = q("SELECT * FROM `profile_check` WHERE `sec` = '%s' ORDER BY `expire` DESC LIMIT 1", dbesc($sec));
            if (!count($r)) {
                xml_status(3, 'No ticket');
                // NOTREACHED
            }
            $orig_id = $r[0]['dfrn_id'];
            if (strpos($orig_id, ':')) {
                $orig_id = substr($orig_id, 2);
            }
            $c = q("SELECT * FROM `contact` WHERE `id` = %d LIMIT 1", intval($r[0]['cid']));
            if (!count($c)) {
                xml_status(3, 'No profile');
            }
            $contact = $c[0];
            $sent_dfrn_id = hex2bin($dfrn_id);
            $challenge = hex2bin($challenge);
            $final_dfrn_id = '';
            if ($contact['duplex'] && strlen($contact['prvkey'])) {
                openssl_private_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['prvkey']);
                openssl_private_decrypt($challenge, $decoded_challenge, $contact['prvkey']);
            } else {
                openssl_public_decrypt($sent_dfrn_id, $final_dfrn_id, $contact['pubkey']);
                openssl_public_decrypt($challenge, $decoded_challenge, $contact['pubkey']);
            }
            $final_dfrn_id = substr($final_dfrn_id, 0, strpos($final_dfrn_id, '.'));
            if (strpos($final_dfrn_id, ':') == 1) {
                $final_dfrn_id = substr($final_dfrn_id, 2);
            }
            if ($final_dfrn_id != $orig_id) {
                logger('profile_check: ' . $final_dfrn_id . ' != ' . $orig_id, LOGGER_DEBUG);
                // did not decode properly - cannot trust this site
                xml_status(3, 'Bad decryption');
            }
            header("Content-type: text/xml");
            echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?><dfrn_poll><status>0</status><challenge>{$decoded_challenge}</challenge><sec>{$sec}</sec></dfrn_poll>";
            killme();
            // NOTREACHED
        }
    }
    $direction = -1;
    if (strpos($dfrn_id, ':') == 1) {
        $direction = intval(substr($dfrn_id, 0, 1));
        $dfrn_id = substr($dfrn_id, 2);
    }
    $r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1", dbesc($dfrn_id), dbesc($challenge));
    if (!count($r)) {
        killme();
    }
    $type = $r[0]['type'];
    $last_update = $r[0]['last_update'];
    $r = q("DELETE FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1", dbesc($dfrn_id), dbesc($challenge));
    $sql_extra = '';
    switch ($direction) {
        case -1:
            $sql_extra = sprintf(" AND `issued-id` = '%s' ", dbesc($dfrn_id));
            $my_id = $dfrn_id;
            break;
        case 0:
            $sql_extra = sprintf(" AND `issued-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
            $my_id = '1:' . $dfrn_id;
            break;
        case 1:
            $sql_extra = sprintf(" AND `dfrn-id` = '%s' AND `duplex` = 1 ", dbesc($dfrn_id));
            $my_id = '0:' . $dfrn_id;
            break;
        default:
            goaway(z_root());
            break;
            // NOTREACHED
    }
    $r = q("SELECT * FROM `contact` WHERE `blocked` = 0 AND `pending` = 0 {$sql_extra} LIMIT 1");
    if (!count($r)) {
        killme();
    }
    $contact = $r[0];
    $owner_uid = $r[0]['uid'];
    $contact_id = $r[0]['id'];
    if ($type === 'reputation' && strlen($url)) {
        $r = q("SELECT * FROM `contact` WHERE `url` = '%s' AND `uid` = %d LIMIT 1", dbesc($url), intval($owner_uid));
        $reputation = 0;
        $text = '';
        if (count($r)) {
            $reputation = $r[0]['rating'];
            $text = $r[0]['reason'];
            if ($r[0]['id'] == $contact_id) {
                // inquiring about own reputation not allowed
                $reputation = 0;
                $text = '';
            }
        }
        echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\t\t<reputation>\n\t\t\t<url>{$url}</url>\n\t\t\t<rating>{$reputation}</rating>\n\t\t\t<description>{$text}</description>\n\t\t</reputation>\n\t\t";
        killme();
        // NOTREACHED
    } else {
        // Update the writable flag if it changed
        logger('dfrn_poll: post request feed: ' . print_r($_POST, true), LOGGER_DATA);
        if ($dfrn_version >= 2.21) {
            if ($perm === 'rw') {
                $writable = 1;
            } else {
                $writable = 0;
            }
            if ($writable != $contact['writable']) {
                q("UPDATE `contact` SET `writable` = %d WHERE `id` = %d LIMIT 1", intval($writable), intval($contact_id));
            }
        }
        header("Content-type: application/atom+xml");
        $o = get_feed_for($a, $dfrn_id, $a->argv[1], $last_update, $direction);
        echo $o;
        killme();
    }
}
Esempio n. 5
0
function dfrn_poll_post(&$a)
{
    $dfrn_id = notags(trim($_POST['dfrn_id']));
    $challenge = notags(trim($_POST['challenge']));
    $url = $_POST['url'];
    $r = q("SELECT * FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1", dbesc($dfrn_id), dbesc($challenge));
    if (!count($r)) {
        killme();
    }
    $type = $r[0]['type'];
    $last_update = $r[0]['last_update'];
    $r = q("DELETE FROM `challenge` WHERE `dfrn-id` = '%s' AND `challenge` = '%s' LIMIT 1", dbesc($dfrn_id), dbesc($challenge));
    $r = q("SELECT * FROM `contact` WHERE ( `issued-id` = '%s' OR ( `dfrn-id` = '%s' AND `duplex` = 1 )) LIMIT 1", dbesc($dfrn_id), dbesc($dfrn_id));
    if (!count($r)) {
        killme();
    }
    $contact_id = $r[0]['id'];
    if ($type == 'reputation' && strlen($url)) {
        $r = q("SELECT * FROM `contact` WHERE `url` = '%s' LIMIT 1", dbesc($url));
        $reputation = 0;
        $text = '';
        if (count($r)) {
            $reputation = $r[0]['rating'];
            $text = $r[0]['reason'];
            if ($r[0]['id'] == $contact_id) {
                // inquiring about own reputation not allowed
                $reputation = 0;
                $text = '';
            }
        }
        echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\t\t<reputation>\n\t\t\t<url>{$url}</url>\n\t\t\t<rating>{$reputation}</rating>\n\t\t\t<description>{$text}</description>\n\t\t</reputation>\n\t\t";
        killme();
        return;
        // NOTREACHED
    } else {
        $o = get_feed_for($a, $dfrn_id, $a->argv[1], $last_update);
        echo $o;
        killme();
    }
}