public function file($str = '') { $this->load->library('EncryptionX', array(), 'encryption'); $this->encryption->key($this->config->item('encryption_key', 'app')); $expiryDate = date('D, d M Y H:i:s e', time() + 3600 * 24 * 30); header('Cache-Control: max-age=86400'); header('Expires: ' . $expiryDate); $nstr = explode('||', $this->encryption->decode(base64url_decode($str))); if (count($nstr) != 5) { return show_404(); } $size = $nstr[1] . 'x' . $nstr[2]; $type = $nstr[3]; $global = round($nstr[4]); $arrf = explode('/', $nstr[0]); if (count($arrf) != 3) { return show_404(); } $year = $arrf[0]; $month = $arrf[1]; $file = $arrf[2]; $this->load->config('app', TRUE); $folder = $this->config->item('uploads-global', 'app'); if (!$global || !$folder) { $folder = $this->config->item('uploads', 'app'); } $date_y = date('Y/m/d', strtotime("-1 day")); $filef = "{$folder}thumbs/{$date_y}/{$size}-{$file}"; $version = $this->config->item('upload-version', 'app') . '.' . date('H'); $mime = get_mime($filef); if ($mime) { header("Content-Type: {$mime}"); readfile($filef); exit; } $date = date('Y/m/d'); $filef = "{$folder}thumbs/{$date}/{$size}-{$file}"; $mime = get_mime($filef); if ($mime) { header("Content-Type: {$mime}"); readfile($filef); exit; } $thumbFolder = "{$folder}thumbs/{$date}/"; if (!is_dir($thumbFolder)) { mkdir($thumbFolder, 0777, true); } $this->load->library('image'); $fileb = "{$folder}{$year}/{$month}/{$file}"; if (!file_exists($fileb)) { return show_404(); } @unlink("{$folder}thumbs/{$date}/{$size}-{$file}"); $function = $type == 'thumb' ? 'resize' : 'resize_crop'; $this->image->load($fileb)->set_jpeg_quality(100)->{$function}($nstr[1], $nstr[2])->save("{$folder}thumbs/{$date}/{$size}-{$file}")->clear(); $mime = get_mime($filef); header("Content-Type: {$mime}"); readfile($filef); exit; }
function get() { if (!local_channel()) { killme(); } if (argc() > 2 && intval(argv(1)) && argv(2)) { $r = q("SELECT abook_xchan from abook where abook_xchan = '%s' and abook_channel = %d and abook_self = 0 limit 1", dbesc(base64url_decode(argv(2))), intval(local_channel())); if ($r) { $change = $r[0]['abook_xchan']; } } if (argc() > 1 && intval(argv(1))) { $r = q("SELECT * FROM `groups` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", intval(argv(1)), intval(local_channel())); if (!$r) { killme(); } $group = $r[0]; $members = group_get_members($group['id']); $preselected = array(); if (count($members)) { foreach ($members as $member) { $preselected[] = $member['xchan_hash']; } } if ($change) { if (in_array($change, $preselected)) { group_rmv_member(local_channel(), $group['gname'], $change); } else { group_add_member(local_channel(), $group['gname'], $change); } } } killme(); }
function post() { $hash = $_POST['hash']; $time = $_POST['time']; $sig = $_POST['signature']; $resource = $_POST['resource']; $revision = intval($_POST['revision']); if (!$hash) { killme(); } $channel = channelx_by_hash($hash); if (!$channel || !$time || !$sig) { killme(); } $slop = intval(get_pconfig($channel['channel_id'], 'system', 'getfile_time_slop')); if ($slop < 1) { $slop = 3; } $d1 = datetime_convert('UTC', 'UTC', "now + {$slop} minutes"); $d2 = datetime_convert('UTC', 'UTC', "now - {$slop} minutes"); if ($time > $d1 || $time < $d2) { logger('time outside allowable range'); killme(); } if (!rsa_verify($hash . '.' . $time, base64url_decode($sig), $channel['channel_pubkey'])) { logger('verify failed.'); killme(); } $r = attach_by_hash($resource, $revision); if (!$r['success']) { notice($r['message'] . EOL); return; } $unsafe_types = array('text/html', 'text/css', 'application/javascript'); if (in_array($r['data']['filetype'], $unsafe_types)) { header('Content-type: text/plain'); } else { header('Content-type: ' . $r['data']['filetype']); } header('Content-disposition: attachment; filename="' . $r['data']['filename'] . '"'); if (intval($r['data']['os_storage'])) { $fname = dbunescbin($r['data']['data']); if (strpos($fname, 'store') !== false) { $istream = fopen($fname, 'rb'); } else { $istream = fopen('store/' . $channel['channel_address'] . '/' . $fname, 'rb'); } $ostream = fopen('php://output', 'wb'); if ($istream && $ostream) { pipe_streams($istream, $ostream); fclose($istream); fclose($ostream); } } else { echo dbunescbin($r['data']['data']); } killme(); }
function oembed_content(&$a) { if ($a->argc == 2) { echo "<html><body>"; $url = base64url_decode($a->argv[1]); $j = oembed_fetch_url($url); echo $j->html; echo "</body></html>"; } killme(); }
public function import($id1_) { Logger::debug('main', "UserGroupDB::ldap_memberof::import (id = {$id1_})"); if (is_base64url($id1_)) { $id_ = base64url_decode($id1_); } else { $id_ = $id1_; } $prefs = Preferences::getInstance(); if (!$prefs) { die_error('get Preferences failed', __FILE__, __LINE__); } $config_ldap = $prefs->get('UserDB', 'ldap'); $config_ldap['match'] = array(); if (array_key_exists('match', $this->preferences)) { $config_ldap['match'] = $this->preferences['match']; } if (str_endswith(strtolower($id_), strtolower($config_ldap['suffix'])) === true) { $id2 = substr($id_, 0, -1 * strlen($config_ldap['suffix']) - 1); } else { $id2 = $id_; } $expl = explode(',', $id2, 2); if (count($expl) == 1) { $expl = array($id2, ''); } $config_ldap['userbranch'] = $expl[1]; $buf = $config_ldap['match']; $buf['id'] = $id_; $ldap = new LDAP($config_ldap); $sr = $ldap->search($expl[0], array_keys($config_ldap['match'])); if ($sr === false) { Logger::error('main', "UserGroupDB::ldap_memberof::import search failed for ({$id_})"); return NULL; } $infos = $ldap->get_entries($sr); if ($infos === array()) { Logger::error('main', "UserGroupDB::ldap_memberof::import get_entries failed for ({$id_})"); return NULL; } $keys = array_keys($infos); $dn = $keys[0]; $info = $infos[$dn]; foreach ($config_ldap['match'] as $attribut => $match_ldap) { if (isset($info[$match_ldap][0])) { $buf[$attribut] = $info[$match_ldap][0]; } } $ug = new UsersGroup($buf['id'], $buf['name'], $buf['description'], true); return $ug; }
function loadcomment($id, $number) { include '../page/protection.php'; include '../page/db.php'; $id = (int) base64url_decode($id); $sql = "SELECT * FROM Comments WHERE ID='{$id}'"; $data = mysqli_query($conn, $sql); $data = mysqli_fetch_assoc($data); $userid = $data['UserID']; $usersql = "SELECT UserName,ProfilePicture FROM UserAccounts WHERE RowID='{$userid}'"; $userdata = mysqli_query($conn, $usersql); $userdata = mysqli_fetch_assoc($userdata); $user = $userdata['UserName']; $comment = $data['Comment']; $space = " "; $postdate = date_create($data['CreateDate']); $postdate = date_format($postdate, 'm/d/Y g:ia'); $modifieddate = date_create($data['ModifiedDate']); $modifieddate = date_format($modifieddate, 'm/d/Y g:ia'); if ($userid === $_SESSION['id']) { $poster = "<span style=\"float:right;padding-right:10px;\" class=\"link2\"><a href=\"/admin/CommentDelete?a=" . base64url_encode($id) . "\">Delete</a></span>"; } if ($data['Edited']) { $time = "<span style=\"float:right;\">Edited: " . $modifieddate . "</span>"; } else { $time = "<span style=\"float:right;\">Posted: " . $postdate . "</span>"; } $text .= "\n\t\t\t<div class=\"commentshadow\" id=\"comment-{$id}\">\n\t\t\t<div class=\"commenttitle\">#{$number} " . $time . $poster . "</div>\n\t\t\t<div class=\"fullcomment\">\n\t\t\t<!--<hr class=\"commenthr\">-->\n\t\t\t<div class=\"commentimage\">\n\t\t"; $text .= "<div class=\"commentimageinner\"><span class=\"profilepichelper\"></span>"; if (strlen($userdata['ProfilePicture'])) { $text .= "<img src=\"/account/ProfilePictureShow?a=" . base64url_encode($userid) . "\" class=\"commentpic\">"; } else { $text .= "<img src=\"/theme/grey-question-mark.png\" class=\"commentpic hideLight\">"; $text .= "<img src=\"/theme/darkgrey-question-mark.png\" class=\"commentpic hideDark\">"; } $text .= "</div>"; $text .= "\n\t\t\t</div>\n\t\t\t\t<div class=\"commentusername\"><span class=\"link3\"><a href=\"/account/Profile?a=" . base64url_encode($userid) . "\">{$user}</a></span></div>\n\t\t"; include '../page/BBCode.php'; if (isset($comment)) { $comment = decrypt($comment); $comment = strip_tags($comment); $comment = preg_replace('/\\r\\n?/', "\n<br />", $comment); $comment = bb_parse($comment); } else { $comment = ''; } $text .= "<div class=\"comment\">" . $comment . "</div></div></div>"; mysqli_close($conn); return $text; }
public function import($id_) { if (is_base64url($id_)) { $id_ = base64url_decode($id_); } Logger::debug('main', 'UserGroupDB::import(' . $id_ . ')'); foreach ($this->instance_type as $key => $value) { if (str_startswith($id_, $key . '_')) { return $value->import(substr($id_, strlen($key) + 1)); } } return NULL; // not found }
/** * 处理上传 * * @access public */ public function process() { $param = Request::only('authkey', 'args'); $config = @unserialize(base64url_decode($param['args'])); $uploadObject = new UploadManager(); if (!$uploadObject->setParam($config)->checkUploadToken($param['authkey'])) { return abort(500); } $file = Request::file('file'); $returnFileUrl = $uploadObject->setFile($file)->upload(); if (!$returnFileUrl) { return abort(500); } $this->saveFile($returnFileUrl, $file); return response()->json(['file' => implode('|', $returnFileUrl)]); }
/** * 处理上传 */ public function process() { $parpams = Request::only('authkey', 'args'); $config = @unserialize(base64url_decode($parpams['args'])); //检测请求是否合法 $uploadObject = new UploadManager(); if (!$uploadObject->setParam($config)->checkUploadToken($parpams['authkey'])) { return abort(500); } //开始处理上传 $file = Request::file('file'); $returnFileUrl = $uploadObject->setFile($file)->upload(); if (!$returnFileUrl) { return abort(500); } return response()->json(['file' => $returnFileUrl]); }
function oembed_init(&$a) { // logger('mod_oembed ' . $a->query_string, LOGGER_ALL); if (argc() > 1) { if (argv(1) == 'b2h') { $url = array("", trim(hex2bin($_REQUEST['url']))); echo oembed_replacecb($url); killme(); } elseif (argv(1) == 'h2b') { $text = trim(hex2bin($_REQUEST['text'])); echo oembed_html2bbcode($text); killme(); } else { echo "<html><body>"; $j = oembed_fetch_url(base64url_decode(argv(1))); echo $j->html; // logger('mod-oembed ' . $j->html, LOGGER_ALL); echo "</body></html>"; } } killme(); }
/** * Update item by his id * @return void */ public function body() { //product id $id = $this->uri->segment(4); $email = base64url_decode($this->uri->segment(5)); $bodymail = $this->Imap_model->get_newsletter_email_by_email($email); $this->load->config('imap'); //echo '<pre>'; print_r($bodymail); die; $config['imap_server'] = $this->config->item('mailbox'); $config['imap_user'] = $bodymail[0]['email']; $config['imap_pass'] = decrypt($bodymail[0]['password']); $config['imap_folder'] = 'INBOX'; // Load the IMAP Library $this->Imap_model->imap($config); $body = $this->Imap_model->imap_read_body($id); //echo $body; die; $this->Imap_model->close_imap(); $data['email'] = $bodymail[0]['email']; $data['body'] = $body; $data['main_content'] = 'kd2a2a0u1g4/email_inbox/body'; $this->load->view('kd2a2a0u1g4/includes/template', $data); }
function oembed_content(&$a) { // logger('mod_oembed ' . $a->query_string, LOGGER_ALL); if ($a->argv[1] == 'b2h') { $url = array("", trim(hex2bin($_REQUEST['url']))); echo oembed_replacecb($url); killme(); } if ($a->argv[1] == 'h2b') { $text = trim(hex2bin($_REQUEST['text'])); echo oembed_html2bbcode($text); killme(); } if ($a->argc == 2) { echo "<html><body>"; $url = base64url_decode($a->argv[1]); $j = oembed_fetch_url($url); echo $j->html; // logger('mod-oembed ' . $j->html, LOGGER_ALL); echo "</body></html>"; } killme(); }
function init() { // logger('mod_oembed ' . \App::$query_string, LOGGER_ALL); if (argc() > 1) { if (argv(1) == 'b2h') { $url = array("", trim(hex2bin($_REQUEST['url']))); echo oembed_replacecb($url); killme(); } elseif (argv(1) == 'h2b') { $text = trim(hex2bin($_REQUEST['text'])); echo oembed_html2bbcode($text); killme(); } else { echo "<html><head><base target=\"_blank\" /></head><body>"; $src = base64url_decode(argv(1)); $j = oembed_fetch_url($src); echo $j['html']; // logger('mod-oembed ' . $h, LOGGER_ALL); echo "</body></html>"; } } killme(); }
function private_messages_fetch_conversation($channel_id, $messageitem_id, $updateseen = false) { // find the parent_mid of the message being requested $r = q("SELECT parent_mid from mail WHERE channel_id = %d and id = %d limit 1", intval($channel_id), intval($messageitem_id)); if (!$r) { return array(); } $messages = q("select * from mail where parent_mid = '%s' and channel_id = %d order by created asc", dbesc($r[0]['parent_mid']), intval($channel_id)); if (!$messages) { return array(); } $chans = array(); foreach ($messages as $rr) { $s = "'" . dbesc(trim($rr['from_xchan'])) . "'"; if (!in_array($s, $chans)) { $chans[] = $s; } $s = "'" . dbesc(trim($rr['to_xchan'])) . "'"; if (!in_array($s, $chans)) { $chans[] = $s; } } $c = q("select * from xchan where xchan_hash in (" . implode(',', $chans) . ")"); foreach ($messages as $k => $message) { $messages[$k]['from'] = find_xchan_in_array($message['from_xchan'], $c); $messages[$k]['to'] = find_xchan_in_array($message['to_xchan'], $c); if (intval($messages[$k]['mail_obscured'])) { if ($messages[$k]['title']) { $messages[$k]['title'] = base64url_decode(str_rot47($messages[$k]['title'])); } if ($messages[$k]['body']) { $messages[$k]['body'] = base64url_decode(str_rot47($messages[$k]['body'])); } } } if ($updateseen) { $r = q("UPDATE `mail` SET mail_seen = 1 where mail_seen = 0 and parent_mid = '%s' AND channel_id = %d", dbesc($r[0]['parent_mid']), intval($channel_id)); } return $messages; }
$system_conf->auth_type = 'none'; // avoid necessity to be logged in (not saved!) Minz_Translate::init('en'); Minz_Request::_param('ajax', true); $feedController = new FreshRSS_feed_Controller(); $simplePie = customSimplePie(); $simplePie->set_raw_data($ORIGINAL_INPUT); $simplePie->init(); unset($ORIGINAL_INPUT); $links = $simplePie->get_links('self'); $self = isset($links[0]) ? $links[0] : null; if ($self !== base64url_decode($canonical64)) { //header('HTTP/1.1 422 Unprocessable Entity'); logMe('Warning: Self URL [' . $self . '] does not match registered canonical URL!: ' . base64url_decode($canonical64)); //die('Self URL does not match registered canonical URL!'); $self = base64url_decode($canonical64); } Minz_Request::_param('url', $self); $nb = 0; foreach ($users as $userFilename) { $username = basename($userFilename, '.txt'); if (!file_exists(USERS_PATH . '/' . $username . '/config.php')) { break; } try { Minz_Session::_param('currentUser', $username); Minz_Configuration::register('user', join_path(USERS_PATH, $username, 'config.php'), join_path(USERS_PATH, '_', 'config.default.php')); FreshRSS_Context::init(); if ($feedController->actualizeAction($simplePie) > 0) { $nb++; }
function unobscure_mail(&$item) { if (array_key_exists('mail_obscured', $item) && intval($item['mail_obscured'])) { if ($item['title']) { $item['title'] = base64url_decode(str_rot47($item['title'])); } if ($item['body']) { $item['body'] = base64url_decode(str_rot47($item['body'])); } } }
list($junk, $authStr) = explode("result=", $value); $kidB64 = strtok($authStr, "."); $chalB64 = strtok("."); $nonceB64 = strtok("."); $sig = base64url_decode(strtok(".")); } } //dump("kidB64:" . $kidB64 . " chalB64:" . $chalB64 . " nonceB64:" . $nonceB64 ." sig:" . $sig); if (checkChal($chalB64, getPeer())) { dump("HOBA: Challenge accepted"); } else { dump("HOBA: Challenge failed"); setFailCookie(); exit(1); } $kid = base64url_decode($kidB64); $tbsOrigin = "https://" . $_SERVER['SERVER_NAME'] . ":" . $_SERVER['SERVER_PORT']; $sigText = genTbsBlob($nonceB64, $GLOBALS['alg'], $tbsOrigin, $kidB64, $chalB64); dbLogin(); $device = dbGetDeviceByKid($kid); if (!$device) { dump("HOBA: kid not found"); setFailCookie(); dbLogout(); exit(1); } $pem = jwkToPem($device['pubKey']); $verified = openssl_verify($sigText, $sig, $pem, OPENSSL_ALGO_SHA256); if ($verified) { dump("HOBA: Key Verification Successful"); $user = dbGetDeviceByKid($kid);
function zfinger_init(&$a) { require_once 'include/zot.php'; require_once 'include/crypto.php'; $ret = array('success' => false); $zhash = x($_REQUEST, 'guid_hash') ? $_REQUEST['guid_hash'] : ''; $zguid = x($_REQUEST, 'guid') ? $_REQUEST['guid'] : ''; $zguid_sig = x($_REQUEST, 'guid_sig') ? $_REQUEST['guid_sig'] : ''; $zaddr = x($_REQUEST, 'address') ? $_REQUEST['address'] : ''; $ztarget = x($_REQUEST, 'target') ? $_REQUEST['target'] : ''; $zsig = x($_REQUEST, 'target_sig') ? $_REQUEST['target_sig'] : ''; $zkey = x($_REQUEST, 'key') ? $_REQUEST['key'] : ''; $mindate = x($_REQUEST, 'mindate') ? $_REQUEST['mindate'] : ''; $feed = x($_REQUEST, 'feed') ? intval($_REQUEST['feed']) : 0; if ($ztarget) { if (!$zkey || !$zsig || !rsa_verify($ztarget, base64url_decode($zsig), $zkey)) { logger('zfinger: invalid target signature'); $ret['message'] = t("invalid target signature"); json_return_and_die($ret); } } // allow re-written domains so bob@foo.example.com can provide an address of bob@example.com // The top-level domain also needs to redirect .well-known/zot-info to the sub-domain with a 301 or 308 // TODO: Make 308 work in include/network.php for zot_fetch_url and zot_post_url if ($zaddr && ($s = get_config('system', 'zotinfo_domainrewrite'))) { $arr = explode('^', $s); if (count($arr) == 2) { $zaddr = str_replace($arr[0], $arr[1], $zaddr); } } $r = null; if (strlen($zhash)) { $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash \n\t\t\twhere channel_hash = '%s' limit 1", dbesc($zhash)); } elseif (strlen($zguid) && strlen($zguid_sig)) { $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash \n\t\t\twhere channel_guid = '%s' and channel_guid_sig = '%s' limit 1", dbesc($zguid), dbesc($zguid_sig)); } elseif (strlen($zaddr)) { if (strpos($zaddr, '[system]') === false) { /* normal address lookup */ $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash\n\t\t\t\twhere ( channel_address = '%s' or xchan_addr = '%s' ) limit 1", dbesc($zaddr), dbesc($zaddr)); } else { /** * The special address '[system]' will return a system channel if one has been defined, * Or the first valid channel we find if there are no system channels. * * This is used by magic-auth if we have no prior communications with this site - and * returns an identity on this site which we can use to create a valid hub record so that * we can exchange signed messages. The precise identity is irrelevant. It's the hub * information that we really need at the other end - and this will return it. * */ $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash\n\t\t\t\twhere ( channel_pageflags & %d )>0 order by channel_id limit 1", intval(PAGE_SYSTEM)); if (!$r) { $r = q("select channel.*, xchan.* from channel left join xchan on channel_hash = xchan_hash\n\t\t\t\t\twhere not ( channel_pageflags & %d )>0 order by channel_id limit 1", intval(PAGE_REMOVED)); } } } else { $ret['message'] = 'Invalid request'; json_return_and_die($ret); } if (!$r) { $ret['message'] = 'Item not found.'; json_return_and_die($ret); } $e = $r[0]; $id = $e['channel_id']; $sys_channel = $e['channel_pageflags'] & PAGE_SYSTEM ? true : false; $special_channel = $e['channel_pageflags'] & PAGE_PREMIUM ? true : false; $adult_channel = $e['channel_pageflags'] & PAGE_ADULT ? true : false; $censored = $e['channel_pageflags'] & PAGE_CENSORED ? true : false; $searchable = $e['channel_pageflags'] & PAGE_HIDDEN ? false : true; $deleted = $e['xchan_flags'] & XCHAN_FLAGS_DELETED ? true : false; if ($deleted || $censored || $sys_channel) { $searchable = false; } $public_forum = false; $role = get_pconfig($e['channel_id'], 'system', 'permissions_role'); if ($role === 'forum') { $public_forum = true; } else { // check if it has characteristics of a public forum based on custom permissions. $t = q("select abook_my_perms from abook where abook_channel = %d and (abook_flags & %d)>0 limit 1", intval($e['channel_id']), intval(ABOOK_FLAG_SELF)); if ($t && $t[0]['abook_my_perms'] & PERMS_W_TAGWALL) { $public_forum = true; } } // This is for birthdays and keywords, but must check access permissions $p = q("select * from profile where uid = %d and is_default = 1", intval($e['channel_id'])); $profile = array(); if ($p) { if (!intval($p[0]['publish'])) { $searchable = false; } $profile['description'] = $p[0]['pdesc']; $profile['birthday'] = $p[0]['dob']; if ($profile['birthday'] != '0000-00-00' && ($bd = z_birthday($p[0]['dob'], $e['channel_timezone'])) !== '') { $profile['next_birthday'] = $bd; } if ($age = age($p[0]['dob'], $e['channel_timezone'], '')) { $profile['age'] = $age; } $profile['gender'] = $p[0]['gender']; $profile['marital'] = $p[0]['marital']; $profile['sexual'] = $p[0]['sexual']; $profile['locale'] = $p[0]['locality']; $profile['region'] = $p[0]['region']; $profile['postcode'] = $p[0]['postal_code']; $profile['country'] = $p[0]['country_name']; $profile['about'] = $p[0]['about']; $profile['homepage'] = $p[0]['homepage']; $profile['hometown'] = $p[0]['hometown']; if ($p[0]['keywords']) { $tags = array(); $k = explode(' ', $p[0]['keywords']); if ($k) { foreach ($k as $kk) { if (trim($kk, " \t\n\r\v,")) { $tags[] = trim($kk, " \t\n\r\v,"); } } } if ($tags) { $profile['keywords'] = $tags; } } } $ret['success'] = true; // Communication details $ret['guid'] = $e['xchan_guid']; $ret['guid_sig'] = $e['xchan_guid_sig']; $ret['key'] = $e['xchan_pubkey']; $ret['name'] = $e['xchan_name']; $ret['name_updated'] = $e['xchan_name_date']; $ret['address'] = $e['xchan_addr']; $ret['photo_mimetype'] = $e['xchan_photo_mimetype']; $ret['photo'] = $e['xchan_photo_l']; $ret['photo_updated'] = $e['xchan_photo_date']; $ret['url'] = $e['xchan_url']; $ret['connections_url'] = $e['xchan_connurl'] ? $e['xchan_connurl'] : z_root() . '/poco/' . $e['channel_address']; $ret['target'] = $ztarget; $ret['target_sig'] = $zsig; $ret['searchable'] = $searchable; $ret['adult_content'] = $adult_channel; $ret['public_forum'] = $public_forum; if ($deleted) { $ret['deleted'] = $deleted; } // premium or other channel desiring some contact with potential followers before connecting. // This is a template - %s will be replaced with the follow_url we discover for the return channel. if ($special_channel) { $ret['connect_url'] = z_root() . '/connect/' . $e['channel_address']; } // This is a template for our follow url, %s will be replaced with a webbie $ret['follow_url'] = z_root() . '/follow?f=&url=%s'; $ztarget_hash = $ztarget && $zsig ? make_xchan_hash($ztarget, $zsig) : ''; $permissions = get_all_perms($e['channel_id'], $ztarget_hash, false); if ($ztarget_hash) { $permissions['connected'] = false; $b = q("select * from abook where abook_xchan = '%s' and abook_channel = %d limit 1", dbesc($ztarget_hash), intval($e['channel_id'])); if ($b) { $permissions['connected'] = true; } } $ret['permissions'] = $ztarget && $zkey ? crypto_encapsulate(json_encode($permissions), $zkey) : $permissions; if ($permissions['view_profile']) { $ret['profile'] = $profile; } // array of (verified) hubs this channel uses $x = zot_encode_locations($e); if ($x) { $ret['locations'] = $x; } $ret['site'] = array(); $ret['site']['url'] = z_root(); $ret['site']['url_sig'] = base64url_encode(rsa_sign(z_root(), $e['channel_prvkey'])); $dirmode = get_config('system', 'directory_mode'); if ($dirmode === false || $dirmode == DIRECTORY_MODE_NORMAL) { $ret['site']['directory_mode'] = 'normal'; } if ($dirmode == DIRECTORY_MODE_PRIMARY) { $ret['site']['directory_mode'] = 'primary'; } elseif ($dirmode == DIRECTORY_MODE_SECONDARY) { $ret['site']['directory_mode'] = 'secondary'; } elseif ($dirmode == DIRECTORY_MODE_STANDALONE) { $ret['site']['directory_mode'] = 'standalone'; } if ($dirmode != DIRECTORY_MODE_NORMAL) { $ret['site']['directory_url'] = z_root() . '/dirsearch'; } // hide detailed site information if you're off the grid if ($dirmode != DIRECTORY_MODE_STANDALONE) { $register_policy = intval(get_config('system', 'register_policy')); if ($register_policy == REGISTER_CLOSED) { $ret['site']['register_policy'] = 'closed'; } if ($register_policy == REGISTER_APPROVE) { $ret['site']['register_policy'] = 'approve'; } if ($register_policy == REGISTER_OPEN) { $ret['site']['register_policy'] = 'open'; } $access_policy = intval(get_config('system', 'access_policy')); if ($access_policy == ACCESS_PRIVATE) { $ret['site']['access_policy'] = 'private'; } if ($access_policy == ACCESS_PAID) { $ret['site']['access_policy'] = 'paid'; } if ($access_policy == ACCESS_FREE) { $ret['site']['access_policy'] = 'free'; } if ($access_policy == ACCESS_TIERED) { $ret['site']['access_policy'] = 'tiered'; } $ret['site']['accounts'] = account_total(); require_once 'include/identity.php'; $ret['site']['channels'] = channel_total(); $ret['site']['version'] = PLATFORM_NAME . ' ' . RED_VERSION . '[' . DB_UPDATE_VERSION . ']'; $ret['site']['admin'] = get_config('system', 'admin_email'); $visible_plugins = array(); if (is_array($a->plugins) && count($a->plugins)) { $r = q("select * from addon where hidden = 0"); if ($r) { foreach ($r as $rr) { $visible_plugins[] = $rr['name']; } } } $ret['site']['plugins'] = $visible_plugins; $ret['site']['sitehash'] = get_config('system', 'location_hash'); $ret['site']['sitename'] = get_config('system', 'sitename'); $ret['site']['sellpage'] = get_config('system', 'sellpage'); $ret['site']['location'] = get_config('system', 'site_location'); $ret['site']['realm'] = get_directory_realm(); } call_hooks('zot_finger', $ret); json_return_and_die($ret); }
/** * @param $jwt string encoded JWT * @param int $section the section we would like to decode * @return object */ private function decodeJWT($jwt, $section = 0) { $parts = explode(".", $jwt); return json_decode(base64url_decode($parts[$section])); }
function import_account($account_id) { if (!$account_id) { logger("import_account: No account ID supplied"); return; } $max_identities = account_service_class_fetch($account_id, 'total_identities'); $max_friends = account_service_class_fetch($account_id, 'total_channels'); $max_feeds = account_service_class_fetch($account_id, 'total_feeds'); if ($max_identities !== false) { $r = q("select channel_id from channel where channel_account_id = %d", intval($account_id)); if ($r && count($r) > $max_identities) { notice(sprintf(t('Your service plan only allows %d channels.'), $max_identities) . EOL); return; } } $data = null; $seize = x($_REQUEST, 'make_primary') ? intval($_REQUEST['make_primary']) : 0; $import_posts = x($_REQUEST, 'import_posts') ? intval($_REQUEST['import_posts']) : 0; $src = $_FILES['filename']['tmp_name']; $filename = basename($_FILES['filename']['name']); $filesize = intval($_FILES['filename']['size']); $filetype = $_FILES['filename']['type']; $completed = array_key_exists('import_step', $_SESSION) ? intval($_SESSION['import_step']) : 0; if ($completed) { logger('saved import step: ' . $_SESSION['import_step']); } if ($src) { // This is OS specific and could also fail if your tmpdir isn't very large // mostly used for Diaspora which exports gzipped files. if (strpos($filename, '.gz')) { @rename($src, $src . '.gz'); @system('gunzip ' . escapeshellarg($src . '.gz')); } if ($filesize) { $data = @file_get_contents($src); } unlink($src); } if (!$src) { $old_address = x($_REQUEST, 'old_address') ? $_REQUEST['old_address'] : ''; if (!$old_address) { logger('mod_import: nothing to import.'); notice(t('Nothing to import.') . EOL); return; } $email = x($_REQUEST, 'email') ? $_REQUEST['email'] : ''; $password = x($_REQUEST, 'password') ? $_REQUEST['password'] : ''; $channelname = substr($old_address, 0, strpos($old_address, '@')); $servername = substr($old_address, strpos($old_address, '@') + 1); $scheme = 'https://'; $api_path = '/api/red/channel/export/basic?f=&channel=' . $channelname; if ($import_posts) { $api_path .= '&posts=1'; } $binary = false; $redirects = 0; $opts = array('http_auth' => $email . ':' . $password); $url = $scheme . $servername . $api_path; $ret = z_fetch_url($url, $binary, $redirects, $opts); if (!$ret['success']) { $ret = z_fetch_url('http://' . $servername . $api_path, $binary, $redirects, $opts); } if ($ret['success']) { $data = $ret['body']; } else { notice(t('Unable to download data from old server') . EOL); } } if (!$data) { logger('mod_import: empty file.'); notice(t('Imported file is empty.') . EOL); return; } $data = json_decode($data, true); // logger('import: data: ' . print_r($data,true)); // print_r($data); if (array_key_exists('user', $data) && array_key_exists('version', $data)) { require_once 'include/Import/import_diaspora.php'; import_diaspora($data); return; } $moving = false; if (array_key_exists('compatibility', $data) && array_key_exists('database', $data['compatibility'])) { $v1 = substr($data['compatibility']['database'], -4); $v2 = substr(DB_UPDATE_VERSION, -4); if ($v2 > $v1) { $t = sprintf(t('Warning: Database versions differ by %1$d updates.'), $v2 - $v1); notice($t); } if (array_key_exists('server_role', $data['compatibility']) && $data['compatibility']['server_role'] == 'basic') { $moving = true; } } if ($moving) { $seize = 1; } // import channel $relocate = array_key_exists('relocate', $data) ? $data['relocate'] : null; if (array_key_exists('channel', $data)) { if ($completed < 1) { $channel = import_channel($data['channel'], $account_id, $seize); } else { $r = q("select * from channel where channel_account_id = %d and channel_guid = '%s' limit 1", intval($account_id), dbesc($channel['channel_guid'])); if ($r) { $channel = $r[0]; } } if (!$channel) { logger('mod_import: channel not found. ', print_r($channel, true)); notice(t('Cloned channel not found. Import failed.') . EOL); return; } } if (!$channel) { $channel = \App::get_channel(); } if (!$channel) { logger('mod_import: channel not found. ', print_r($channel, true)); notice(t('No channel. Import failed.') . EOL); return; } if ($completed < 2) { if (is_array($data['config'])) { import_config($channel, $data['config']); } logger('import step 2'); $_SESSION['import_step'] = 2; } if ($completed < 3) { if ($data['photo']) { require_once 'include/photo/photo_driver.php'; import_channel_photo(base64url_decode($data['photo']['data']), $data['photo']['type'], $account_id, $channel['channel_id']); } if (is_array($data['profile'])) { import_profiles($channel, $data['profile']); } logger('import step 3'); $_SESSION['import_step'] = 3; } if ($completed < 4) { if (is_array($data['hubloc']) && !$moving) { import_hublocs($channel, $data['hubloc'], $seize); } logger('import step 4'); $_SESSION['import_step'] = 4; } if ($completed < 5) { // create new hubloc for the new channel at this site $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_network, hubloc_primary, \n\t\t\t\thubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey )\n\t\t\t\tvalues ( '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s' )", dbesc($channel['channel_guid']), dbesc($channel['channel_guid_sig']), dbesc($channel['channel_hash']), dbesc(channel_reddress($channel)), dbesc('zot'), intval($seize ? 1 : 0), dbesc(z_root()), dbesc(base64url_encode(rsa_sign(z_root(), $channel['channel_prvkey']))), dbesc(\App::get_hostname()), dbesc(z_root() . '/post'), dbesc(get_config('system', 'pubkey'))); // reset the original primary hubloc if it is being seized if ($seize) { $r = q("update hubloc set hubloc_primary = 0 where hubloc_primary = 1 and hubloc_hash = '%s' and hubloc_url != '%s' ", dbesc($channel['channel_hash']), dbesc(z_root())); } logger('import step 5'); $_SESSION['import_step'] = 5; } if ($completed < 6) { // import xchans and contact photos if ($seize) { // replace any existing xchan we may have on this site if we're seizing control $r = q("delete from xchan where xchan_hash = '%s'", dbesc($channel['channel_hash'])); $r = q("insert into xchan ( xchan_hash, xchan_guid, xchan_guid_sig, xchan_pubkey, xchan_photo_l, xchan_photo_m, xchan_photo_s, xchan_addr, xchan_url, xchan_follow, xchan_connurl, xchan_name, xchan_network, xchan_photo_date, xchan_name_date, xchan_hidden, xchan_orphan, xchan_censored, xchan_selfcensored, xchan_system, xchan_pubforum, xchan_deleted ) values ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d, %d, %d, %d, %d, %d )", dbesc($channel['channel_hash']), dbesc($channel['channel_guid']), dbesc($channel['channel_guid_sig']), dbesc($channel['channel_pubkey']), dbesc(z_root() . "/photo/profile/l/" . $channel['channel_id']), dbesc(z_root() . "/photo/profile/m/" . $channel['channel_id']), dbesc(z_root() . "/photo/profile/s/" . $channel['channel_id']), dbesc(channel_reddress($channel)), dbesc(z_root() . '/channel/' . $channel['channel_address']), dbesc(z_root() . '/follow?f=&url=%s'), dbesc(z_root() . '/poco/' . $channel['channel_address']), dbesc($channel['channel_name']), dbesc('zot'), dbesc(datetime_convert()), dbesc(datetime_convert()), 0, 0, 0, 0, 0, 0, 0); } logger('import step 6'); $_SESSION['import_step'] = 6; } if ($completed < 7) { $xchans = $data['xchan']; if ($xchans) { foreach ($xchans as $xchan) { $hash = make_xchan_hash($xchan['xchan_guid'], $xchan['xchan_guid_sig']); if ($xchan['xchan_network'] === 'zot' && $hash !== $xchan['xchan_hash']) { logger('forged xchan: ' . print_r($xchan, true)); continue; } if (!array_key_exists('xchan_hidden', $xchan)) { $xchan['xchan_hidden'] = $xchan['xchan_flags'] & 0x1 ? 1 : 0; $xchan['xchan_orphan'] = $xchan['xchan_flags'] & 0x2 ? 1 : 0; $xchan['xchan_censored'] = $xchan['xchan_flags'] & 0x4 ? 1 : 0; $xchan['xchan_selfcensored'] = $xchan['xchan_flags'] & 0x8 ? 1 : 0; $xchan['xchan_system'] = $xchan['xchan_flags'] & 0x10 ? 1 : 0; $xchan['xchan_pubforum'] = $xchan['xchan_flags'] & 0x20 ? 1 : 0; $xchan['xchan_deleted'] = $xchan['xchan_flags'] & 0x1000 ? 1 : 0; } $r = q("select xchan_hash from xchan where xchan_hash = '%s' limit 1", dbesc($xchan['xchan_hash'])); if ($r) { continue; } dbesc_array($xchan); $r = dbq("INSERT INTO xchan (`" . implode("`, `", array_keys($xchan)) . "`) VALUES ('" . implode("', '", array_values($xchan)) . "')"); require_once 'include/photo/photo_driver.php'; $photos = import_xchan_photo($xchan['xchan_photo_l'], $xchan['xchan_hash']); if ($photos[4]) { $photodate = NULL_DATE; } else { $photodate = $xchan['xchan_photo_date']; } $r = q("update xchan set xchan_photo_l = '%s', xchan_photo_m = '%s', xchan_photo_s = '%s', xchan_photo_mimetype = '%s', xchan_photo_date = '%s'\n\t\t\t\t\t\twhere xchan_hash = '%s'", dbesc($photos[0]), dbesc($photos[1]), dbesc($photos[2]), dbesc($photos[3]), dbesc($photodate), dbesc($xchan['xchan_hash'])); } } logger('import step 7'); $_SESSION['import_step'] = 7; } // FIXME - ensure we have an xchan if somebody is trying to pull a fast one if ($completed < 8) { $friends = 0; $feeds = 0; // import contacts $abooks = $data['abook']; if ($abooks) { foreach ($abooks as $abook) { $abook_copy = $abook; $abconfig = null; if (array_key_exists('abconfig', $abook) && is_array($abook['abconfig']) && count($abook['abconfig'])) { $abconfig = $abook['abconfig']; } unset($abook['abook_id']); unset($abook['abook_rating']); unset($abook['abook_rating_text']); unset($abook['abconfig']); unset($abook['abook_their_perms']); unset($abook['abook_my_perms']); $abook['abook_account'] = $account_id; $abook['abook_channel'] = $channel['channel_id']; if (!array_key_exists('abook_blocked', $abook)) { $abook['abook_blocked'] = $abook['abook_flags'] & 0x1 ? 1 : 0; $abook['abook_ignored'] = $abook['abook_flags'] & 0x2 ? 1 : 0; $abook['abook_hidden'] = $abook['abook_flags'] & 0x4 ? 1 : 0; $abook['abook_archived'] = $abook['abook_flags'] & 0x8 ? 1 : 0; $abook['abook_pending'] = $abook['abook_flags'] & 0x10 ? 1 : 0; $abook['abook_unconnected'] = $abook['abook_flags'] & 0x20 ? 1 : 0; $abook['abook_self'] = $abook['abook_flags'] & 0x80 ? 1 : 0; $abook['abook_feed'] = $abook['abook_flags'] & 0x100 ? 1 : 0; } if ($abook['abook_self']) { $role = get_pconfig($channel['channel_id'], 'system', 'permissions_role'); if ($role === 'forum' || $abook['abook_my_perms'] & PERMS_W_TAGWALL) { q("update xchan set xchan_pubforum = 1 where xchan_hash = '%s' ", dbesc($abook['abook_xchan'])); } } else { if ($max_friends !== false && $friends > $max_friends) { continue; } if ($max_feeds !== false && intval($abook['abook_feed']) && $feeds > $max_feeds) { continue; } } dbesc_array($abook); $r = dbq("INSERT INTO abook (`" . implode("`, `", array_keys($abook)) . "`) VALUES ('" . implode("', '", array_values($abook)) . "')"); $friends++; if (intval($abook['abook_feed'])) { $feeds++; } translate_abook_perms_inbound($channel, $abook_copy); if ($abconfig) { // @fixme does not handle sync of del_abconfig foreach ($abconfig as $abc) { set_abconfig($channel['channel_id'], $abc['xchan'], $abc['cat'], $abc['k'], $abc['v']); } } } } logger('import step 8'); $_SESSION['import_step'] = 8; } if ($completed < 9) { $groups = $data['group']; if ($groups) { $saved = array(); foreach ($groups as $group) { $saved[$group['hash']] = array('old' => $group['id']); if (array_key_exists('name', $group)) { $group['gname'] = $group['name']; unset($group['name']); } unset($group['id']); $group['uid'] = $channel['channel_id']; dbesc_array($group); $r = dbq("INSERT INTO groups (`" . implode("`, `", array_keys($group)) . "`) VALUES ('" . implode("', '", array_values($group)) . "')"); } $r = q("select * from `groups` where uid = %d", intval($channel['channel_id'])); if ($r) { foreach ($r as $rr) { $saved[$rr['hash']]['new'] = $rr['id']; } } } $group_members = $data['group_member']; if ($group_members) { foreach ($group_members as $group_member) { unset($group_member['id']); $group_member['uid'] = $channel['channel_id']; foreach ($saved as $x) { if ($x['old'] == $group_member['gid']) { $group_member['gid'] = $x['new']; } } dbesc_array($group_member); $r = dbq("INSERT INTO group_member (`" . implode("`, `", array_keys($group_member)) . "`) VALUES ('" . implode("', '", array_values($group_member)) . "')"); } } logger('import step 9'); $_SESSION['import_step'] = 9; } if (is_array($data['obj'])) { import_objs($channel, $data['obj']); } if (is_array($data['likes'])) { import_likes($channel, $data['likes']); } if (is_array($data['app'])) { import_apps($channel, $data['app']); } if (is_array($data['chatroom'])) { import_chatrooms($channel, $data['chatroom']); } if (is_array($data['conv'])) { import_conv($channel, $data['conv']); } if (is_array($data['mail'])) { import_mail($channel, $data['mail']); } if (is_array($data['event'])) { import_events($channel, $data['event']); } if (is_array($data['event_item'])) { import_items($channel, $data['event_item'], false, $relocate); } if (is_array($data['menu'])) { import_menus($channel, $data['menu']); } $addon = array('channel' => $channel, 'data' => $data); call_hooks('import_channel', $addon); $saved_notification_flags = notifications_off($channel['channel_id']); if ($import_posts && array_key_exists('item', $data) && $data['item']) { import_items($channel, $data['item'], false, $relocate); } notifications_on($channel['channel_id'], $saved_notification_flags); if (array_key_exists('item_id', $data) && $data['item_id']) { import_item_ids($channel, $data['item_id']); } // FIXME - ensure we have a self entry if somebody is trying to pull a fast one // send out refresh requests // notify old server that it may no longer be primary. \Zotlabs\Daemon\Master::Summon(array('Notifier', 'location', $channel['channel_id'])); // This will indirectly perform a refresh_all *and* update the directory \Zotlabs\Daemon\Master::Summon(array('Directory', $channel['channel_id'])); notice(t('Import completed.') . EOL); change_channel($channel['channel_id']); unset($_SESSION['import_step']); goaway(z_root() . '/network'); }
/** * * diaspora_decode($importer,$xml) * array $importer -> from user table * string $xml -> urldecoded Diaspora salmon * * Returns array * 'message' -> decoded Diaspora XML message * 'author' -> author diaspora handle * 'key' -> author public key (converted to pkcs#8) * * Author and key are used elsewhere to save a lookup for verifying replies and likes */ function diaspora_decode($importer, $xml) { $public = false; $basedom = parse_xml_string($xml); $children = $basedom->children('https://joindiaspora.com/protocol'); if ($children->header) { $public = true; $author_link = str_replace('acct:', '', $children->header->author_id); } else { $encrypted_header = json_decode(base64_decode($children->encrypted_header)); $encrypted_aes_key_bundle = base64_decode($encrypted_header->aes_key); $ciphertext = base64_decode($encrypted_header->ciphertext); $outer_key_bundle = ''; openssl_private_decrypt($encrypted_aes_key_bundle, $outer_key_bundle, $importer['prvkey']); $j_outer_key_bundle = json_decode($outer_key_bundle); $outer_iv = base64_decode($j_outer_key_bundle->iv); $outer_key = base64_decode($j_outer_key_bundle->key); $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $outer_key, $ciphertext, MCRYPT_MODE_CBC, $outer_iv); $decrypted = pkcs5_unpad($decrypted); /** * $decrypted now contains something like * * <decrypted_header> * <iv>8e+G2+ET8l5BPuW0sVTnQw==</iv> * <aes_key>UvSMb4puPeB14STkcDWq+4QE302Edu15oaprAQSkLKU=</aes_key> ***** OBSOLETE * <author> * <name>Ryan Hughes</name> * <uri>acct:galaxor@diaspora.pirateship.org</uri> * </author> ***** CURRENT * <author_id>galaxor@diaspora.priateship.org</author_id> ***** END DIFFS * </decrypted_header> */ logger('decrypted: ' . $decrypted, LOGGER_DEBUG); $idom = parse_xml_string($decrypted, false); $inner_iv = base64_decode($idom->iv); $inner_aes_key = base64_decode($idom->aes_key); $author_link = str_replace('acct:', '', $idom->author_id); } $dom = $basedom->children(NAMESPACE_SALMON_ME); // figure out where in the DOM tree our data is hiding if ($dom->provenance->data) { $base = $dom->provenance; } elseif ($dom->env->data) { $base = $dom->env; } elseif ($dom->data) { $base = $dom; } if (!$base) { logger('mod-diaspora: unable to locate salmon data in xml '); http_status_exit(400); } // Stash the signature away for now. We have to find their key or it won't be good for anything. $signature = base64url_decode($base->sig); // unpack the data // strip whitespace so our data element will return to one big base64 blob $data = str_replace(array(" ", "\t", "\r", "\n"), array("", "", "", ""), $base->data); // stash away some other stuff for later $type = $base->data[0]->attributes()->type[0]; $keyhash = $base->sig[0]->attributes()->keyhash[0]; $encoding = $base->encoding; $alg = $base->alg; $signed_data = $data . '.' . base64url_encode($type) . '.' . base64url_encode($encoding) . '.' . base64url_encode($alg); // decode the data $data = base64url_decode($data); if ($public) { $inner_decrypted = $data; } else { // Decode the encrypted blob $inner_encrypted = base64_decode($data); $inner_decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $inner_aes_key, $inner_encrypted, MCRYPT_MODE_CBC, $inner_iv); $inner_decrypted = pkcs5_unpad($inner_decrypted); } if (!$author_link) { logger('mod-diaspora: Could not retrieve author URI.'); http_status_exit(400); } // Once we have the author URI, go to the web and try to find their public key // (first this will look it up locally if it is in the fcontact cache) // This will also convert diaspora public key from pkcs#1 to pkcs#8 logger('mod-diaspora: Fetching key for ' . $author_link); $key = get_diaspora_key($author_link); if (!$key) { logger('mod-diaspora: Could not retrieve author key.'); http_status_exit(400); } $verify = rsa_verify($signed_data, $signature, $key); if (!$verify) { logger('mod-diaspora: Message did not verify. Discarding.'); http_status_exit(400); } logger('mod-diaspora: Message verified.'); return array('message' => $inner_decrypted, 'author' => $author_link, 'key' => $key); }
function get() { $change = false; logger('mod_group: ' . \App::$cmd, LOGGER_DEBUG); if (!local_channel()) { notice(t('Permission denied') . EOL); return; } // Switch to text mode interface if we have more than 'n' contacts or group members $switchtotext = get_pconfig(local_channel(), 'system', 'groupedit_image_limit'); if ($switchtotext === false) { $switchtotext = get_config('system', 'groupedit_image_limit'); } if ($switchtotext === false) { $switchtotext = 400; } $tpl = get_markup_template('group_edit.tpl'); $context = array('$submit' => t('Submit')); if (argc() == 2 && argv(1) === 'new') { return replace_macros($tpl, $context + array('$title' => t('Create a group of channels.'), '$gname' => array('groupname', t('Privacy group name: '), '', ''), '$gid' => 'new', '$public' => array('public', t('Members are visible to other channels'), false, ''), '$form_security_token' => get_form_security_token("group_edit"))); } if (argc() == 3 && argv(1) === 'drop') { check_form_security_token_redirectOnErr('/group', 'group_drop', 't'); if (intval(argv(2))) { $r = q("SELECT `name` FROM `groups` WHERE `id` = %d AND `uid` = %d LIMIT 1", intval(argv(2)), intval(local_channel())); if ($r) { $result = group_rmv(local_channel(), $r[0]['gname']); } if ($result) { info(t('Privacy group removed.') . EOL); } else { notice(t('Unable to remove privacy group.') . EOL); } } goaway(z_root() . '/group'); // NOTREACHED } if (argc() > 2 && intval(argv(1)) && argv(2)) { check_form_security_token_ForbiddenOnErr('group_member_change', 't'); $r = q("SELECT abook_xchan from abook left join xchan on abook_xchan = xchan_hash where abook_xchan = '%s' and abook_channel = %d and xchan_deleted = 0 and abook_self = 0 and abook_blocked = 0 and abook_pending = 0 limit 1", dbesc(base64url_decode(argv(2))), intval(local_channel())); if (count($r)) { $change = base64url_decode(argv(2)); } } if (argc() > 1 && intval(argv(1))) { require_once 'include/acl_selectors.php'; $r = q("SELECT * FROM `groups` WHERE `id` = %d AND `uid` = %d AND `deleted` = 0 LIMIT 1", intval(argv(1)), intval(local_channel())); if (!$r) { notice(t('Privacy group not found.') . EOL); goaway(z_root() . '/connections'); } $group = $r[0]; $members = group_get_members($group['id']); $preselected = array(); if (count($members)) { foreach ($members as $member) { if (!in_array($member['xchan_hash'], $preselected)) { $preselected[] = $member['xchan_hash']; } } } if ($change) { if (in_array($change, $preselected)) { group_rmv_member(local_channel(), $group['gname'], $change); } else { group_add_member(local_channel(), $group['gname'], $change); } $members = group_get_members($group['id']); $preselected = array(); if (count($members)) { foreach ($members as $member) { $preselected[] = $member['xchan_hash']; } } } $drop_tpl = get_markup_template('group_drop.tpl'); $drop_txt = replace_macros($drop_tpl, array('$id' => $group['id'], '$delete' => t('Delete'), '$form_security_token' => get_form_security_token("group_drop"))); $context = $context + array('$title' => t('Privacy group editor'), '$gname' => array('groupname', t('Privacy group name: '), $group['gname'], ''), '$gid' => $group['id'], '$drop' => $drop_txt, '$public' => array('public', t('Members are visible to other channels'), $group['visible'], ''), '$form_security_token' => get_form_security_token('group_edit')); } if (!isset($group)) { return; } $groupeditor = array('label_members' => t('Members'), 'members' => array(), 'label_contacts' => t('All Connected Channels'), 'contacts' => array()); $sec_token = addslashes(get_form_security_token('group_member_change')); $textmode = $switchtotext && count($members) > $switchtotext ? true : false; foreach ($members as $member) { if ($member['xchan_url']) { $member['archived'] = intval($member['abook_archived']) ? true : false; $member['click'] = 'groupChangeMember(' . $group['id'] . ',\'' . base64url_encode($member['xchan_hash']) . '\',\'' . $sec_token . '\'); return false;'; $groupeditor['members'][] = micropro($member, true, 'mpgroup', $textmode); } else { group_rmv_member(local_channel(), $group['gname'], $member['xchan_hash']); } } $r = q("SELECT abook.*, xchan.* FROM `abook` left join xchan on abook_xchan = xchan_hash WHERE `abook_channel` = %d AND abook_self = 0 and abook_blocked = 0 and abook_pending = 0 and xchan_deleted = 0 order by xchan_name asc", intval(local_channel())); if (count($r)) { $textmode = $switchtotext && count($r) > $switchtotext ? true : false; foreach ($r as $member) { if (!in_array($member['xchan_hash'], $preselected)) { $member['archived'] = intval($member['abook_archived']) ? true : false; $member['click'] = 'groupChangeMember(' . $group['id'] . ',\'' . base64url_encode($member['xchan_hash']) . '\',\'' . $sec_token . '\'); return false;'; $groupeditor['contacts'][] = micropro($member, true, 'mpall', $textmode); } } } $context['$groupeditor'] = $groupeditor; $context['$desc'] = t('Click on a channel to add or remove.'); if ($change) { $tpl = get_markup_template('groupeditor.tpl'); echo replace_macros($tpl, $context); killme(); } return replace_macros($tpl, $context); }
/** * @brief Create an array representing the important channel information * which would be necessary to create a nomadic identity clone. This includes * most channel resources and connection information with the exception of content. * * @param int $channel_id * Channel_id to export * @param boolean $items * Include channel posts (wall items), default false * * @returns array * See function for details */ function identity_basic_export($channel_id, $items = false) { /* * Red basic channel export */ $ret = array(); $ret['compatibility'] = array('project' => PLATFORM_NAME, 'version' => RED_VERSION, 'database' => DB_UPDATE_VERSION); $r = q("select * from channel where channel_id = %d limit 1", intval($channel_id)); if ($r) { $ret['channel'] = $r[0]; } $r = q("select * from profile where uid = %d", intval($channel_id)); if ($r) { $ret['profile'] = $r; } $xchans = array(); $r = q("select * from abook where abook_channel = %d ", intval($channel_id)); if ($r) { $ret['abook'] = $r; foreach ($r as $rr) { $xchans[] = $rr['abook_xchan']; } stringify_array_elms($xchans); } if ($xchans) { $r = q("select * from xchan where xchan_hash in ( " . implode(',', $xchans) . " ) "); if ($r) { $ret['xchan'] = $r; } $r = q("select * from hubloc where hubloc_hash in ( " . implode(',', $xchans) . " ) "); if ($r) { $ret['hubloc'] = $r; } } $r = q("select * from `groups` where uid = %d ", intval($channel_id)); if ($r) { $ret['group'] = $r; } $r = q("select * from group_member where uid = %d ", intval($channel_id)); if ($r) { $ret['group_member'] = $r; } $r = q("select * from pconfig where uid = %d", intval($channel_id)); if ($r) { $ret['config'] = $r; } $r = q("select type, data, os_storage from photo where scale = 4 and profile = 1 and uid = %d limit 1", intval($channel_id)); if ($r) { $ret['photo'] = array('type' => $r[0]['type'], 'data' => $r[0]['os_storage'] ? base64url_encode(file_get_contents($r[0]['data'])) : base64url_encode($r[0]['data'])); } // All other term types will be included in items, if requested. $r = q("select * from term where type in (%d,%d) and uid = %d", intval(TERM_SAVEDSEARCH), intval(TERM_THING), intval($channel_id)); if ($r) { $ret['term'] = $r; } // add psuedo-column obj_baseurl to aid in relocations $r = q("select obj.*, '%s' as obj_baseurl from obj where obj_channel = %d", dbesc(z_root()), intval($channel_id)); if ($r) { $ret['obj'] = $r; } $r = q("select * from app where app_channel = %d", intval($channel_id)); if ($r) { $ret['app'] = $r; } $r = q("select * from chatroom where cr_uid = %d", intval($channel_id)); if ($r) { $ret['chatroom'] = $r; } $r = q("select * from event where uid = %d", intval($channel_id)); if ($r) { $ret['event'] = $r; } $r = q("select * from item where resource_type = 'event' and uid = %d", intval($channel_id)); if ($r) { $ret['event_item'] = array(); xchan_query($r); $r = fetch_post_tags($r, true); foreach ($r as $rr) { $ret['event_item'][] = encode_item($rr, true); } } $x = menu_list($channel_id); if ($x) { $ret['menu'] = array(); for ($y = 0; $y < count($x); $y++) { $m = menu_fetch($x[$y]['menu_name'], $channel_id, $ret['channel']['channel_hash']); if ($m) { $ret['menu'][] = menu_element($m); } } } $x = menu_list($channel_id); if ($x) { $ret['menu'] = array(); for ($y = 0; $y < count($x); $y++) { $m = menu_fetch($x[$y]['menu_name'], $channel_id, $ret['channel']['channel_hash']); if ($m) { $ret['menu'][] = menu_element($m); } } } $addon = array('channel_id' => $channel_id, 'data' => $ret); call_hooks('identity_basic_export', $addon); $ret = $addon['data']; if (!$items) { return $ret; } $r = q("select * from likes where channel_id = %d", intval($channel_id)); if ($r) { $ret['likes'] = $r; } $r = q("select * from conv where uid = %d", intval($channel_id)); if ($r) { for ($x = 0; $x < count($r); $x++) { $r[$x]['subject'] = base64url_decode(str_rot47($r[$x]['subject'])); } $ret['conv'] = $r; } $r = q("select * from mail where mail.uid = %d", intval($channel_id)); if ($r) { $m = array(); foreach ($r as $rr) { xchan_mail_query($rr); $m[] = mail_encode($rr, true); } $ret['mail'] = $m; } $r = q("select item_id.*, item.mid from item_id left join item on item_id.iid = item.id where item_id.uid = %d", intval($channel_id)); if ($r) { $ret['item_id'] = $r; } //$key = get_config('system','prvkey'); /** @warning this may run into memory limits on smaller systems */ /** export three months of posts. If you want to export and import all posts you have to start with * the first year and export/import them in ascending order. * * Don't export linked resource items. we'll have to pull those out separately. */ $r = q("select * from item where item_wall = 1 and item_deleted = 0 and uid = %d and created > %s - INTERVAL %s and resource_type = '' order by created", intval($channel_id), db_utcnow(), db_quoteinterval('3 MONTH')); if ($r) { $ret['item'] = array(); xchan_query($r); $r = fetch_post_tags($r, true); foreach ($r as $rr) { $ret['item'][] = encode_item($rr, true); } } return $ret; }
//Recieve the request $request = file_get_contents('php://input'); //Download the headers in the requests $headers = getallheaders(); //Extract the signature and digest from header $signature = $headers['signature']; $digest = $headers['digest']; //Assume we have the public key of the clients upfront $pub_key = openssl_pkey_get_public(file_get_contents('./public_key.pem')); $pubkey = openssl_pkey_get_details($pub_key); $pubkey = $pubkey["key"]; if (!$pubkey or !$signature or !$digest) { die('Failed to retrieve headers.' . "\n"); } else { //Verify the signiture of the client based on the request body and the public key of the client $ok = openssl_verify($request, base64url_decode($signature), $pubkey, $digest); } //Create the http body response $response = '<html><head><title>Elham Test</title>'; $response .= '<body>' . dynamicContent($ok, isset($_POST['verify'])) . '</body>'; $response .= '</html>'; //Server loads the private key to sign the body response $private_pair = file_get_contents('./private_key.pem'); if (!openssl_pkey_export($private_pair, $privateKey)) { die('Failed to retrieve saved private key.' . "\n"); } //Sign the response and upload the signature into header of the responses openssl_sign($response, $signature, $privateKey, $signature_alg = "sha256"); header('signature:' . base64url_encode($signature)); header('digest: sha256'); //Load the page
/** * @brief Process atom feed and update anything/everything we might need to update. * * $hub = should we find a hub declation in the feed, pass it back to our calling process, who might (or * might not) try and subscribe to it. * $datedir sorts in reverse order * * @param array $xml * The (atom) feed to consume - RSS isn't as fully supported but may work for simple feeds. * @param $importer * The contact_record (joined to user_record) of the local user who owns this * relationship. It is this person's stuff that is going to be updated. * @param $contact * The person who is sending us stuff. If not set, we MAY be processing a "follow" activity * from an external network and MAY create an appropriate contact record. Otherwise, we MUST * have a contact record. * @param int $pass by default ($pass = 0) we cannot guarantee that a parent item has been * imported prior to its children being seen in the stream unless we are certain * of how the feed is arranged/ordered. * * With $pass = 1, we only pull parent items out of the stream. * * With $pass = 2, we only pull children (comments/likes). * * So running this twice, first with pass 1 and then with pass 2 will do the right * thing regardless of feed ordering. This won't be adequate in a fully-threaded * model where comments can have sub-threads. That would require some massive sorting * to get all the feed items into a mostly linear ordering, and might still require * recursion. */ function consume_feed($xml, $importer, &$contact, $pass = 0) { require_once 'library/simplepie/simplepie.inc'; if (!strlen($xml)) { logger('consume_feed: empty input'); return; } $feed = new SimplePie(); $feed->set_raw_data($xml); $feed->init(); if ($feed->error()) { logger('consume_feed: Error parsing XML: ' . $feed->error()); } $permalink = $feed->get_permalink(); // Check at the feed level for updated contact name and/or photo // process any deleted entries $del_entries = $feed->get_feed_tags(NAMESPACE_TOMB, 'deleted-entry'); if (is_array($del_entries) && count($del_entries) && $pass != 2) { foreach ($del_entries as $dentry) { $deleted = false; if (isset($dentry['attribs']['']['ref'])) { $mid = $dentry['attribs']['']['ref']; $deleted = true; if (isset($dentry['attribs']['']['when'])) { $when = $dentry['attribs']['']['when']; $when = datetime_convert('UTC', 'UTC', $when, 'Y-m-d H:i:s'); } else { $when = datetime_convert('UTC', 'UTC', 'now', 'Y-m-d H:i:s'); } } if ($deleted && is_array($contact)) { $r = q("SELECT * from item where mid = '%s' and author_xchan = '%s' and uid = %d limit 1", dbesc(base64url_encode($mid)), dbesc($contact['xchan_hash']), intval($importer['channel_id'])); if ($r) { $item = $r[0]; if (!($item['item_restrict'] & ITEM_DELETED)) { logger('consume_feed: deleting item ' . $item['id'] . ' mid=' . base64url_decode($item['mid']), LOGGER_DEBUG); drop_item($item['id'], false); } } } } } // Now process the feed if ($feed->get_item_quantity()) { logger('consume_feed: feed item count = ' . $feed->get_item_quantity(), LOGGER_DEBUG); $items = $feed->get_items(); foreach ($items as $item) { $is_reply = false; $item_id = base64url_encode($item->get_id()); logger('consume_feed: processing ' . $item_id, LOGGER_DEBUG); $rawthread = $item->get_item_tags(NAMESPACE_THREAD, 'in-reply-to'); if (isset($rawthread[0]['attribs']['']['ref'])) { $is_reply = true; $parent_mid = base64url_encode($rawthread[0]['attribs']['']['ref']); } if ($is_reply) { if ($pass == 1) { continue; } // Have we seen it? If not, import it. $item_id = base64url_encode($item->get_id()); $author = array(); $datarray = get_atom_elements($feed, $item, $author); if (!x($author, 'author_name') || $author['author_is_feed']) { $author['author_name'] = $contact['xchan_name']; } if (!x($author, 'author_link') || $author['author_is_feed']) { $author['author_link'] = $contact['xchan_url']; } if (!x($author, 'author_photo') || $author['author_is_feed']) { $author['author_photo'] = $contact['xchan_photo_m']; } $datarray['author_xchan'] = ''; if ($author['author_link'] != $contact['xchan_url']) { $x = import_author_unknown(array('name' => $author['author_name'], 'url' => $author['author_link'], 'photo' => array('src' => $author['author_photo']))); if ($x) { $datarray['author_xchan'] = $x; } } if (!$datarray['author_xchan']) { $datarray['author_xchan'] = $contact['xchan_hash']; } $datarray['owner_xchan'] = $contact['xchan_hash']; $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", dbesc($item_id), intval($importer['channel_id'])); // Update content if 'updated' changes if ($r) { if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) { // do not accept (ignore) an earlier edit than one we currently have. if (datetime_convert('UTC', 'UTC', $datarray['edited']) < $r[0]['edited']) { continue; } update_feed_item($importer['channel_id'], $datarray); } continue; } $datarray['parent_mid'] = $parent_mid; $datarray['uid'] = $importer['channel_id']; logger('consume_feed: ' . print_r($datarray, true), LOGGER_DATA); $xx = item_store($datarray); $r = $xx['item_id']; continue; } else { // Head post of a conversation. Have we seen it? If not, import it. $item_id = base64url_encode($item->get_id()); $author = array(); $datarray = get_atom_elements($feed, $item, $author); if (is_array($contact)) { if (!x($author, 'author_name') || $author['author_is_feed']) { $author['author_name'] = $contact['xchan_name']; } if (!x($author, 'author_link') || $author['author_is_feed']) { $author['author_link'] = $contact['xchan_url']; } if (!x($author, 'author_photo') || $author['author_is_feed']) { $author['author_photo'] = $contact['xchan_photo_m']; } } if (!x($author, 'author_name') || !x($author, 'author_link')) { logger('consume_feed: no author information! ' . print_r($author, true)); continue; } $datarray['author_xchan'] = ''; if ($author['author_link'] != $contact['xchan_url']) { $x = import_author_unknown(array('name' => $author['author_name'], 'url' => $author['author_link'], 'photo' => array('src' => $author['author_photo']))); if ($x) { $datarray['author_xchan'] = $x; } } if (!$datarray['author_xchan']) { $datarray['author_xchan'] = $contact['xchan_hash']; } $datarray['owner_xchan'] = $contact['xchan_hash']; $r = q("SELECT edited FROM item WHERE mid = '%s' AND uid = %d LIMIT 1", dbesc($item_id), intval($importer['channel_id'])); // Update content if 'updated' changes if ($r) { if (x($datarray, 'edited') !== false && datetime_convert('UTC', 'UTC', $datarray['edited']) !== $r[0]['edited']) { // do not accept (ignore) an earlier edit than one we currently have. if (datetime_convert('UTC', 'UTC', $datarray['edited']) < $r[0]['edited']) { continue; } update_feed_item($importer['channel_id'], $datarray); } continue; } $datarray['parent_mid'] = $item_id; $datarray['uid'] = $importer['channel_id']; if (!link_compare($author['owner_link'], $contact['xchan_url'])) { logger('consume_feed: Correcting item owner.', LOGGER_DEBUG); $author['owner_name'] = $contact['name']; $author['owner_link'] = $contact['url']; $author['owner_avatar'] = $contact['thumb']; } logger('consume_feed: author ' . print_r($author, true), LOGGER_DEBUG); logger('consume_feed: ' . print_r($datarray, true), LOGGER_DATA); $xx = item_store($datarray); $r = $xx['item_id']; continue; } } } }
function smile_decode($m) { return str_replace($m[1], base64url_decode($m[1]), $m[0]); }
function check_zotinfo($channel, $locations, &$ret) { // logger('locations: ' . print_r($locations,true),LOGGER_DATA); // This function will likely expand as we find more things to detect and fix. // 1. Because magic-auth is reliant on it, ensure that the system channel has a valid hubloc // Force this to be the case if anything is found to be wrong with it. // @FIXME ensure that the system channel exists in the first place and has an xchan if ($channel['channel_system']) { // the sys channel must have a location (hubloc) $valid_location = false; if (count($locations) === 1 && $locations[0]['primary'] && !$locations[0]['deleted']) { if (rsa_verify($locations[0]['url'], base64url_decode($locations[0]['url_sig']), $channel['channel_pubkey']) && $locations[0]['sitekey'] === get_config('system', 'pubkey') && $locations[0]['url'] === z_root()) { $valid_location = true; } else { logger('sys channel: invalid url signature'); } } if (!$locations || !$valid_location) { logger('System channel locations are not valid. Attempting repair.'); // Don't trust any existing records. Just get rid of them, but only do this // for the sys channel as normal channels will be trickier. q("delete from hubloc where hubloc_hash = '%s'", dbesc($channel['channel_hash'])); $r = q("insert into hubloc ( hubloc_guid, hubloc_guid_sig, hubloc_hash, hubloc_addr, hubloc_primary,\n\t\t\t\thubloc_url, hubloc_url_sig, hubloc_host, hubloc_callback, hubloc_sitekey, hubloc_network )\n\t\t\t\tvalues ( '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '%s', '%s' )", dbesc($channel['channel_guid']), dbesc($channel['channel_guid_sig']), dbesc($channel['channel_hash']), dbesc($channel['channel_address'] . '@' . get_app()->get_hostname()), intval(1), dbesc(z_root()), dbesc(base64url_encode(rsa_sign(z_root(), $channel['channel_prvkey']))), dbesc(get_app()->get_hostname()), dbesc(z_root() . '/post'), dbesc(get_config('system', 'pubkey')), dbesc('zot')); if ($r) { $x = zot_encode_locations($channel); if ($x) { $ret['locations'] = $x; } } else { logger('Unable to store sys hub location'); } } } }
function get_atom_elements($feed, $item, $contact = array()) { require_once 'library/HTMLPurifier.auto.php'; require_once 'include/html2bbcode.php'; $best_photo = array(); $res = array(); $author = $item->get_author(); if ($author) { $res['author-name'] = unxmlify($author->get_name()); $res['author-link'] = unxmlify($author->get_link()); } else { $res['author-name'] = unxmlify($feed->get_title()); $res['author-link'] = unxmlify($feed->get_permalink()); } $res['uri'] = unxmlify($item->get_id()); $res['title'] = unxmlify($item->get_title()); $res['body'] = unxmlify($item->get_content()); $res['plink'] = unxmlify($item->get_link(0)); if (isset($contact["network"]) and $contact["network"] == NETWORK_FEED and strstr($res['plink'], ".app.net/")) { logger("get_atom_elements: detected app.net posting: " . print_r($res, true), LOGGER_DEBUG); $res['title'] = ""; $res['body'] = nl2br($res['body']); } // removing the content of the title if its identically to the body // This helps with auto generated titles e.g. from tumblr if (title_is_body($res["title"], $res["body"])) { $res['title'] = ""; } if ($res['plink']) { $base_url = implode('/', array_slice(explode('/', $res['plink']), 0, 3)); } else { $base_url = ''; } // look for a photo. We should check media size and find the best one, // but for now let's just find any author photo // Additionally we look for an alternate author link. On OStatus this one is the one we want. $authorlinks = $item->feed->data["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["feed"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["author"][0]["child"]["http://www.w3.org/2005/Atom"]["link"]; if (is_array($authorlinks)) { foreach ($authorlinks as $link) { $linkdata = array_shift($link["attribs"]); if ($linkdata["rel"] == "alternate") { $res["author-link"] = $linkdata["href"]; } } } $rawauthor = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); if ($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach ($base as $link) { if ($link['attribs']['']['rel'] === 'alternate') { $res['author-link'] = unxmlify($link['attribs']['']['href']); } if (!x($res, 'author-avatar') || !$res['author-avatar']) { if ($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } $rawactor = $item->get_item_tags(NAMESPACE_ACTIVITY, 'actor'); if ($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'], ACTIVITY_OBJ_PERSON)) { $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; if ($base && count($base)) { foreach ($base as $link) { if ($link['attribs']['']['rel'] === 'alternate' && !$res['author-link']) { $res['author-link'] = unxmlify($link['attribs']['']['href']); } if (!x($res, 'author-avatar') || !$res['author-avatar']) { if ($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } } // No photo/profile-link on the item - look at the feed level if (!x($res, 'author-link') || !x($res, 'author-avatar')) { $rawauthor = $feed->get_feed_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'author'); if ($rawauthor && $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawauthor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach ($base as $link) { if ($link['attribs']['']['rel'] === 'alternate' && !$res['author-link']) { $res['author-link'] = unxmlify($link['attribs']['']['href']); } if (!$res['author-avatar']) { if ($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } $rawactor = $feed->get_feed_tags(NAMESPACE_ACTIVITY, 'subject'); if ($rawactor && activity_match($rawactor[0]['child'][NAMESPACE_ACTIVITY]['object-type'][0]['data'], ACTIVITY_OBJ_PERSON)) { $base = $rawactor[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; if ($base && count($base)) { foreach ($base as $link) { if ($link['attribs']['']['rel'] === 'alternate' && !$res['author-link']) { $res['author-link'] = unxmlify($link['attribs']['']['href']); } if (!x($res, 'author-avatar')) { if ($link['attribs']['']['rel'] === 'avatar' || $link['attribs']['']['rel'] === 'photo') { $res['author-avatar'] = unxmlify($link['attribs']['']['href']); } } } } } } $apps = $item->get_item_tags(NAMESPACE_STATUSNET, 'notice_info'); if ($apps && $apps[0]['attribs']['']['source']) { $res['app'] = strip_tags(unxmlify($apps[0]['attribs']['']['source'])); if ($res['app'] === 'web') { $res['app'] = 'OStatus'; } } // base64 encoded json structure representing Diaspora signature $dsig = $item->get_item_tags(NAMESPACE_DFRN, 'diaspora_signature'); if ($dsig) { $res['dsprsig'] = unxmlify($dsig[0]['data']); } $dguid = $item->get_item_tags(NAMESPACE_DFRN, 'diaspora_guid'); if ($dguid) { $res['guid'] = unxmlify($dguid[0]['data']); } $bm = $item->get_item_tags(NAMESPACE_DFRN, 'bookmark'); if ($bm) { $res['bookmark'] = unxmlify($bm[0]['data']) === 'true' ? 1 : 0; } /** * If there's a copy of the body content which is guaranteed to have survived mangling in transit, use it. */ $have_real_body = false; $rawenv = $item->get_item_tags(NAMESPACE_DFRN, 'env'); if ($rawenv) { $have_real_body = true; $res['body'] = $rawenv[0]['data']; $res['body'] = str_replace(array(' ', "\t", "\r", "\n"), array('', '', '', ''), $res['body']); // make sure nobody is trying to sneak some html tags by us $res['body'] = notags(base64url_decode($res['body'])); } $res['body'] = limit_body_size($res['body']); // It isn't certain at this point whether our content is plaintext or html and we'd be foolish to trust // the content type. Our own network only emits text normally, though it might have been converted to // html if we used a pubsubhubbub transport. But if we see even one html tag in our text, we will // have to assume it is all html and needs to be purified. // It doesn't matter all that much security wise - because before this content is used anywhere, we are // going to escape any tags we find regardless, but this lets us import a limited subset of html from // the wild, by sanitising it and converting supported tags to bbcode before we rip out any remaining // html. if (strpos($res['body'], '<') !== false && strpos($res['body'], '>') !== false) { $res['body'] = reltoabs($res['body'], $base_url); $res['body'] = html2bb_video($res['body']); $res['body'] = oembed_html2bbcode($res['body']); $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); // we shouldn't need a whitelist, because the bbcode converter // will strip out any unsupported tags. $purifier = new HTMLPurifier($config); $res['body'] = $purifier->purify($res['body']); $res['body'] = @html2bbcode($res['body']); } elseif (!$have_real_body) { // it's not one of our messages and it has no tags // so it's probably just text. We'll escape it just to be safe. $res['body'] = escape_tags($res['body']); } // this tag is obsolete but we keep it for really old sites $allow = $item->get_item_tags(NAMESPACE_DFRN, 'comment-allow'); if ($allow && $allow[0]['data'] == 1) { $res['last-child'] = 1; } else { $res['last-child'] = 0; } $private = $item->get_item_tags(NAMESPACE_DFRN, 'private'); if ($private && intval($private[0]['data']) > 0) { $res['private'] = intval($private[0]['data']); } else { $res['private'] = 0; } $extid = $item->get_item_tags(NAMESPACE_DFRN, 'extid'); if ($extid && $extid[0]['data']) { $res['extid'] = $extid[0]['data']; } $rawlocation = $item->get_item_tags(NAMESPACE_DFRN, 'location'); if ($rawlocation) { $res['location'] = unxmlify($rawlocation[0]['data']); } $rawcreated = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'published'); if ($rawcreated) { $res['created'] = unxmlify($rawcreated[0]['data']); } $rawedited = $item->get_item_tags(SIMPLEPIE_NAMESPACE_ATOM_10, 'updated'); if ($rawedited) { $res['edited'] = unxmlify($rawedited[0]['data']); } if (x($res, 'edited') && !x($res, 'created')) { $res['created'] = $res['edited']; } if (!$res['created']) { $res['created'] = $item->get_date('c'); } if (!$res['edited']) { $res['edited'] = $item->get_date('c'); } // Disallow time travelling posts $d1 = strtotime($res['created']); $d2 = strtotime($res['edited']); $d3 = strtotime('now'); if ($d1 > $d3) { $res['created'] = datetime_convert(); } if ($d2 > $d3) { $res['edited'] = datetime_convert(); } $rawowner = $item->get_item_tags(NAMESPACE_DFRN, 'owner'); if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']) { $res['owner-name'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['name'][0]['data']); } elseif ($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']) { $res['owner-name'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['name'][0]['data']); } if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']) { $res['owner-link'] = unxmlify($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['uri'][0]['data']); } elseif ($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']) { $res['owner-link'] = unxmlify($rawowner[0]['child'][NAMESPACE_DFRN]['uri'][0]['data']); } if ($rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $base = $rawowner[0]['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['link']; foreach ($base as $link) { if (!x($res, 'owner-avatar') || !$res['owner-avatar']) { if ($link['attribs']['']['rel'] === 'photo' || $link['attribs']['']['rel'] === 'avatar') { $res['owner-avatar'] = unxmlify($link['attribs']['']['href']); } } } } $rawgeo = $item->get_item_tags(NAMESPACE_GEORSS, 'point'); if ($rawgeo) { $res['coord'] = unxmlify($rawgeo[0]['data']); } if ($contact["network"] == NETWORK_FEED) { $res['verb'] = ACTIVITY_POST; $res['object-type'] = ACTIVITY_OBJ_NOTE; } $rawverb = $item->get_item_tags(NAMESPACE_ACTIVITY, 'verb'); // select between supported verbs if ($rawverb) { $res['verb'] = unxmlify($rawverb[0]['data']); } // translate OStatus unfollow to activity streams if it happened to get selected if (x($res, 'verb') && $res['verb'] === 'http://ostatus.org/schema/1.0/unfollow') { $res['verb'] = ACTIVITY_UNFOLLOW; } $cats = $item->get_categories(); if ($cats) { $tag_arr = array(); foreach ($cats as $cat) { $term = $cat->get_term(); if (!$term) { $term = $cat->get_label(); } $scheme = $cat->get_scheme(); if ($scheme && $term && stristr($scheme, 'X-DFRN:')) { $tag_arr[] = substr($scheme, 7, 1) . '[url=' . unxmlify(substr($scheme, 9)) . ']' . unxmlify($term) . '[/url]'; } elseif ($term) { $tag_arr[] = notags(trim($term)); } } $res['tag'] = implode(',', $tag_arr); } $attach = $item->get_enclosures(); if ($attach) { $att_arr = array(); foreach ($attach as $att) { $len = intval($att->get_length()); $link = str_replace(array(',', '"'), array('%2D', '%22'), notags(trim(unxmlify($att->get_link())))); $title = str_replace(array(',', '"'), array('%2D', '%22'), notags(trim(unxmlify($att->get_title())))); $type = str_replace(array(',', '"'), array('%2D', '%22'), notags(trim(unxmlify($att->get_type())))); if (strpos($type, ';')) { $type = substr($type, 0, strpos($type, ';')); } if (!$link || strpos($link, 'http') !== 0) { continue; } if (!$title) { $title = ' '; } if (!$type) { $type = 'application/octet-stream'; } $att_arr[] = '[attach]href="' . $link . '" length="' . $len . '" type="' . $type . '" title="' . $title . '"[/attach]'; } $res['attach'] = implode(',', $att_arr); } $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'object'); if ($rawobj) { $res['object'] = '<object>' . "\n"; $child = $rawobj[0]['child']; if ($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { $res['object-type'] = $child[NAMESPACE_ACTIVITY]['object-type'][0]['data']; $res['object'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) { $res['object'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $res['object'] .= '<link>' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'title') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']) { $res['object'] .= '<title>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'content') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']; if (!$body) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; } // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events $res['object'] .= '<orig>' . xmlify($body) . '</orig>' . "\n"; if (strpos($body, '<') !== false || strpos($body, '>') !== false) { $body = html2bb_video($body); $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); $purifier = new HTMLPurifier($config); $body = $purifier->purify($body); $body = html2bbcode($body); } $res['object'] .= '<content>' . $body . '</content>' . "\n"; } $res['object'] .= '</object>' . "\n"; } $rawobj = $item->get_item_tags(NAMESPACE_ACTIVITY, 'target'); if ($rawobj) { $res['target'] = '<target>' . "\n"; $child = $rawobj[0]['child']; if ($child[NAMESPACE_ACTIVITY]['object-type'][0]['data']) { $res['target'] .= '<type>' . $child[NAMESPACE_ACTIVITY]['object-type'][0]['data'] . '</type>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'id') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data']) { $res['target'] .= '<id>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['id'][0]['data'] . '</id>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'link') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) { $res['target'] .= '<link>' . encode_rel_links($child[SIMPLEPIE_NAMESPACE_ATOM_10]['link']) . '</link>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data']) { $res['target'] .= '<title>' . $child[SIMPLEPIE_NAMESPACE_ATOM_10]['title'][0]['data'] . '</title>' . "\n"; } if (x($child[SIMPLEPIE_NAMESPACE_ATOM_10], 'data') && $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['content'][0]['data']; if (!$body) { $body = $child[SIMPLEPIE_NAMESPACE_ATOM_10]['summary'][0]['data']; } // preserve a copy of the original body content in case we later need to parse out any microformat information, e.g. events $res['target'] .= '<orig>' . xmlify($body) . '</orig>' . "\n"; if (strpos($body, '<') !== false || strpos($body, '>') !== false) { $body = html2bb_video($body); $config = HTMLPurifier_Config::createDefault(); $config->set('Cache.DefinitionImpl', null); $purifier = new HTMLPurifier($config); $body = $purifier->purify($body); $body = html2bbcode($body); } $res['target'] .= '<content>' . $body . '</content>' . "\n"; } $res['target'] .= '</target>' . "\n"; } // This is some experimental stuff. By now retweets are shown with "RT:" // But: There is data so that the message could be shown similar to native retweets // There is some better way to parse this array - but it didn't worked for me. $child = $item->feed->data["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["feed"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["entry"][0]["child"]["http://activitystrea.ms/spec/1.0/"][object][0]["child"]; if (is_array($child)) { logger('get_atom_elements: Looking for status.net repeated message'); $message = $child["http://activitystrea.ms/spec/1.0/"]["object"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["content"][0]["data"]; $orig_id = ostatus_convert_href($child["http://activitystrea.ms/spec/1.0/"]["object"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]["id"][0]["data"]); $author = $child[SIMPLEPIE_NAMESPACE_ATOM_10]["author"][0]["child"][SIMPLEPIE_NAMESPACE_ATOM_10]; $uri = $author["uri"][0]["data"]; $name = $author["name"][0]["data"]; $avatar = @array_shift($author["link"][2]["attribs"]); $avatar = $avatar["href"]; if ($name != "" and $uri != "" and $avatar != "" and $message != "") { logger('get_atom_elements: fixing sender of repeated message. ' . $orig_id, LOGGER_DEBUG); if (!intval(get_config('system', 'wall-to-wall_share'))) { $prefix = share_header($name, $uri, $avatar, "", "", $orig_link); $res["body"] = $prefix . html2bbcode($message) . "[/share]"; } else { $res["owner-name"] = $res["author-name"]; $res["owner-link"] = $res["author-link"]; $res["owner-avatar"] = $res["author-avatar"]; $res["author-name"] = $name; $res["author-link"] = $uri; $res["author-avatar"] = $avatar; $res["body"] = html2bbcode($message); } } } if (isset($contact["network"]) and $contact["network"] == NETWORK_FEED and $contact['fetch_further_information']) { $preview = ""; // Handle enclosures and treat them as preview picture if (isset($attach)) { foreach ($attach as $attachment) { if ($attachment->type == "image/jpeg") { $preview = $attachment->link; } } } $res["body"] = $res["title"] . add_page_info($res['plink'], false, $preview, $contact['fetch_further_information'] == 2, $contact['ffi_keyword_blacklist']); $res["tag"] = add_page_keywords($res['plink'], false, $preview, $contact['fetch_further_information'] == 2, $contact['ffi_keyword_blacklist']); $res["title"] = ""; $res["object-type"] = ACTIVITY_OBJ_BOOKMARK; unset($res["attach"]); } elseif (isset($contact["network"]) and $contact["network"] == NETWORK_OSTATUS) { $res["body"] = add_page_info_to_body($res["body"]); } elseif (isset($contact["network"]) and $contact["network"] == NETWORK_FEED and strstr($res['plink'], ".app.net/")) { $res["body"] = add_page_info_to_body($res["body"]); } $arr = array('feed' => $feed, 'item' => $item, 'result' => $res); call_hooks('parse_atom', $arr); return $res; }
* @package Tidy * @subpackage Webroot * @filesource */ /** * include the initiator */ error_reporting(0); define('DS', strstr(PHP_OS, 'WIN') ? '\\' : '/'); define('APP_PATH', realpath(dirname(dirname(__FILE__))) . DS); include_once APP_PATH . 'core' . DS . 'ini.php'; /** * check the request contain cash for process */ if ($requestReg->getGet('cash') != NULL) { $cashArray = explode('|', base64url_decode($requestReg->getGet('cash'))); /** * cash the file content * @see Apps */ if (is_array($cashArray)) { $newfunc = create_function('$a', ' if(strstr($a,"Controller-") and strstr($a,"-Action")) { $jsActionController=explode("-",$a); return JS_PATH.$jsActionController[1].DS.(isset($jsActionController[4])?$jsActionController[4].DS:"").$jsActionController[2].".js"; } elseif(strstr($a,"http")) return $a; else return JS_PATH.$a.".js";');
} if ($didType != $GLOBALS['didType']) { dump("HOBA: Unsupported device ID type"); setFailCookie(); exit(1); } // TODO: Check to make sure kid === RSA256(pubKey) foreach (getallheaders() as $name => $value) { //dump("Header:" . $name . " " . $value); if ($name == "Authorization" && stripos($value, "hoba") > -1) { list($junk, $authStr) = explode("result=", $value); $kidB64 = strtok($authStr, "."); $chalB64 = strtok("."); $nonceB64 = strtok("."); $sig = base64url_decode(strtok(".")); if ($kid != base64url_decode($kidB64)) { dump("HOBA: kid in POST different from kid in Auth Header"); setFailCookie(); exit(1); } } } //dump("kidB64:" . $kidB64 . " chalB64:" . $chalB64 . " nonceB64:" . $nonceB64 ." sig:" . $sig); if (checkChal($chalB64, getPeer())) { dump("HOBA: Challenge accepted"); } else { dump("HOBA: Challenge failed"); setFailCookie(); exit(1); } $tbsOrigin = "https://" . $_SERVER['SERVER_NAME'] . ":" . $_SERVER['SERVER_PORT'];