Пример #1
0
function webfinger_content(&$a)
{
    $o .= '<h3>Webfinger Diagnostic</h3>';
    $o .= '<form action="webfinger" method="get">';
    $o .= 'Lookup address: <input type="text" style="width: 250px;" name="addr" value="' . $_GET['addr'] . '" />';
    $o .= '<input type="submit" name="submit" value="Submit" /></form>';
    $o .= '<br /><br />';
    if (x($_GET, 'addr')) {
        $addr = trim($_GET['addr']);
        if (strpos($addr, '@') !== false) {
            $res = webfinger_rfc7033($addr, true);
            if (!$res) {
                $res = old_webfinger($addr);
            }
        } else {
            if (function_exists('lrdd')) {
                $res = lrdd($addr);
            }
        }
        $o .= '<pre>';
        $o .= str_replace("\n", '<br />', print_r($res, true));
        $o .= '</pre>';
    }
    return $o;
}
Пример #2
0
function get_salmon_key($uri, $keyhash)
{
    $ret = array();
    logger('Fetching salmon key for ' . $uri, LOGGER_DEBUG, LOG_INFO);
    $x = webfinger_rfc7033($uri, true);
    logger('webfinger returns: ' . print_r($x, true), LOGGER_DATA, LOG_DEBUG);
    if ($x && array_key_exists('links', $x) && $x['links']) {
        foreach ($x['links'] as $link) {
            if (array_key_exists('rel', $link) && $link['rel'] === 'magic-public-key') {
                $ret[] = $link['href'];
            }
        }
    } else {
        $arr = old_webfinger($uri);
        logger('old webfinger returns: ' . print_r($arr, true), LOGGER_DATA, LOG_DEBUG);
        if (is_array($arr)) {
            foreach ($arr as $a) {
                if ($a['@attributes']['rel'] === 'magic-public-key') {
                    $ret[] = $a['@attributes']['href'];
                }
            }
        } else {
            return '';
        }
    }
    // We have found at least one key URL
    // If it's inline, parse it - otherwise get the key
    if (count($ret)) {
        for ($x = 0; $x < count($ret); $x++) {
            if (substr($ret[$x], 0, 5) === 'data:') {
                $ret[$x] = convert_salmon_key($ret[$x]);
            }
        }
    }
    logger('Key located: ' . print_r($ret, true), LOGGER_DEBUG, LOG_INFO);
    if (count($ret) == 1) {
        // We only found one one key so we don't care if the hash matches.
        // If it's the wrong key we'll find out soon enough because
        // message verification will fail. This also covers some older
        // software which don't supply a keyhash. As long as they only
        // have one key we'll be right.
        return $ret[0];
    } else {
        foreach ($ret as $a) {
            $hash = base64url_encode(hash('sha256', $a));
            if ($hash == $keyhash) {
                return $a;
            }
        }
    }
    return '';
}
Пример #3
0
 function get()
 {
     $o .= '<h3>Webfinger Diagnostic</h3>';
     $o .= '<form action="webfinger" method="get">';
     $o .= 'Lookup address: <input type="text" style="width: 250px;" name="addr" value="' . $_GET['addr'] . '" />';
     $o .= '<input type="submit" name="submit" value="Submit" /></form>';
     $o .= '<br /><br />';
     $old = false;
     if (x($_GET, 'addr')) {
         $addr = trim($_GET['addr']);
         //		if(strpos($addr,'@') !== false) {
         $res = webfinger_rfc7033($addr, true);
         if (!$res) {
             $res = old_webfinger($addr);
             $old = true;
         }
         //		}
         //		else {
         //			if(function_exists('lrdd'))
         //				$res = lrdd($addr);
         //		}
         if ($res && $old) {
             foreach ($res as $r) {
                 if ($r['@attributes']['rel'] === 'http://microformats.org/profile/hcard') {
                     $hcard = unamp($r['@attributes']['href']);
                     require_once 'library/HTML5/Parser.php';
                     $res['vcard'] = scrape_vcard($hcard);
                     break;
                 }
             }
         }
         $o .= '<pre>';
         $o .= str_replace("\n", '<br />', print_r($res, true));
         $o .= '</pre>';
     }
     return $o;
 }
Пример #4
0
function diaspora_discover(&$a, &$b)
{
    require_once 'include/network.php';
    $result = array();
    $network = null;
    $diaspora = false;
    $diaspora_base = '';
    $diaspora_guid = '';
    $diaspora_key = '';
    $dfrn = false;
    $x = old_webfinger($webbie);
    if ($x) {
        logger('old_webfinger: ' . print_r($x, true));
        foreach ($x as $link) {
            if ($link['@attributes']['rel'] === NAMESPACE_DFRN) {
                $dfrn = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === 'salmon') {
                $notify = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === NAMESPACE_FEED) {
                $poll = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') {
                $hcard = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') {
                $profile = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') {
                $poco = unamp($link['@attributes']['href']);
            }
            if ($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
                $diaspora_base = unamp($link['@attributes']['href']);
                $diaspora = true;
            }
            if ($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
                $diaspora_guid = unamp($link['@attributes']['href']);
                $diaspora = true;
            }
            if ($link['@attributes']['rel'] === 'diaspora-public-key') {
                $diaspora_key = base64_decode(unamp($link['@attributes']['href']));
                if (strstr($diaspora_key, 'RSA ')) {
                    $pubkey = rsatopem($diaspora_key);
                } else {
                    $pubkey = $diaspora_key;
                }
                $diaspora = true;
            }
        }
        if ($diaspora && $diaspora_base && $diaspora_guid) {
            $guid = $diaspora_guid;
            $diaspora_base = trim($diaspora_base, '/');
            $notify = $diaspora_base . '/receive';
            if (strpos($webbie, '@')) {
                $addr = str_replace('acct:', '', $webbie);
                $hostname = substr($webbie, strpos($webbie, '@') + 1);
            }
            $network = 'diaspora';
            // until we get a dfrn layer, we'll use diaspora protocols for Friendica,
            // but give it a different network so we can go back and fix these when we get proper support.
            // It really should be just 'friendica' but we also want to distinguish
            // between Friendica sites that we can use D* protocols with and those we can't.
            // Some Friendica sites will have Diaspora disabled.
            if ($dfrn) {
                $network = 'friendica-over-diaspora';
            }
            if ($hcard) {
                $vcard = scrape_vcard($hcard);
                $vcard['nick'] = substr($webbie, 0, strpos($webbie, '@'));
                if (!$vcard['fn']) {
                    $vcard['fn'] = $webbie;
                }
            }
            $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($addr));
            /**
             *
             * Diaspora communications are notoriously unreliable and receiving profile update messages (indeed any messages) 
             * are pretty much random luck. We'll check the timestamp of the xchan_name_date at a higher level and refresh
             * this record once a month; because if you miss a profile update message and they update their profile photo or name 
             * you're otherwise stuck with stale info until they change their profile again - which could be years from now. 
             *
             */
            if ($r) {
                $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s' limit 1", dbesc($vcard['fn']), dbesc($network), dbesc(datetime_convert()), dbesc($addr));
            } else {
                $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ", dbesc($addr), dbesc($guid), dbesc($pubkey), dbesc($addr), dbesc($profile), dbesc($vcard['fn']), dbesc($network), dbescdate(datetime_convert()));
            }
            $r = q("select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($webbie));
            if (!$r) {
                $r = q("insert into hubloc ( hubloc_guid, hubloc_hash, hubloc_addr, hubloc_network, hubloc_url, hubloc_host, hubloc_callback, hubloc_updated, hubloc_primary ) values ('%s','%s','%s','%s','%s','%s','%s','%s', 1)", dbesc($guid), dbesc($addr), dbesc($addr), dbesc($network), dbesc(trim($diaspora_base, '/')), dbesc($hostname), dbesc($notify), dbescdate(datetime_convert()));
            }
            $photos = import_xchan_photo($vcard['photo'], $addr);
            $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbescdate(datetime_convert('UTC', 'UTC', $arr['photo_updated'])), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($addr));
            return true;
        }
        return false;
        /*
        	$vcard['fn'] = notags($vcard['fn']);
        	$vcard['nick'] = str_replace(' ','',notags($vcard['nick']));
        	$result['name'] = $vcard['fn'];
        	$result['nick'] = $vcard['nick'];
        	$result['guid'] = $guid;
        	$result['url'] = $profile;
        	$result['hostname'] = $hostname;
        	$result['addr'] = $addr;
        	$result['batch'] = $batch;
        	$result['notify'] = $notify;
        	$result['poll'] = $poll;
        	$result['request'] = $request;
        	$result['confirm'] = $confirm;
        	$result['poco'] = $poco;
        	$result['photo'] = $vcard['photo'];
        	$result['priority'] = $priority;
        	$result['network'] = $network;
        	$result['alias'] = $alias;
        	$result['pubkey'] = $pubkey;
        	logger('probe_url: ' . print_r($result,true), LOGGER_DEBUG);
        	return $result;
        */
        /* Sample Diaspora result.
        
        Array
        (
        	[name] => Mike Macgirvin
        	[nick] => macgirvin
        	[guid] => a9174a618f8d269a
        	[url] => https://joindiaspora.com/u/macgirvin
        	[hostname] => joindiaspora.com
        	[addr] => macgirvin@joindiaspora.com
        	[batch] => 
        	[notify] => https://joindiaspora.com/receive
        	[poll] => https://joindiaspora.com/public/macgirvin.atom
        	[request] => 
        	[confirm] => 
        	[poco] => 
        	[photo] => https://joindiaspora.s3.amazonaws.com/uploads/images/thumb_large_fec4e6eef13ae5e56207.jpg
        	[priority] => 
        	[network] => diaspora
        	[alias] => 
        	[pubkey] => -----BEGIN PUBLIC KEY-----
        MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtihtyIuRDWkDpCA+I1UaQ
        jI4S7k625+A7EEJm+pL2ZVSJxeCKiFeEgHBQENjLMNNm8l8F6blxgQqE6ZJ9Spa7f
        tlaXYTRCrfxKzh02L3hR7sNA+JS/nXJaUAIo+IwpIEspmcIRbD9GB7Wv/rr+M28uH
        31EeYyDz8QL6InU/bJmnCdFvmEMBQxJOw1ih9tQp7UNJAbUMCje0WYFzBz7sfcaHL
        OyYcCOqOCBLdGucUoJzTQ9iDBVzB8j1r1JkIHoEb2moUoKUp+tkCylNfd/3IVELF9
        7w1Qjmit3m50OrJk2DQOXvCW9KQxaQNdpRPSwhvemIt98zXSeyZ1q/YjjOwG0DWDq
        AF8aLj3/oQaZndTPy/6tMiZogKaijoxj8xFLuPYDTw5VpKquriVC0z8oxyRbv4t9v
        8JZZ9BXqzmayvY3xZGGp8NulrfjW+me2bKh0/df1aHaBwpZdDTXQ6kqAiS2FfsuPN
        vg57fhfHbL1yJ4oDbNNNeI0kJTGchXqerr8C20khU/cQ2Xt31VyEZtnTB665Ceugv
        kp3t2qd8UpAVKl430S5Quqx2ymfUIdxdW08CEjnoRNEL3aOWOXfbf4gSVaXmPCR4i
        LSIeXnd14lQYK/uxW/8cTFjcmddsKxeXysoQxbSa9VdDK+KkpZdgYXYrTTofXs6v+
        4afAEhRaaY+MCAwEAAQ==
        -----END PUBLIC KEY-----
        
        )
        */
    }
}
Пример #5
0
function discover_by_webbie($webbie)
{
    require_once 'library/HTML5/Parser.php';
    $result = array();
    $network = null;
    $diaspora = false;
    $gnusoc = false;
    $dfrn = false;
    $has_salmon = false;
    $salmon_key = false;
    $atom_feed = false;
    $diaspora_base = '';
    $diaspora_guid = '';
    $diaspora_key = '';
    $webbie = strtolower($webbie);
    $x = webfinger_rfc7033($webbie, true);
    if ($x && array_key_exists('links', $x) && $x['links']) {
        foreach ($x['links'] as $link) {
            if (array_key_exists('rel', $link)) {
                // If we discover zot - don't search further; grab the info and get out of
                // here.
                if ($link['rel'] === PROTOCOL_ZOT) {
                    logger('discover_by_webbie: zot found for ' . $webbie, LOGGER_DEBUG);
                    if (array_key_exists('zot', $x) && $x['zot']['success']) {
                        $i = import_xchan($x['zot']);
                    } else {
                        $z = z_fetch_url($link['href']);
                        if ($z['success']) {
                            $j = json_decode($z['body'], true);
                            $i = import_xchan($j);
                            return true;
                        }
                    }
                }
                if ($link['rel'] == NAMESPACE_DFRN) {
                    $dfrn = $link['href'];
                }
                if ($link['rel'] == 'magic-public-key') {
                    if (substr($link['href'], 0, 5) === 'data:') {
                        $salmon_key = convert_salmon_key($link['href']);
                    }
                }
                if ($link['rel'] == 'salmon') {
                    $has_salmon = true;
                    $salmon = $link['href'];
                }
                if ($link['rel'] == 'http://schemas.google.com/g/2010#updates-from') {
                    $atom_feed = $link['href'];
                }
            }
        }
    }
    logger('webfinger: ' . print_r($x, true), LOGGER_DATA, LOG_INFO);
    $arr = array('address' => $webbie, 'success' => false, 'webfinger' => $x);
    call_hooks('discover_channel_webfinger', $arr);
    if ($arr['success']) {
        return true;
    }
    $aliases = array();
    // Now let's make some decisions on what we may need
    // to obtain further info
    $probe_atom = false;
    $probe_old = false;
    $probe_hcard = false;
    $address = '';
    $location = '';
    $nickname = '';
    $fullname = '';
    $avatar = '';
    $pubkey = '';
    if (is_array($x)) {
        if (array_key_exists('address', $x)) {
            $address = $x['address'];
        }
        if (array_key_exists('location', $x)) {
            $location = $x['location'];
        }
        if (array_key_exists('nickname', $x)) {
            $nickname = $x['nickname'];
        }
    }
    if (!$x) {
        $probe_old = true;
    }
    if (!$dfrn && !$has_salmon) {
        $probe_old = true;
    }
    if ($probe_old) {
        $y = old_webfinger($webbie);
        if ($y) {
            logger('old_webfinger: ' . print_r($x, true));
            foreach ($y as $link) {
                if ($link['@attributes']['rel'] === NAMESPACE_DFRN) {
                    $dfrn = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'salmon') {
                    $notify = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === NAMESPACE_FEED) {
                    $poll = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://microformats.org/profile/hcard') {
                    $hcard = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://webfinger.net/rel/profile-page') {
                    $profile = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://portablecontacts.net/spec/1.0') {
                    $poco = unamp($link['@attributes']['href']);
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/seed_location') {
                    $diaspora_base = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'http://joindiaspora.com/guid') {
                    $diaspora_guid = unamp($link['@attributes']['href']);
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] === 'diaspora-public-key') {
                    $diaspora_key = base64_decode(unamp($link['@attributes']['href']));
                    if (strstr($diaspora_key, 'RSA ')) {
                        $pubkey = rsatopem($diaspora_key);
                    } else {
                        $pubkey = $diaspora_key;
                    }
                    $diaspora = true;
                }
                if ($link['@attributes']['rel'] == 'magic-public-key') {
                    if (substr($link['@attributes']['href'], 0, 5) === 'data:') {
                        $salmon_key = convert_salmon_key($link['@attributes']['href']);
                    }
                }
                if ($link['@attributes']['rel'] == 'salmon') {
                    $has_salmon = true;
                    $salmon = $link['@attributes']['href'];
                }
                if ($link['@attributes']['rel'] == 'http://schemas.google.com/g/2010#updates-from') {
                    $atom_feed = $link['@attributes']['href'];
                }
                if ($link['@attributes']['rel'] === 'alias') {
                    $aliases[] = $link['@attributes']['href'];
                }
                if ($link['@attributes']['rel'] === 'subject') {
                    $subject = $link['@attributes']['href'];
                }
            }
        }
    }
    if ($subject || $aliases) {
        if (strpos($webbie, '@')) {
            $rhs = substr($webbie, strpos($webbie, '@') + 1);
        } else {
            $m = parse_url($webbie);
            if ($m) {
                $rhs = $m['host'] . ($m['port'] ? ':' . $m['port'] : '');
            }
        }
        $v = array('subject' => $subject, 'aliases' => $aliases);
        $address = find_webfinger_address($v, $rhs);
        $location = find_webfinger_location($v, $rhs);
        if ($address) {
            $nickname = substr($address, 0, strpos($address, '@'));
        }
    }
    if ($salmon_key && $has_salmon && $atom_feed && !$dfrn && !$diaspora) {
        $gnusoc = true;
        $probe_atom = true;
    }
    if (!$pubkey) {
        $pubkey = $salmon_key;
    }
    if (($dfrn || $diaspora) && $hcard) {
        $probe_hcard = true;
    }
    if (!$fullname) {
        $fullname = $nickname;
    }
    if ($probe_atom) {
        $k = z_fetch_url($atom_feed);
        if ($k['success']) {
            $feed_meta = feed_meta($k['body']);
        }
        if ($feed_meta) {
            // stash any discovered pubsubhubbub hubs in case we need to follow them
            // this will save an expensive lookup later
            if ($feed_meta['hubs'] && $address) {
                set_xconfig($address, 'system', 'push_hubs', $feed_meta['hubs']);
                set_xconfig($address, 'system', 'feed_url', $atom_feed);
            }
            if ($feed_meta['author']['author_name']) {
                $fullname = $feed_meta['author']['author_name'];
            }
            if (!$avatar) {
                if ($feed_meta['author']['author_photo']) {
                    $avatar = $feed_meta['author']['author_photo'];
                }
            }
            // for GNU-social over-ride any url aliases we may have picked up in webfinger
            // The author.uri element in the feed is likely to be more accurate
            if ($gnusoc && $feed_meta['author']['author_uri']) {
                $location = $feed_meta['author']['author_uri'];
            }
        }
    } else {
        if ($probe_hcard) {
            $vcard = scrape_vcard($hcard);
            if ($vcard) {
                logger('vcard: ' . print_r($vcard, true), LOGGER_DATA);
                if ($vcard['fn']) {
                    $fullname = $vcard['fn'];
                }
                if ($vcard['photo'] && strpos($vcard['photo'], 'http') !== 0) {
                    $vcard['photo'] = $diaspora_base . '/' . $vcard['photo'];
                }
                if (!$avatar) {
                    $avatar = $vcard['photo'];
                }
            }
        }
    }
    if ($profile && !$location) {
        $location = $profile;
    }
    if ($location) {
        $m = parse_url($location);
        $base = $m['scheme'] . '://' . $m['host'];
        $host = $m['host'];
    }
    if ($diaspora && $diaspora_base && $diaspora_guid) {
        if ($dfrn) {
            $network = 'friendica-over-diaspora';
        } else {
            $network = 'diaspora';
        }
        $base = trim($diaspora_base, '/');
        $notify = $base . '/receive';
    } else {
        if ($gnusoc) {
            $network = 'gnusoc';
            $notify = $salmon;
        }
    }
    logger('network: ' . $network);
    logger('address: ' . $address);
    logger('fullname: ' . $fullname);
    logger('pubkey: ' . $pubkey);
    logger('location: ' . $location);
    // if we have everything we need, let's create the records
    if ($network && $address && $fullname && $pubkey && $location) {
        $r = q("select * from xchan where xchan_hash = '%s' limit 1", dbesc($address));
        if ($r) {
            $r = q("update xchan set xchan_name = '%s', xchan_network = '%s', xchan_name_date = '%s' where xchan_hash = '%s' limit 1", dbesc($fullname), dbesc($network), dbesc(datetime_convert()), dbesc($address));
        } else {
            $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_pubkey, xchan_addr, xchan_url, xchan_name, xchan_network, xchan_name_date ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s') ", dbesc($address), dbesc($diaspora_guid ? $diaspora_guid : $location), dbesc($pubkey), dbesc($address), dbesc($location), dbesc($fullname), dbesc($network), dbescdate(datetime_convert()));
        }
        $r = q("select * from hubloc where hubloc_hash = '%s' limit 1", dbesc($address));
        if (!$r) {
            $r = q("insert into hubloc ( hubloc_guid, hubloc_hash, hubloc_addr, hubloc_network, hubloc_url, hubloc_host, hubloc_callback, hubloc_updated, hubloc_primary ) values ('%s','%s','%s','%s','%s','%s','%s','%s', 1)", dbesc($diaspora_guid ? $diaspora_guid : $location), dbesc($address), dbesc($address), dbesc($network), dbesc($base), dbesc($host), dbesc($notify), dbescdate(datetime_convert()));
        }
        $photos = import_xchan_photo($avatar, $address);
        $r = q("update xchan set xchan_photo_date = '%s', xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s' where xchan_hash = '%s'", dbescdate(datetime_convert()), dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($address));
        return true;
    }
    return false;
}