Merge pull request #741 from dawnbreak/docu

Add security logger to RedDAV.
This commit is contained in:
Thomas Willingham 2014-12-14 12:26:08 +00:00
commit 082ef8b950
5 changed files with 237 additions and 233 deletions

View File

@ -51,6 +51,15 @@ define ( 'ZOT_REVISION', 1 );
define ( 'DB_UPDATE_VERSION', 1131 ); define ( 'DB_UPDATE_VERSION', 1131 );
/**
* Constant with a HTML line break.
*
* Contains a HTML line break (br) element and a real carriage return with line
* feed for the source.
* This can be used in HTML and JavaScript where needed a line break.
*
* @var string
*/
define ( 'EOL', '<br>' . "\r\n" ); define ( 'EOL', '<br>' . "\r\n" );
define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' ); define ( 'ATOM_TIME', 'Y-m-d\TH:i:s\Z' );
//define ( 'NULL_DATE', '0000-00-00 00:00:00' ); //define ( 'NULL_DATE', '0000-00-00 00:00:00' );

View File

@ -118,8 +118,11 @@ class RedBasicAuth extends DAV\Auth\Backend\AbstractBasic {
} }
} }
} }
logger('password failed for ' . $username);
// @TODO add security logger $error = 'password failed for ' . $username;
logger($error);
log_failed_login($error);
return false; return false;
} }

View File

@ -183,9 +183,9 @@ class RedBrowser extends DAV\Browser\Plugin {
} }
} }
$parentHash = ""; $parentHash = '';
$owner = $this->auth->owner_id; $owner = $this->auth->owner_id;
$splitPath = split("/", $fullPath); $splitPath = split('/', $fullPath);
if (count($splitPath) > 3) { if (count($splitPath) > 3) {
for ($i = 3; $i < count($splitPath); $i++) { for ($i = 3; $i < count($splitPath); $i++) {
$attachName = urldecode($splitPath[$i]); $attachName = urldecode($splitPath[$i]);
@ -233,6 +233,7 @@ class RedBrowser extends DAV\Browser\Plugin {
} }
// prepare quota for template // prepare quota for template
$quota = array();
$quota['used'] = $used; $quota['used'] = $used;
$quota['limit'] = $limit; $quota['limit'] = $limit;
$quota['desc'] = $quotaDesc; $quota['desc'] = $quotaDesc;

View File

@ -41,6 +41,9 @@ function nuke_session() {
/** /**
* @brief Verify login credentials. * @brief Verify login credentials.
* *
* If system <i>authlog</i> is set a log entry will be added for failed login
* attempts.
*
* @param string $email * @param string $email
* The email address to verify. * The email address to verify.
* @param string $pass * @param string $pass
@ -88,14 +91,25 @@ function account_verify_password($email, $pass) {
if($record['account_flags'] & ACCOUNT_PENDING) if($record['account_flags'] & ACCOUNT_PENDING)
logger('Account is pending. account_flags = ' . $record['account_flags']); logger('Account is pending. account_flags = ' . $record['account_flags']);
// Also log failed logins to a separate auth log to reduce overhead for server side intrusion prevention log_failed_login($error);
$authlog = get_config('system', 'authlog');
if ($authlog)
@file_put_contents($authlog, datetime_convert() . ':' . session_id() . ' ' . $error . "\n", FILE_APPEND);
return null; return null;
} }
/**
* @brief Log failed logins to a separate auth log.
*
* Can be used to reduce overhead for server side intrusion prevention, like
* parse the authlog file with something like fail2ban, OSSEC, etc.
*
* @param string $errormsg
* Error message to display for failed login.
*/
function log_failed_login($errormsg) {
$authlog = get_config('system', 'authlog');
if ($authlog)
@file_put_contents($authlog, datetime_convert() . ':' . session_id() . ' ' . $errormsg . PHP_EOL, FILE_APPEND);
}
/** /**
* Inline - not a function * Inline - not a function

View File

@ -314,7 +314,6 @@ function paginate(&$a) {
$pagenum = $a->pager['page']; $pagenum = $a->pager['page'];
$url = $a->get_baseurl() . '/' . $stripped; $url = $a->get_baseurl() . '/' . $stripped;
if($a->pager['total'] > $a->pager['itemspage']) { if($a->pager['total'] > $a->pager['itemspage']) {
$o .= '<div class="pager">'; $o .= '<div class="pager">';
if($a->pager['page'] != 1) if($a->pager['page'] != 1)
@ -420,7 +419,6 @@ function sanitise_acl(&$item) {
// Convert an ACL array to a storable string // Convert an ACL array to a storable string
function perms2str($p) { function perms2str($p) {
$ret = ''; $ret = '';
@ -436,16 +434,17 @@ function perms2str($p) {
return $ret; return $ret;
} }
// generate a guaranteed unique (for this domain) item ID for ATOM /**
// safe from birthday paradox * @brief Generate a guaranteed unique (for this domain) item ID for ATOM.
*
* Safe from birthday paradox.
*
* @return string a unique id
*/
function item_message_id() { function item_message_id() {
do { do {
$dups = false; $dups = false;
$hash = random_string(); $hash = random_string();
$mid = $hash . '@' . get_app()->get_hostname(); $mid = $hash . '@' . get_app()->get_hostname();
$r = q("SELECT id FROM item WHERE mid = '%s' LIMIT 1", $r = q("SELECT id FROM item WHERE mid = '%s' LIMIT 1",
@ -453,31 +452,33 @@ function item_message_id() {
if(count($r)) if(count($r))
$dups = true; $dups = true;
} while($dups == true); } while($dups == true);
return $mid; return $mid;
} }
// Generate a guaranteed unique photo ID. /**
// safe from birthday paradox * @brief Generate a guaranteed unique photo ID.
*
* Safe from birthday paradox.
*
* @return string a uniqe hash
*/
function photo_new_resource() { function photo_new_resource() {
do { do {
$found = false; $found = false;
$resource = hash('md5',uniqid(mt_rand(),true)); $resource = hash('md5', uniqid(mt_rand(), true));
$r = q("SELECT id FROM photo WHERE resource_id = '%s' LIMIT 1", $r = q("SELECT id FROM photo WHERE resource_id = '%s' LIMIT 1",
dbesc($resource) dbesc($resource));
);
if(count($r)) if(count($r))
$found = true; $found = true;
} while($found == true); } while($found === true);
return $resource; return $resource;
} }
// for html,xml parsing - let's say you've got // for html,xml parsing - let's say you've got
// an attribute foobar="class1 class2 class3" // an attribute foobar="class1 class2 class3"
// and you want to find out if it contains 'class3'. // and you want to find out if it contains 'class3'.
@ -487,52 +488,76 @@ function photo_new_resource() {
// pass the attribute string as $attr and the attribute you // pass the attribute string as $attr and the attribute you
// are looking for as $s - returns true if found, otherwise false // are looking for as $s - returns true if found, otherwise false
function attribute_contains($attr,$s) { function attribute_contains($attr, $s) {
$a = explode(' ', $attr); $a = explode(' ', $attr);
if(count($a) && in_array($s,$a)) if(count($a) && in_array($s, $a))
return true; return true;
return false; return false;
} }
/**
function logger($msg,$level = 0) { * @brief Logging function for RedMatrix.
*
* Logging output is configured through RedMatrix's system config. The log file
* is set in system logfile, log level in system loglevel and to enable logging
* set system debugging.
*
* Available constants for log level are LOGGER_NORMAL, LOGGER_TRACE, LOGGER_DEBUG,
* LOGGER_DATA and LOGGER_ALL.
*
* Since PHP5.4 we get the file, function and line automatically where the logger
* was caleld, so no need to add it to the message anymore.
*
* @param string $msg Message to log
* @param int $level A log level.
*/
function logger($msg, $level = 0) {
// turn off logger in install mode // turn off logger in install mode
global $a; global $a;
global $db; global $db;
if(($a->module == 'install') || (! ($db && $db->connected))) return; if(($a->module == 'install') || (! ($db && $db->connected)))
return;
$debugging = get_config('system','debugging'); $debugging = get_config('system', 'debugging');
$loglevel = intval(get_config('system','loglevel')); $loglevel = intval(get_config('system', 'loglevel'));
$logfile = get_config('system','logfile'); $logfile = get_config('system', 'logfile');
if((! $debugging) || (! $logfile) || ($level > $loglevel)) if((! $debugging) || (! $logfile) || ($level > $loglevel))
return; return;
$where = ''; $where = '';
if(version_compare(PHP_VERSION,'5.4.0') >= 0) { if(version_compare(PHP_VERSION, '5.4.0') >= 0) {
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS,2); $stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': '; $where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': ';
} }
@file_put_contents($logfile, datetime_convert() . ':' . session_id() . ' ' . $where . $msg . "\n", FILE_APPEND); @file_put_contents($logfile, datetime_convert() . ':' . session_id() . ' ' . $where . $msg . PHP_EOL, FILE_APPEND);
return;
} }
/**
// This is a special logging facility for developers. It allows one to target specific things to trace/debug * @brief This is a special logging facility for developers.
// and is identical to logger() with the exception of the log filename. This allows one to isolate specific *
// calls while allowing logger() to paint a bigger picture of overall activity and capture more detail. * It allows one to target specific things to trace/debug and is identical to
// If you find dlogger() calls in checked in code, you are free to remove them - so as to provide a noise-free * logger() with the exception of the log filename. This allows one to isolate
// development environment which responds to events you are targetting personally. * specific calls while allowing logger() to paint a bigger picture of overall
* activity and capture more detail.
*
function dlogger($msg,$level = 0) { * If you find dlogger() calls in checked in code, you are free to remove them -
* so as to provide a noise-free development environment which responds to events
* you are targetting personally.
*
* @param string $msg Message to log
* @param int $level A log level.
*/
function dlogger($msg, $level = 0) {
// turn off logger in install mode // turn off logger in install mode
global $a; global $a;
global $db; global $db;
if(($a->module == 'install') || (! ($db && $db->connected))) return; if(($a->module == 'install') || (! ($db && $db->connected)))
return;
$debugging = get_config('system','debugging'); $debugging = get_config('system','debugging');
$loglevel = intval(get_config('system','loglevel')); $loglevel = intval(get_config('system','loglevel'));
@ -541,18 +566,22 @@ function dlogger($msg,$level = 0) {
if((! $debugging) || (! $logfile) || ($level > $loglevel)) if((! $debugging) || (! $logfile) || ($level > $loglevel))
return; return;
@file_put_contents($logfile, datetime_convert() . ':' . session_id() . ' ' . $msg . "\n", FILE_APPEND); $where = '';
return; if(version_compare(PHP_VERSION, '5.4.0') >= 0) {
$stack = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$where = basename($stack[0]['file']) . ':' . $stack[0]['line'] . ':' . $stack[1]['function'] . ': ';
}
@file_put_contents($logfile, datetime_convert() . ':' . session_id() . ' ' . $where . $msg . PHP_EOL, FILE_APPEND);
} }
function profiler($t1,$t2,$label) { function profiler($t1,$t2,$label) {
if(file_exists('profiler.out') && $t1 && t2) if(file_exists('profiler.out') && $t1 && t2)
@file_put_contents('profiler.out', sprintf('%01.4f %s',$t2 - $t1,$label) . "\n", FILE_APPEND); @file_put_contents('profiler.out', sprintf('%01.4f %s',$t2 - $t1,$label) . PHP_EOL, FILE_APPEND);
} }
function activity_match($haystack,$needle) { function activity_match($haystack,$needle) {
if(($haystack === $needle) || ((basename($needle) === $haystack) && strstr($needle,NAMESPACE_ACTIVITY_SCHEMA))) if(($haystack === $needle) || ((basename($needle) === $haystack) && strstr($needle,NAMESPACE_ACTIVITY_SCHEMA)))
return true; return true;
@ -569,7 +598,6 @@ function activity_match($haystack,$needle) {
// Returns array of tags found, or empty array. // Returns array of tags found, or empty array.
function get_tags($s) { function get_tags($s) {
$ret = array(); $ret = array();
@ -592,9 +620,6 @@ function get_tags($s) {
// Match full names against @tags including the space between first and last // Match full names against @tags including the space between first and last
// We will look these up afterward to see if they are full names or not recognisable. // We will look these up afterward to see if they are full names or not recognisable.
if(preg_match_all('/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/',$s,$match)) { if(preg_match_all('/(@[^ \x0D\x0A,:?]+ [^ \x0D\x0A@,:?]+)([ \x0D\x0A@,:?]|$)/',$s,$match)) {
foreach($match[1] as $mtch) { foreach($match[1] as $mtch) {
if(strstr($mtch,"]")) { if(strstr($mtch,"]")) {
@ -648,7 +673,6 @@ function get_tags($s) {
usort($ret,'tag_sort_length'); usort($ret,'tag_sort_length');
// logger('get_tags: ' . print_r($ret,true)); // logger('get_tags: ' . print_r($ret,true));
return $ret; return $ret;
@ -657,13 +681,12 @@ function get_tags($s) {
function tag_sort_length($a,$b) { function tag_sort_length($a,$b) {
if(mb_strlen($a) == mb_strlen($b)) if(mb_strlen($a) == mb_strlen($b))
return 0; return 0;
return((mb_strlen($b) < mb_strlen($a)) ? (-1) : 1); return((mb_strlen($b) < mb_strlen($a)) ? (-1) : 1);
} }
function strip_zids($s) { function strip_zids($s) {
return preg_replace('/[\?&]zid=(.*?)(&|$)/ism','$2',$s); return preg_replace('/[\?&]zid=(.*?)(&|$)/ism','$2',$s);
} }
@ -673,12 +696,10 @@ function strip_zids($s) {
function qp($s) { function qp($s) {
return str_replace ("%","=",rawurlencode($s)); return str_replace ("%","=",rawurlencode($s));
} }
function get_mentions($item,$tags) { function get_mentions($item,$tags) {
$o = ''; $o = '';
@ -712,7 +733,6 @@ function contact_block() {
if($shown == 0) if($shown == 0)
return; return;
$is_owner = ((local_user() && local_user() == $a->profile['uid']) ? true : false); $is_owner = ((local_user() && local_user() == $a->profile['uid']) ? true : false);
$abook_flags = ABOOK_FLAG_PENDING|ABOOK_FLAG_SELF; $abook_flags = ABOOK_FLAG_PENDING|ABOOK_FLAG_SELF;
@ -734,8 +754,7 @@ function contact_block() {
} }
if(! $total) { if(! $total) {
$contacts = t('No connections'); $contacts = t('No connections');
$micropro = Null; $micropro = null;
} else { } else {
if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) {
$randfunc = 'RANDOM()'; $randfunc = 'RANDOM()';
@ -771,7 +790,6 @@ function contact_block() {
call_hooks('contact_block_end', $arr); call_hooks('contact_block_end', $arr);
return $o; return $o;
} }
@ -815,8 +833,6 @@ function micropro($contact, $redirect = false, $class = '', $textmode = false) {
} }
function search($s,$id='search-box',$url='/search',$save = false) { function search($s,$id='search-box',$url='/search',$save = false) {
$a = get_app(); $a = get_app();
return replace_macros(get_markup_template('searchbox.tpl'),array( return replace_macros(get_markup_template('searchbox.tpl'),array(
@ -843,12 +859,12 @@ function searchbox($s,$id='search-box',$url='/search',$save = false) {
function valid_email($x){ function valid_email($x){
if(get_config('system','disable_email_validation')) if(get_config('system','disable_email_validation'))
return true; return true;
if(preg_match('/^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9\-\+]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/',$x)) if(preg_match('/^[_a-zA-Z0-9\-\+]+(\.[_a-zA-Z0-9\-\+]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+$/',$x))
return true; return true;
return false; return false;
} }
@ -879,11 +895,10 @@ function linkify($s) {
* *
* @returns string * @returns string
*/ */
function sslify($s) { function sslify($s) {
if(strpos(z_root(),'https:') === false) if(strpos(z_root(),'https:') === false)
return $s; return $s;
$matches = null; $matches = null;
$cnt = preg_match_all("/\<(.*?)src=\"(http\:.*?)\"(.*?)\>/",$s,$matches,PREG_SET_ORDER); $cnt = preg_match_all("/\<(.*?)src=\"(http\:.*?)\"(.*?)\>/",$s,$matches,PREG_SET_ORDER);
if($cnt) { if($cnt) {
@ -897,7 +912,6 @@ function sslify($s) {
function get_poke_verbs() { function get_poke_verbs() {
// index is present tense verb // index is present tense verb
// value is array containing past tense verb, translation of present, translation of past // value is array containing past tense verb, translation of present, translation of past
@ -909,6 +923,7 @@ function get_poke_verbs() {
'finger' => array( 'fingered', t('finger'), t('fingered')), 'finger' => array( 'fingered', t('finger'), t('fingered')),
'rebuff' => array( 'rebuffed', t('rebuff'), t('rebuffed')), 'rebuff' => array( 'rebuffed', t('rebuff'), t('rebuffed')),
); );
call_hooks('poke_verbs', $arr); call_hooks('poke_verbs', $arr);
return $arr; return $arr;
} }
@ -964,17 +979,13 @@ function get_mood_verbs() {
* bbcode source for HTML display * bbcode source for HTML display
* *
*/ */
function smilies($s, $sample = false) { function smilies($s, $sample = false) {
$a = get_app(); $a = get_app();
if(intval(get_config('system','no_smilies')) if(intval(get_config('system','no_smilies'))
|| (local_user() && intval(get_pconfig(local_user(),'system','no_smilies')))) || (local_user() && intval(get_pconfig(local_user(),'system','no_smilies'))))
return $s; return $s;
$s = preg_replace_callback('{<(pre|code)>.*?</\1>}ism','smile_shield',$s); $s = preg_replace_callback('{<(pre|code)>.*?</\1>}ism','smile_shield',$s);
$s = preg_replace_callback('/<[a-z]+ .*?>/ism','smile_shield',$s); $s = preg_replace_callback('/<[a-z]+ .*?>/ism','smile_shield',$s);
@ -1072,7 +1083,6 @@ function smilies($s, $sample = false) {
$s = preg_replace_callback('/<!--base64:(.*?)-->/ism', 'smile_unshield', $s); $s = preg_replace_callback('/<!--base64:(.*?)-->/ism', 'smile_unshield', $s);
return $s; return $s;
} }
function smile_shield($m) { function smile_shield($m) {
@ -1132,6 +1142,7 @@ function normalise_link($url) {
function link_compare($a,$b) { function link_compare($a,$b) {
if(strcasecmp(normalise_link($a),normalise_link($b)) === 0) if(strcasecmp(normalise_link($a),normalise_link($b)) === 0)
return true; return true;
return false; return false;
} }
@ -1147,7 +1158,6 @@ function unobscure(&$item) {
if($item['body']) if($item['body'])
$item['body'] = crypto_unencapsulate(json_decode_plus($item['body']),$key); $item['body'] = crypto_unencapsulate(json_decode_plus($item['body']),$key);
} }
} }
function theme_attachments(&$item) { function theme_attachments(&$item) {
@ -1190,12 +1200,10 @@ function theme_attachments(&$item) {
$url = $r['href']; $url = $r['href'];
else else
$url = z_root() . '/magic?f=&hash=' . $item['author_xchan'] . '&dest=' . $r['href'] . '/' . $r['revision']; $url = z_root() . '/magic?f=&hash=' . $item['author_xchan'] . '&dest=' . $r['href'] . '/' . $r['revision'];
$s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>'; $s .= '<a href="' . $url . '" title="' . $title . '" class="attachlink" >' . $icon . '</a>';
$attaches[] = array('title' => $title, 'url' => $url, 'icon' => $icon ); $attaches[] = array('title' => $title, 'url' => $url, 'icon' => $icon );
} }
} }
$s = replace_macros(get_markup_template('item_attach.tpl'), array( $s = replace_macros(get_markup_template('item_attach.tpl'), array(
@ -1203,13 +1211,12 @@ function theme_attachments(&$item) {
)); ));
return $s; return $s;
} }
function format_categories(&$item,$writeable) { function format_categories(&$item,$writeable) {
$s = ''; $s = '';
$terms = get_terms_oftype($item['term'],TERM_CATEGORY); $terms = get_terms_oftype($item['term'],TERM_CATEGORY);
if($terms) { if($terms) {
$categories = array(); $categories = array();
@ -1225,6 +1232,7 @@ function format_categories(&$item,$writeable) {
'$remove' => t('remove category'), '$remove' => t('remove category'),
'$categories' => $categories '$categories' => $categories
)); ));
return $s; return $s;
} }
@ -1235,7 +1243,6 @@ function format_hashtags(&$item) {
$s = ''; $s = '';
$terms = get_terms_oftype($item['term'],TERM_HASHTAG); $terms = get_terms_oftype($item['term'],TERM_HASHTAG);
if($terms) { if($terms) {
$categories = array();
foreach($terms as $t) { foreach($terms as $t) {
$term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ; $term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ;
if(! trim($term)) if(! trim($term))
@ -1255,11 +1262,10 @@ function format_hashtags(&$item) {
function format_mentions(&$item) { function format_mentions(&$item) {
$s = ''; $s = '';
$terms = get_terms_oftype($item['term'],TERM_MENTION); $terms = get_terms_oftype($item['term'],TERM_MENTION);
if($terms) { if($terms) {
$categories = array();
foreach($terms as $t) { foreach($terms as $t) {
$term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ; $term = htmlspecialchars($t['term'],ENT_COMPAT,'UTF-8',false) ;
if(! trim($term)) if(! trim($term))
@ -1278,8 +1284,8 @@ function format_mentions(&$item) {
function format_filer(&$item) { function format_filer(&$item) {
$s = ''; $s = '';
$terms = get_terms_oftype($item['term'],TERM_FILE); $terms = get_terms_oftype($item['term'],TERM_FILE);
if($terms) { if($terms) {
$categories = array(); $categories = array();
@ -1295,19 +1301,14 @@ function format_filer(&$item) {
'$remove' => t('remove from file'), '$remove' => t('remove from file'),
'$categories' => $categories '$categories' => $categories
)); ));
return $s; return $s;
} }
function prepare_body(&$item,$attach = false) { function prepare_body(&$item,$attach = false) {
$a = get_app();
call_hooks('prepare_body_init', $item); call_hooks('prepare_body_init', $item);
unobscure($item); unobscure($item);
@ -1322,28 +1323,22 @@ function prepare_body(&$item,$attach = false) {
return $s; return $s;
} }
$s .= theme_attachments($item); $s .= theme_attachments($item);
$writeable = ((get_observer_hash() == $item['owner_xchan']) ? true : false); $writeable = ((get_observer_hash() == $item['owner_xchan']) ? true : false);
$s .= format_hashtags($item); $s .= format_hashtags($item);
if($item['resource_type']) if($item['resource_type'])
$s .= format_mentions($item); $s .= format_mentions($item);
$s .= format_categories($item,$writeable); $s .= format_categories($item,$writeable);
if(local_user() == $item['uid']) if(local_user() == $item['uid'])
$s .= format_filer($item); $s .= format_filer($item);
$s = sslify($s); $s = sslify($s);
// Look for spoiler // Look for spoiler
$spoilersearch = '<blockquote class="spoiler">'; $spoilersearch = '<blockquote class="spoiler">';
@ -1366,7 +1361,6 @@ function prepare_body(&$item,$attach = false) {
$authorsearch = '<blockquote class="author">'; $authorsearch = '<blockquote class="author">';
while ((strpos($s, $authorsearch) !== false)) { while ((strpos($s, $authorsearch) !== false)) {
$pos = strpos($s, $authorsearch); $pos = strpos($s, $authorsearch);
$rnd = random_string(8); $rnd = random_string(8);
$authorreplace = '<br /> <span id="author-wrap-'.$rnd.'" style="white-space:nowrap;" class="fakelink" onclick="openClose(\'author-'.$rnd.'\');">'.sprintf(t('Click to open/close')).'</span>'. $authorreplace = '<br /> <span id="author-wrap-'.$rnd.'" style="white-space:nowrap;" class="fakelink" onclick="openClose(\'author-'.$rnd.'\');">'.sprintf(t('Click to open/close')).'</span>'.
@ -1386,10 +1380,7 @@ function prepare_body(&$item,$attach = false) {
function prepare_text($text,$content_type = 'text/bbcode') { function prepare_text($text,$content_type = 'text/bbcode') {
switch($content_type) { switch($content_type) {
case 'text/plain': case 'text/plain':
$s = escape_tags($text); $s = escape_tags($text);
break; break;
@ -1472,14 +1463,11 @@ function zidify_links($s) {
} }
/** /**
* return atom link elements for all of our hubs * return atom link elements for all of our hubs
*/ */
function feed_hublinks() { function feed_hublinks() {
$hub = get_config('system','huburl'); $hub = get_config('system','huburl');
$hubxml = ''; $hubxml = '';
@ -1494,14 +1482,13 @@ function feed_hublinks() {
} }
} }
} }
return $hubxml; return $hubxml;
} }
/* return atom link elements for salmon endpoints */ /* return atom link elements for salmon endpoints */
function feed_salmonlinks($nick) { function feed_salmonlinks($nick) {
$a = get_app(); $a = get_app();
$salmon = '<link rel="salmon" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ; $salmon = '<link rel="salmon" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ;
@ -1510,12 +1497,12 @@ function feed_salmonlinks($nick) {
$salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-replies" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ; $salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-replies" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ;
$salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-mention" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ; $salmon .= ' <link rel="http://salmon-protocol.org/ns/salmon-mention" href="' . xmlify($a->get_baseurl() . '/salmon/' . $nick) . '" />' . "\n" ;
return $salmon; return $salmon;
} }
function get_plink($item,$conversation_mode = true) { function get_plink($item,$conversation_mode = true) {
$a = get_app();
if($conversation_mode) if($conversation_mode)
$key = 'plink'; $key = 'plink';
else else
@ -1558,9 +1545,6 @@ function layout_select($channel_id, $current = '') {
} }
function mimetype_select($channel_id, $current = 'text/bbcode') { function mimetype_select($channel_id, $current = 'text/bbcode') {
$x = array( $x = array(
@ -1591,11 +1575,9 @@ function mimetype_select($channel_id, $current = 'text/bbcode') {
$o .= '</select>'; $o .= '</select>';
return $o; return $o;
} }
function lang_selector() { function lang_selector() {
global $a; global $a;
@ -1627,14 +1609,13 @@ function lang_selector() {
'$langs' => array($lang_options, $selected), '$langs' => array($lang_options, $selected),
)); ));
return $o; return $o;
} }
function return_bytes ($size_str) { function return_bytes ($size_str) {
switch (substr ($size_str, -1)) switch (substr ($size_str, -1)) {
{
case 'M': case 'm': return (int)$size_str * 1048576; case 'M': case 'm': return (int)$size_str * 1048576;
case 'K': case 'k': return (int)$size_str * 1024; case 'K': case 'k': return (int)$size_str * 1024;
case 'G': case 'g': return (int)$size_str * 1073741824; case 'G': case 'g': return (int)$size_str * 1073741824;
@ -1654,7 +1635,6 @@ function base64url_encode($s, $strip_padding = true) {
} }
function base64url_decode($s) { function base64url_decode($s) {
if(is_array($s)) { if(is_array($s)) {
logger('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true)); logger('base64url_decode: illegal input: ' . print_r(debug_backtrace(), true));
return $s; return $s;
@ -1662,7 +1642,11 @@ function base64url_decode($s) {
return base64_decode(strtr($s,'-_','+/')); return base64_decode(strtr($s,'-_','+/'));
} }
/**
* @ Return a div to clear floats.
*
* @return string
*/
function cleardiv() { function cleardiv() {
return '<div class="clear"></div>'; return '<div class="clear"></div>';
} }
@ -1700,15 +1684,14 @@ function html2bb_video($s) {
/** /**
* apply xmlify() to all values of array $val, recursively * apply xmlify() to all values of array $val, recursively
*/ */
function array_xmlify($val){ function array_xmlify($val) {
if (is_bool($val)) return $val?"true":"false"; if (is_bool($val)) return $val?"true":"false";
if (is_array($val)) return array_map('array_xmlify', $val); if (is_array($val)) return array_map('array_xmlify', $val);
return xmlify((string) $val); return xmlify((string) $val);
} }
function reltoabs($text, $base) function reltoabs($text, $base) {
{
if (empty($base)) if (empty($base))
return $text; return $text;
@ -1734,14 +1717,11 @@ function reltoabs($text, $base)
$replace = "<img\${1} src=\"" . $base . "\${2}\""; $replace = "<img\${1} src=\"" . $base . "\${2}\"";
$text = preg_replace($pattern, $replace, $text); $text = preg_replace($pattern, $replace, $text);
// Done // Done
return $text; return $text;
} }
function item_post_type($item) { function item_post_type($item) {
switch($item['resource_type']) { switch($item['resource_type']) {
case 'photo': case 'photo':
$post_type = t('photo'); $post_type = t('photo');
@ -1796,6 +1776,7 @@ function is_a_date_arg($s) {
return true; return true;
} }
} }
return false; return false;
} }
@ -1847,6 +1828,7 @@ function check_webbie($arr) {
} }
} }
} }
return ''; return '';
} }
@ -1855,6 +1837,7 @@ function ids_to_querystr($arr,$idx = 'id') {
$t = array(); $t = array();
foreach($arr as $x) foreach($arr as $x)
$t[] = $x[$idx]; $t[] = $x[$idx];
return(implode(',', $t)); return(implode(',', $t));
} }
@ -1903,7 +1886,6 @@ function xchan_query(&$items,$abook = true,$effective_uid = 0) {
$items[$x]['author'] = find_xchan_in_array($items[$x]['author_xchan'],$chans); $items[$x]['author'] = find_xchan_in_array($items[$x]['author_xchan'],$chans);
} }
} }
} }
function xchan_mail_query(&$item) { function xchan_mail_query(&$item) {
@ -1943,6 +1925,7 @@ function get_rel_link($j,$rel) {
foreach($j as $l) foreach($j as $l)
if($l['rel'] === $rel) if($l['rel'] === $rel)
return $l['href']; return $l['href'];
return ''; return '';
} }
@ -1978,7 +1961,6 @@ function jindent($json) {
$outOfQuotes = true; $outOfQuotes = true;
for ($i=0; $i<=$strLen; $i++) { for ($i=0; $i<=$strLen; $i++) {
// Grab the next character in the string. // Grab the next character in the string.
$char = substr($json, $i, 1); $char = substr($json, $i, 1);
@ -2020,12 +2002,11 @@ function jindent($json) {
function json_decode_plus($s) { function json_decode_plus($s) {
$x = json_decode($s,true); $x = json_decode($s,true);
if(! $x) if(! $x)
$x = json_decode(str_replace(array('\\"','\\\\'),array('"','\\'),$s),true); $x = json_decode(str_replace(array('\\"','\\\\'),array('"','\\'),$s),true);
return $x;
return $x;
} }
@ -2105,12 +2086,10 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) {
$replaced = false; $replaced = false;
$r = null; $r = null;
$termtype = ((strpos($tag,'#') === 0) ? TERM_HASHTAG : TERM_UNKNOWN); $termtype = ((strpos($tag,'#') === 0) ? TERM_HASHTAG : TERM_UNKNOWN);
$termtype = ((strpos($tag,'@') === 0) ? TERM_MENTION : $termtype); $termtype = ((strpos($tag,'@') === 0) ? TERM_MENTION : $termtype);
$termtype = ((strpos($tag,'#^[') === 0) ? TERM_BOOKMARK : $termtype); $termtype = ((strpos($tag,'#^[') === 0) ? TERM_BOOKMARK : $termtype);
//is it a hash tag? //is it a hash tag?
if(strpos($tag,'#') === 0) { if(strpos($tag,'#') === 0) {
if(strpos($tag,'#^[') === 0) { if(strpos($tag,'#^[') === 0) {
@ -2118,7 +2097,6 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) {
$basetag = $match[3]; $basetag = $match[3];
$url = ((substr($match[2],0,1) === '=') ? substr($match[2],1) : $match[3]); $url = ((substr($match[2],0,1) === '=') ? substr($match[2],1) : $match[3]);
$replaced = true; $replaced = true;
} }
} }
// if the tag is already replaced... // if the tag is already replaced...
@ -2156,6 +2134,7 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) {
//append or set str_tags //append or set str_tags
if(strlen($str_tags)) if(strlen($str_tags))
$str_tags .= ','; $str_tags .= ',';
$str_tags .= $newtag; $str_tags .= $newtag;
} }
return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $basetag, 'url' => $url, 'contact' => $r[0]); return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $basetag, 'url' => $url, 'contact' => $r[0]);
@ -2264,7 +2243,6 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) {
} }
if(! $r) { if(! $r) {
// it's possible somebody has a name ending with '+', which we stripped off as a forum indicator // it's possible somebody has a name ending with '+', which we stripped off as a forum indicator
// This is very rare but we want to get it right. // This is very rare but we want to get it right.
@ -2340,6 +2318,5 @@ function handle_tag($a, &$body, &$access_tag, &$str_tags, $profile_uid, $tag) {
} }
} }
return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $newname, 'url' => $url, 'contact' => $r[0]); return array('replaced' => $replaced, 'termtype' => $termtype, 'term' => $newname, 'url' => $url, 'contact' => $r[0]);
} }