diff --git a/actions/all.php b/actions/all.php index 9c01b63938..ac4e321d0f 100644 --- a/actions/all.php +++ b/actions/all.php @@ -143,10 +143,10 @@ class AllAction extends ProfileAction $message .= _('Try subscribing to more people, [join a group](%%action.groups%%) or post something yourself.'); } else { // TRANS: %1$s is user nickname, %2$s is user nickname, %2$s is user nickname prefixed with "@" - $message .= sprintf(_('You can try to [nudge %1$s](../%2$s) from his profile or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname); + $message .= sprintf(_('You can try to [nudge %1$s](../%2$s) from their profile or [post something to their attention](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname); } } else { - $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to his or her attention.'), $this->user->nickname); + $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to their attention.'), $this->user->nickname); } $this->elementStart('div', 'guide'); diff --git a/actions/favor.php b/actions/favor.php index 475912fd0b..01976a38f5 100644 --- a/actions/favor.php +++ b/actions/favor.php @@ -104,7 +104,7 @@ class FavorAction extends Action } /** - * Notifies a user when his notice is favorited. + * Notifies a user when their notice is favorited. * * @param class $notice favorited notice * @param class $user user declaring a favorite diff --git a/actions/finishremotesubscribe.php b/actions/finishremotesubscribe.php index ac51ddec3f..0325f6adbb 100644 --- a/actions/finishremotesubscribe.php +++ b/actions/finishremotesubscribe.php @@ -37,7 +37,7 @@ require_once INSTALLDIR.'/lib/omb.php'; * Handler for remote subscription finish callback * * When a remote user subscribes a local user, a redirect to this action is - * issued after the remote user authorized his service to subscribe. + * issued after the remote user authorized their service to subscribe. * * @category Action * @package Laconica diff --git a/actions/nudge.php b/actions/nudge.php index cf5f773e71..32ae8587cc 100644 --- a/actions/nudge.php +++ b/actions/nudge.php @@ -82,7 +82,7 @@ class NudgeAction extends Action } if (!$other->email || !$other->emailnotifynudge) { - $this->clientError(_('This user doesn\'t allow nudges or hasn\'t confirmed or set his email yet.')); + $this->clientError(_('This user doesn\'t allow nudges or hasn\'t confirmed or set their email yet.')); return; } diff --git a/actions/replies.php b/actions/replies.php index 608f71d6e0..0474a6de04 100644 --- a/actions/replies.php +++ b/actions/replies.php @@ -196,18 +196,18 @@ class RepliesAction extends OwnerDesignAction function showEmptyListMessage() { - $message = sprintf(_('This is the timeline showing replies to %1$s but %2$s hasn\'t received a notice to his attention yet.'), $this->user->nickname, $this->user->nickname) . ' '; + $message = sprintf(_('This is the timeline showing replies to %1$s but %2$s hasn\'t received a notice to their attention yet.'), $this->user->nickname, $this->user->nickname) . ' '; if (common_logged_in()) { $current_user = common_current_user(); if ($this->user->id === $current_user->id) { $message .= _('You can engage other users in a conversation, subscribe to more people or [join groups](%%action.groups%%).'); } else { - $message .= sprintf(_('You can try to [nudge %1$s](../%2$s) or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname); + $message .= sprintf(_('You can try to [nudge %1$s](../%2$s) or [post something to their attention](%%%%action.newnotice%%%%?status_textarea=%3$s).'), $this->user->nickname, $this->user->nickname, '@' . $this->user->nickname); } } else { - $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to his or her attention.'), $this->user->nickname); + $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to their attention.'), $this->user->nickname); } $this->elementStart('div', 'guide'); diff --git a/actions/showfavorites.php b/actions/showfavorites.php index 7f3c77ee24..d8042e91c7 100644 --- a/actions/showfavorites.php +++ b/actions/showfavorites.php @@ -119,7 +119,7 @@ class ShowfavoritesAction extends OwnerDesignAction if (!empty($cur) && $cur->id == $this->user->id) { // Show imported/gateway notices as well as local if - // the user is looking at his own favorites + // the user is looking at their own favorites $this->notice = $this->user->favoriteNotices(true, ($this->page-1)*NOTICES_PER_PAGE, NOTICES_PER_PAGE + 1); @@ -205,11 +205,11 @@ class ShowfavoritesAction extends OwnerDesignAction if ($this->user->id === $current_user->id) { $message = _('You haven\'t chosen any favorite notices yet. Click the fave button on notices you like to bookmark them for later or shed a spotlight on them.'); } else { - $message = sprintf(_('%s hasn\'t added any notices to his favorites yet. Post something interesting they would add to their favorites :)'), $this->user->nickname); + $message = sprintf(_('%s hasn\'t added any favorite notices yet. Post something interesting they would add to their favorites :)'), $this->user->nickname); } } else { - $message = sprintf(_('%s hasn\'t added any notices to his favorites yet. Why not [register an account](%%%%action.register%%%%) and then post something interesting they would add to their favorites :)'), $this->user->nickname); + $message = sprintf(_('%s hasn\'t added any favorite notices yet. Why not [register an account](%%%%action.register%%%%) and then post something interesting they would add to their favorites :)'), $this->user->nickname); } $this->elementStart('div', 'guide'); diff --git a/actions/showstream.php b/actions/showstream.php index f9407e35a1..956c057415 100644 --- a/actions/showstream.php +++ b/actions/showstream.php @@ -204,11 +204,11 @@ class ShowstreamAction extends ProfileAction if ($this->user->id === $current_user->id) { $message .= _('Seen anything interesting recently? You haven\'t posted any notices yet, now would be a good time to start :)'); } else { - $message .= sprintf(_('You can try to nudge %1$s or [post something to his or her attention](%%%%action.newnotice%%%%?status_textarea=%2$s).'), $this->user->nickname, '@' . $this->user->nickname); + $message .= sprintf(_('You can try to nudge %1$s or [post something to their attention](%%%%action.newnotice%%%%?status_textarea=%2$s).'), $this->user->nickname, '@' . $this->user->nickname); } } else { - $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to his or her attention.'), $this->user->nickname); + $message .= sprintf(_('Why not [register an account](%%%%action.register%%%%) and then nudge %s or post a notice to their attention.'), $this->user->nickname); } $this->elementStart('div', 'guide'); diff --git a/classes/Notice.php b/classes/Notice.php index ae7e2e5402..8552248bad 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -42,10 +42,10 @@ if (!defined('STATUSNET') && !defined('LACONICA')) { */ require_once INSTALLDIR.'/classes/Memcached_DataObject.php'; -/* We keep the first three 20-notice pages, plus one for pagination check, +/* We keep 200 notices, the max number of notices available per API request, * in the memcached cache. */ -define('NOTICE_CACHE_WINDOW', 61); +define('NOTICE_CACHE_WINDOW', 200); define('MAX_BOXCARS', 128); diff --git a/classes/User.php b/classes/User.php index 2abb7eeb69..cf8d4527b8 100644 --- a/classes/User.php +++ b/classes/User.php @@ -524,7 +524,7 @@ class User extends Memcached_DataObject if ($this->id == $other->id) { common_log(LOG_WARNING, sprintf( - "Profile ID %d (%s) tried to block his or herself.", + "Profile ID %d (%s) tried to block themself.", $this->id, $this->nickname ) diff --git a/extlib/Auth/OpenID/Association.php b/extlib/Auth/OpenID/Association.php index d1ac1ed9b9..7fdf399a3c 100644 --- a/extlib/Auth/OpenID/Association.php +++ b/extlib/Auth/OpenID/Association.php @@ -374,7 +374,42 @@ class Auth_OpenID_Association { } $calculated_sig = $this->getMessageSignature($message); - return $calculated_sig == $sig; + + return $this->constantTimeCompare($calculated_sig, $sig); + } + + /** + * String comparison function which will complete in a constant time + * for strings of any given matching length, to help prevent an attacker + * from distinguishing how much of a signature token they have guessed + * correctly. + * + * For this usage, it's assumed that the length of the string is known, + * so we may safely short-circuit on mismatched lengths which will be known + * to be invalid by the attacker. + * + * http://lists.openid.net/pipermail/openid-security/2010-July/001156.html + * http://rdist.root.org/2010/01/07/timing-independent-array-comparison/ + */ + private function constantTimeCompare($a, $b) + { + $len = strlen($a); + if (strlen($b) !== $len) { + // Short-circuit on length mismatch; attackers will already know + // the correct target length so this is safe. + return false; + } + if ($len == 0) { + // 0-length valid input shouldn't really happen. :) + return true; + } + $result = 0; + for ($i = 0; $i < strlen($a); $i++) { + // We use scary bitwise operations to avoid logical short-circuits + // in lower-level code. + $result |= ord($a{$i}) ^ ord($b{$i}); + } + return ($result == 0); } } diff --git a/extlib/OAuth.php b/extlib/OAuth.php index 648627b576..04984d5fa0 100644 --- a/extlib/OAuth.php +++ b/extlib/OAuth.php @@ -54,6 +54,24 @@ class OAuthSignatureMethod {/*{{{*/ public function check_signature(&$request, $consumer, $token, $signature) { $built = $this->build_signature($request, $consumer, $token); return $built == $signature; + + // Check for zero length, although unlikely here + if (strlen($built) == 0 || strlen($signature) == 0) { + return false; + } + + if (strlen($built) != strlen($signature)) { + return false; + } + + $result = 0; + + // Avoid a timing leak with a (hopefully) time insensitive compare + for ($i = 0; $i < strlen($signature); $i++) { + $result |= ord($built{$i}) ^ ord($signature{$i}); + } + + return $result == 0; } }/*}}}*/ diff --git a/lib/activityutils.php b/lib/activityutils.php index 401fd7fc28..dd38d4e142 100644 --- a/lib/activityutils.php +++ b/lib/activityutils.php @@ -257,6 +257,12 @@ class ActivityUtils */ static function validateUri($uri) { + // Check mailto: URIs first + + if (preg_match('/^mailto:(.*)$/', $uri, $match)) { + return Validate::email($match[1], common_config('email', 'check_domain')); + } + if (Validate::uri($uri)) { return true; } diff --git a/theme/biz/css/display.css b/theme/biz/css/display.css index ea09ef4c0f..e735d8683f 100644 --- a/theme/biz/css/display.css +++ b/theme/biz/css/display.css @@ -7,7 +7,7 @@ * @link http://status.net/ */ -@import url(base.css) screen, projection, tv, print; +@import url(base.css); @media screen, projection, tv { html { diff --git a/theme/default/css/display.css b/theme/default/css/display.css index 5e3748cb7a..9a1dabb515 100644 --- a/theme/default/css/display.css +++ b/theme/default/css/display.css @@ -7,7 +7,7 @@ * @link http://status.net/ */ -@import url(../../base/css/display.css) screen, projection, tv, print; +@import url(../../base/css/display.css); @media screen, projection, tv { body, diff --git a/theme/identica/css/display.css b/theme/identica/css/display.css index 440dd8be22..d7f150bcb0 100644 --- a/theme/identica/css/display.css +++ b/theme/identica/css/display.css @@ -7,7 +7,7 @@ * @link http://status.net/ */ -@import url(../../base/css/display.css) screen, projection, tv, print; +@import url(../../base/css/display.css); @media screen, projection, tv { body, diff --git a/theme/pigeonthoughts/css/display.css b/theme/pigeonthoughts/css/display.css index e584683fcd..3d6db00e14 100644 --- a/theme/pigeonthoughts/css/display.css +++ b/theme/pigeonthoughts/css/display.css @@ -7,7 +7,7 @@ * @link http://status.net/ */ -@import url(base.css) screen, projection, tv, print; +@import url(base.css); @media screen, projection, tv { html {