Exemplo n.º 1
0
 function init()
 {
     $uri = urldecode(notags(trim($_GET['uri'])));
     logger('xrd: ' . $uri, LOGGER_DEBUG);
     $resource = $uri;
     if (substr($uri, 0, 4) === 'http') {
         $uri = str_replace('~', '', $uri);
         $name = basename($uri);
     } else {
         $local = str_replace('acct:', '', $uri);
         if (substr($local, 0, 2) == '//') {
             $local = substr($local, 2);
         }
         $name = substr($local, 0, strpos($local, '@'));
     }
     $r = q("SELECT * FROM channel WHERE channel_address = '%s' LIMIT 1", dbesc($name));
     if (!$r) {
         killme();
     }
     $dspr = replace_macros(get_markup_template('xrd_diaspora.tpl'), array('$baseurl' => z_root(), '$dspr_guid' => $r[0]['channel_guid'] . str_replace('.', '', \App::get_hostname()), '$dspr_key' => base64_encode(pemtorsa($r[0]['channel_pubkey']))));
     $salmon_key = salmon_key($r[0]['channel_pubkey']);
     header('Access-Control-Allow-Origin: *');
     header("Content-type: application/xrd+xml");
     $aliases = array('acct:' . channel_reddress($r[0]), z_root() . '/channel/' . $r[0]['channel_address'], z_root() . '/~' . $r[0]['channel_address']);
     for ($x = 0; $x < count($aliases); $x++) {
         if ($aliases[$x] === $resource) {
             unset($aliases[$x]);
         }
     }
     $o = replace_macros(get_markup_template('xrd_person.tpl'), array('$nick' => $r[0]['channel_address'], '$accturi' => $resource, '$aliases' => $aliases, '$profile_url' => z_root() . '/channel/' . $r[0]['channel_address'], '$hcard_url' => z_root() . '/hcard/' . $r[0]['channel_address'], '$atom' => z_root() . '/feed/' . $r[0]['channel_address'], '$zot_post' => z_root() . '/post/' . $r[0]['channel_address'], '$poco_url' => z_root() . '/poco/' . $r[0]['channel_address'], '$photo' => z_root() . '/photo/profile/l/' . $r[0]['channel_id'], '$dspr' => $dspr, '$modexp' => 'data:application/magic-public-key,' . $salmon_key, '$subscribe' => z_root() . '/follow?url={uri}', '$bigkey' => salmon_key($r[0]['channel_pubkey'])));
     $arr = array('user' => $r[0], 'xml' => $o);
     call_hooks('personal_xrd', $arr);
     echo $arr['xml'];
     killme();
 }
Exemplo n.º 2
0
function xrd_init(&$a)
{
    $uri = urldecode(notags(trim($_GET['uri'])));
    if (substr($uri, 0, 4) === 'http') {
        $name = basename($uri);
    } else {
        $local = str_replace('acct:', '', $uri);
        if (substr($local, 0, 2) == '//') {
            $local = substr($local, 2);
        }
        $name = substr($local, 0, strpos($local, '@'));
    }
    $r = q("SELECT * FROM `user` WHERE `nickname` = '%s' LIMIT 1", dbesc($name));
    if (!count($r)) {
        killme();
    }
    $salmon_key = salmon_key($r[0]['spubkey']);
    header('Access-Control-Allow-Origin: *');
    header("Content-type: text/xml");
    if (get_config('system', 'diaspora_enabled')) {
        //$tpl = file_get_contents('view/xrd_diaspora.tpl');
        $tpl = get_markup_template('xrd_diaspora.tpl');
        $dspr = replace_macros($tpl, array('$baseurl' => $a->get_baseurl(), '$dspr_guid' => $r[0]['guid'], '$dspr_key' => base64_encode(pemtorsa($r[0]['pubkey']))));
    } else {
        $dspr = '';
    }
    //$tpl = file_get_contents('view/xrd_person.tpl');
    $tpl = get_markup_template('xrd_person.tpl');
    $o = replace_macros($tpl, array('$nick' => $r[0]['nickname'], '$accturi' => $uri, '$profile_url' => $a->get_baseurl() . '/profile/' . $r[0]['nickname'], '$hcard_url' => $a->get_baseurl() . '/hcard/' . $r[0]['nickname'], '$atom' => $a->get_baseurl() . '/dfrn_poll/' . $r[0]['nickname'], '$zot_post' => $a->get_baseurl() . '/post/' . $r[0]['nickname'], '$poco_url' => $a->get_baseurl() . '/poco/' . $r[0]['nickname'], '$photo' => $a->get_baseurl() . '/photo/profile/' . $r[0]['uid'] . '.jpg', '$dspr' => $dspr, '$salmon' => $a->get_baseurl() . '/salmon/' . $r[0]['nickname'], '$salmen' => $a->get_baseurl() . '/salmon/' . $r[0]['nickname'] . '/mention', '$subscribe' => $a->get_baseurl() . '/follow?url={uri}', '$modexp' => 'data:application/magic-public-key,' . $salmon_key, '$bigkey' => salmon_key($r[0]['pubkey'])));
    $arr = array('user' => $r[0], 'xml' => $o);
    call_hooks('personal_xrd', $arr);
    echo $arr['xml'];
    killme();
}
Exemplo n.º 3
0
function xrd_init(&$a)
{
    $uri = urldecode(notags(trim($_GET['uri'])));
    if (substr($uri, 0, 4) === 'http') {
        $name = basename($uri);
    } else {
        $local = str_replace('acct:', '', $uri);
        if (substr($local, 0, 2) == '//') {
            $local = substr($local, 2);
        }
        $name = substr($local, 0, strpos($local, '@'));
    }
    $r = q("SELECT * FROM channel WHERE channel_address = '%s' LIMIT 1", dbesc($name));
    if (!$r) {
        killme();
    }
    $dspr = replace_macros(get_markup_template('xrd_diaspora.tpl'), array('$baseurl' => $a->get_baseurl(), '$dspr_guid' => $r[0]['channel_guid'], '$dspr_key' => base64_encode(pemtorsa($r[0]['channel_pubkey']))));
    $salmon_key = salmon_key($r[0]['channel_pubkey']);
    header('Access-Control-Allow-Origin: *');
    header("Content-type: text/xml");
    $tpl = get_markup_template('view/xrd_person.tpl');
    $o = replace_macros(get_markup_template('xrd_person.tpl'), array('$nick' => $r[0]['channel_address'], '$accturi' => $uri, '$profile_url' => $a->get_baseurl() . '/channel/' . $r[0]['channel_address'], '$hcard_url' => $a->get_baseurl() . '/hcard/' . $r[0]['channel_address'], '$atom' => $a->get_baseurl() . '/feed/' . $r[0]['channel_address'], '$zot_post' => $a->get_baseurl() . '/post/' . $r[0]['channel_address'], '$poco_url' => $a->get_baseurl() . '/poco/' . $r[0]['channel_address'], '$photo' => $a->get_baseurl() . '/photo/profile/l/' . $r[0]['channel_id'], '$dspr' => $dspr, '$modexp' => 'data:application/magic-public-key,' . $salmon_key));
    $arr = array('user' => $r[0], 'xml' => $o);
    call_hooks('personal_xrd', $arr);
    echo $arr['xml'];
    killme();
}
Exemplo n.º 4
0
function slapper($owner, $url, $slap)
{
    // does contact have a salmon endpoint?
    if (!strlen($url)) {
        return;
    }
    if (!$owner['channel_prvkey']) {
        logger(sprintf("channel '%s' (%d) does not have a salmon private key. Send failed.", $owner['channel_address'], $owner['channel_id']));
        return;
    }
    logger('slapper called for ' . $url . '. Data: ' . $slap, LOGGER_DATA, LOG_DEBUG);
    // create a magic envelope
    $data = base64url_encode($slap);
    $data_type = 'application/atom+xml';
    $encoding = 'base64url';
    $algorithm = 'RSA-SHA256';
    $keyhash = base64url_encode(hash('sha256', salmon_key($owner['channel_pubkey'])), true);
    // precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
    $precomputed = '.YXBwbGljYXRpb24vYXRvbSt4bWw=.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
    $signature = base64url_encode(rsa_sign(str_replace('=', '', $data . $precomputed), $owner['channel_prvkey']));
    $signature2 = base64url_encode(rsa_sign($data . $precomputed, $owner['channel_prvkey']));
    $signature3 = base64url_encode(rsa_sign($data, $owner['channel_prvkey']));
    $salmon_tpl = get_markup_template('magicsig.tpl');
    $salmon = replace_macros($salmon_tpl, array('$data' => $data, '$encoding' => $encoding, '$algorithm' => $algorithm, '$keyhash' => $keyhash, '$signature' => $signature));
    // slap them
    $redirects = 0;
    $ret = z_post_url($url, $salmon, $redirects, array('headers' => array('Content-type: application/magic-envelope+xml', 'Content-length: ' . strlen($salmon))));
    $return_code = $ret['return_code'];
    // check for success, e.g. 2xx
    if ($return_code > 299) {
        logger('compliant salmon failed. Falling back to status.net hack2');
        // Entirely likely that their salmon implementation is
        // non-compliant. Let's try once more, this time only signing
        // the data, without stripping '=' chars
        $salmon = replace_macros($salmon_tpl, array('$data' => $data, '$encoding' => $encoding, '$algorithm' => $algorithm, '$keyhash' => $keyhash, '$signature' => $signature2));
        $redirects = 0;
        $ret = z_post_url($url, $salmon, $redirects, array('headers' => array('Content-type: application/magic-envelope+xml', 'Content-length: ' . strlen($salmon))));
        $return_code = $ret['return_code'];
        if ($return_code > 299) {
            logger('compliant salmon failed. Falling back to status.net hack3');
            // Entirely likely that their salmon implementation is
            // non-compliant. Let's try once more, this time only signing
            // the data, without the precomputed blob
            $salmon = replace_macros($salmon_tpl, array('$data' => $data, '$encoding' => $encoding, '$algorithm' => $algorithm, '$keyhash' => $keyhash, '$signature' => $signature3));
            $redirects = 0;
            $ret = z_post_url($url, $salmon, $redirects, array('headers' => array('Content-type: application/magic-envelope+xml', 'Content-length: ' . strlen($salmon))));
            $return_code = $ret['return_code'];
        }
    }
    logger('slapper for ' . $url . ' returned ' . $return_code);
    if (!$return_code) {
        return -1;
    }
    if ($return_code == 503 && stristr($ret['header'], 'retry-after')) {
        return -1;
    }
    return $return_code >= 200 && $return_code < 300 ? 0 : 1;
}
Exemplo n.º 5
0
function hostxrd_init(&$a)
{
    header('Access-Control-Allow-Origin: *');
    header("Content-type: text/xml");
    $pubkey = get_config('system', 'site_pubkey');
    if (!$pubkey) {
        $res = new_keypair(1024);
        set_config('system', 'site_prvkey', $res['prvkey']);
        set_config('system', 'site_pubkey', $res['pubkey']);
    }
    $tpl = file_get_contents('view/xrd_host.tpl');
    echo str_replace(array('$zhost', '$zroot', '$domain', '$zot_post', '$bigkey'), array($a->get_hostname(), z_root(), z_path(), z_root() . '/post', salmon_key(get_config('system', 'site_pubkey'))), $tpl);
    session_write_close();
    exit;
}
Exemplo n.º 6
0
function hostxrd_init(&$a)
{
    header('Access-Control-Allow-Origin: *');
    header("Content-type: text/xml");
    $pubkey = get_config('system', 'site_pubkey');
    if (!$pubkey) {
        // should only have to ever do this once.
        $res = openssl_pkey_new(array('digest_alg' => 'sha1', 'private_key_bits' => 4096, 'encrypt_key' => false));
        $prvkey = '';
        openssl_pkey_export($res, $prvkey);
        // Get public key
        $pkey = openssl_pkey_get_details($res);
        $pubkey = $pkey["key"];
        set_config('system', 'site_prvkey', $prvkey);
        set_config('system', 'site_pubkey', $pubkey);
    }
    $tpl = file_get_contents('view/xrd_host.tpl');
    echo str_replace(array('$zhost', '$zroot', '$domain', '$zot_post', '$bigkey'), array($a->get_hostname(), z_root(), z_path(), z_root() . '/post', salmon_key(get_config('system', 'site_pubkey'))), $tpl);
    session_write_close();
    exit;
}
Exemplo n.º 7
0
function slapper($owner, $url, $slap)
{
    // does contact have a salmon endpoint?
    if (!strlen($url)) {
        return;
    }
    if (!$owner['channel_prvkey']) {
        logger(sprintf("channel '%s' (%d) does not have a salmon private key. Send failed.", $owner['channel_address'], $owner['channel_id']));
        return;
    }
    logger('slapper called for ' . $url . '. Data: ' . $slap, LOGGER_DATA, LOG_DEBUG);
    // create a magic envelope
    $data = base64url_encode($slap, false);
    // do not strip padding
    $data_type = 'application/atom+xml';
    $encoding = 'base64url';
    $algorithm = 'RSA-SHA256';
    $keyhash = base64url_encode(hash('sha256', salmon_key($owner['channel_pubkey'])), true);
    $data = str_replace(array(" ", "\t", "\r", "\n"), array("", "", "", ""), $data);
    // precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
    $precomputed = '.YXBwbGljYXRpb24vYXRvbSt4bWw=.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
    $signature = base64url_encode(rsa_sign($data . $precomputed, $owner['channel_prvkey']));
    $salmon_tpl = get_markup_template('magicsig.tpl', 'addon/gnusoc/');
    $salmon = replace_macros($salmon_tpl, array('$data' => $data, '$encoding' => $encoding, '$algorithm' => $algorithm, '$keyhash' => $keyhash, '$signature' => $signature));
    logger('salmon: ' . $salmon, LOGGER_DATA);
    $hash = random_string();
    queue_insert(array('hash' => $hash, 'account_id' => $owner['channel_account_id'], 'channel_id' => $owner['channel_id'], 'driver' => 'slap', 'posturl' => $url, 'notify' => '', 'msg' => $salmon));
    return $hash;
}
Exemplo n.º 8
0
function slapper($owner, $url, $slap)
{
    logger('slapper called for ' . $url . '. Data: ' . $slap);
    // does contact have a salmon endpoint?
    if (!strlen($url)) {
        return;
    }
    if (!$owner['sprvkey']) {
        logger(sprintf("user '%s' (%d) does not have a salmon private key. Send failed.", $owner['username'], $owner['uid']));
        return;
    }
    // add all namespaces to item
    $namespaces = <<<EOT
<entry xmlns="http://www.w3.org/2005/Atom"
      xmlns:thr="http://purl.org/syndication/thread/1.0"
      xmlns:at="http://purl.org/atompub/tombstones/1.0"
      xmlns:media="http://purl.org/syndication/atommedia"
      xmlns:dfrn="http://purl.org/macgirvin/dfrn/1.0" 
      xmlns:as="http://activitystrea.ms/spec/1.0/"
      xmlns:georss="http://www.georss.org/georss" 
      xmlns:poco="http://portablecontacts.net/spec/1.0" 
      xmlns:ostatus="http://ostatus.org/schema/1.0" 
\t  xmlns:statusnet="http://status.net/schema/api/1/" >\t\t\t\t\t\t\t\t\t\t\t\t\t>
EOT;
    $slap = str_replace('<entry>', $namespaces, $slap);
    // create a magic envelope
    $data = base64url_encode($slap);
    $data_type = 'application/atom+xml';
    $encoding = 'base64url';
    $algorithm = 'RSA-SHA256';
    $keyhash = base64url_encode(hash('sha256', salmon_key($owner['spubkey'])), true);
    // precomputed base64url encoding of data_type, encoding, algorithm concatenated with periods
    $precomputed = '.YXBwbGljYXRpb24vYXRvbSt4bWw=.YmFzZTY0dXJs.UlNBLVNIQTI1Ng==';
    $signature = base64url_encode(rsa_sign(str_replace('=', '', $data . $precomputed), $owner['sprvkey']));
    $signature2 = base64url_encode(rsa_sign($data . $precomputed, $owner['sprvkey']));
    $signature3 = base64url_encode(rsa_sign($data, $owner['sprvkey']));
    $salmon_tpl = get_markup_template('magicsig.tpl');
    $salmon = replace_macros($salmon_tpl, array('$data' => $data, '$encoding' => $encoding, '$algorithm' => $algorithm, '$keyhash' => $keyhash, '$signature' => $signature));
    // slap them
    post_url($url, $salmon, array('Content-type: application/magic-envelope+xml', 'Content-length: ' . strlen($salmon)));
    $a = get_app();
    $return_code = $a->get_curl_code();
    // check for success, e.g. 2xx
    if ($return_code > 299) {
        logger('compliant salmon failed. Falling back to status.net hack2');
        // Entirely likely that their salmon implementation is
        // non-compliant. Let's try once more, this time only signing
        // the data, without stripping '=' chars
        $salmon = replace_macros($salmon_tpl, array('$data' => $data, '$encoding' => $encoding, '$algorithm' => $algorithm, '$keyhash' => $keyhash, '$signature' => $signature2));
        // slap them
        post_url($url, $salmon, array('Content-type: application/magic-envelope+xml', 'Content-length: ' . strlen($salmon)));
        $return_code = $a->get_curl_code();
        if ($return_code > 299) {
            logger('compliant salmon failed. Falling back to status.net hack3');
            // Entirely likely that their salmon implementation is
            // non-compliant. Let's try once more, this time only signing
            // the data, without the precomputed blob
            $salmon = replace_macros($salmon_tpl, array('$data' => $data, '$encoding' => $encoding, '$algorithm' => $algorithm, '$keyhash' => $keyhash, '$signature' => $signature3));
            // slap them
            post_url($url, $salmon, array('Content-type: application/magic-envelope+xml', 'Content-length: ' . strlen($salmon)));
            $return_code = $a->get_curl_code();
        }
    }
    logger('slapper for ' . $url . ' returned ' . $return_code);
    if (!$return_code) {
        return -1;
    }
    if ($return_code == 503 && stristr($a->get_curl_headers(), 'retry-after')) {
        return -1;
    }
    return $return_code >= 200 && $return_code < 300 ? 0 : 1;
}
Exemplo n.º 9
0
 function init()
 {
     $result = array();
     $scheme = '';
     if (x($_SERVER, 'HTTPS') && $_SERVER['HTTPS']) {
         $scheme = 'https';
     } elseif (x($_SERVER, 'SERVER_PORT') && intval($_SERVER['SERVER_PORT']) == 443) {
         $scheme = 'https';
     }
     $zot = intval($_REQUEST['zot']);
     if ($scheme !== 'https' && !$zot) {
         header($_SERVER["SERVER_PROTOCOL"] . ' ' . 500 . ' ' . 'Webfinger requires HTTPS');
         killme();
     }
     $resource = $_REQUEST['resource'];
     logger('webfinger: ' . $resource, LOGGER_DEBUG);
     $r = null;
     if ($resource) {
         if (strpos($resource, 'acct:') === 0) {
             $channel = str_replace('acct:', '', $resource);
             if (strpos($channel, '@') !== false) {
                 $host = substr($channel, strpos($channel, '@') + 1);
                 if (strcasecmp($host, \App::get_hostname())) {
                     goaway('https://' . $host . '/.well-known/webfinger?f=&resource=' . $resource . ($zot ? '&zot=' . $zot : ''));
                 }
                 $channel = substr($channel, 0, strpos($channel, '@'));
             }
         }
         if (strpos($resource, 'http') === 0) {
             $channel = str_replace('~', '', basename($resource));
         }
         $r = q("select * from channel left join xchan on channel_hash = xchan_hash \n\t\t\t\twhere channel_address = '%s' limit 1", dbesc($channel));
     }
     header('Access-Control-Allow-Origin: *');
     if ($resource && $r) {
         $h = q("select hubloc_addr from hubloc where hubloc_hash = '%s' and hubloc_deleted = 0", dbesc($r[0]['channel_hash']));
         $result['subject'] = $resource;
         $aliases = array(z_root() . '/channel/' . $r[0]['channel_address'], z_root() . '/~' . $r[0]['channel_address']);
         if ($h) {
             foreach ($h as $hh) {
                 $aliases[] = 'acct:' . $hh['hubloc_addr'];
             }
         }
         $result['aliases'] = array();
         $result['properties'] = array('http://webfinger.net/ns/name' => $r[0]['channel_name'], 'http://xmlns.com/foaf/0.1/name' => $r[0]['channel_name']);
         foreach ($aliases as $alias) {
             if ($alias != $resource) {
                 $result['aliases'][] = $alias;
             }
         }
         $result['links'] = array(array('rel' => 'http://webfinger.net/rel/avatar', 'type' => $r[0]['xchan_photo_mimetype'], 'href' => $r[0]['xchan_photo_l']), array('rel' => 'http://webfinger.net/rel/profile-page', 'href' => z_root() . '/profile/' . $r[0]['channel_address']), array('rel' => 'http://webfinger.net/rel/blog', 'href' => z_root() . '/channel/' . $r[0]['channel_address']), array('rel' => 'http://ostatus.org/schema/1.0/subscribe', 'template' => z_root() . '/follow/url={uri}'), array('rel' => 'http://purl.org/zot/protocol', 'href' => z_root() . '/.well-known/zot-info' . '?address=' . $r[0]['xchan_addr']), array('rel' => 'magic-public-key', 'href' => 'data:application/magic-public-key,' . salmon_key($r[0]['channel_pubkey'])));
         if ($zot) {
             // get a zotinfo packet and return it with webfinger
             $result['zot'] = zotinfo(array('address' => $r[0]['xchan_addr']));
         }
     } else {
         header($_SERVER["SERVER_PROTOCOL"] . ' ' . 400 . ' ' . 'Bad Request');
         killme();
     }
     $arr = array('channel' => $r[0], 'request' => $_REQUEST, 'result' => $result);
     call_hooks('webfinger', $arr);
     json_return_and_die($arr['result'], 'application/jrd+json');
 }