From ed5828f30ea0f7a30e01d407058990b06164c6f3 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 8 Jan 2010 17:20:25 -0800 Subject: [PATCH 01/16] Redirect to a one-time-password when ssl and regular server are different --- actions/login.php | 95 +++++++++++++------------- actions/otp.php | 145 ++++++++++++++++++++++++++++++++++++++++ classes/Login_token.php | 27 ++++++++ lib/command.php | 24 +++---- lib/router.php | 5 +- 5 files changed, 233 insertions(+), 63 deletions(-) create mode 100644 actions/otp.php diff --git a/actions/login.php b/actions/login.php index c775fa6924..a2f853e3a4 100644 --- a/actions/login.php +++ b/actions/login.php @@ -76,15 +76,10 @@ class LoginAction extends Action { parent::handle($args); - $disabled = common_config('logincommand','disabled'); - $disabled = isset($disabled) && $disabled; - if (common_is_real_login()) { $this->clientError(_('Already logged in.')); } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { $this->checkLogin(); - } else if (!$disabled && isset($args['user_id']) && isset($args['token'])){ - $this->checkLogin($args['user_id'],$args['token']); } else { common_ensure_session(); $this->showForm(); @@ -103,46 +98,21 @@ class LoginAction extends Action function checkLogin($user_id=null, $token=null) { - if(isset($token) && isset($user_id)){ - //Token based login (from the LoginCommand) - $login_token = Login_token::staticGet('user_id',$user_id); - if($login_token && $login_token->token == $token){ - if($login_token->modified > time()+2*60){ - //token has expired - //delete the token as it is useless - $login_token->delete(); - $this->showForm(_('Invalid or expired token.')); - return; - }else{ - //delete the token so it cannot be reused - $login_token->delete(); - //it's a valid token - let them log in - $user = User::staticGet('id', $user_id); - //$user = User::staticGet('nickname', "candrews"); - } - }else{ - $this->showForm(_('Invalid or expired token.')); - return; - } - }else{ - // Regular form submission login + // XXX: login throttle - // XXX: login throttle - - // CSRF protection - token set in NoticeForm - $token = $this->trimmed('token'); - if (!$token || $token != common_session_token()) { - $this->clientError(_('There was a problem with your session token. '. - 'Try again, please.')); - return; - } - - $nickname = $this->trimmed('nickname'); - $password = $this->arg('password'); - - $user = common_check_user($nickname, $password); + // CSRF protection - token set in NoticeForm + $token = $this->trimmed('token'); + if (!$token || $token != common_session_token()) { + $this->clientError(_('There was a problem with your session token. '. + 'Try again, please.')); + return; } + $nickname = $this->trimmed('nickname'); + $password = $this->arg('password'); + + $user = common_check_user($nickname, $password); + if (!$user) { $this->showForm(_('Incorrect username or password.')); return; @@ -162,6 +132,12 @@ class LoginAction extends Action $url = common_get_returnto(); + if (common_config('ssl', 'sometimes') && // mixed environment + common_config('site', 'server') != common_config('site', 'sslserver')) { + $this->redirectFromSSL($user, $url, $this->boolean('rememberme')); + return; + } + if ($url) { // We don't have to return to it again common_set_returnto(null); @@ -240,9 +216,9 @@ class LoginAction extends Action function showContent() { $this->elementStart('form', array('method' => 'post', - 'id' => 'form_login', - 'class' => 'form_settings', - 'action' => common_local_url('login'))); + 'id' => 'form_login', + 'class' => 'form_settings', + 'action' => common_local_url('login'))); $this->elementStart('fieldset'); $this->element('legend', null, _('Login to site')); $this->elementStart('ul', 'form_data'); @@ -255,7 +231,7 @@ class LoginAction extends Action $this->elementStart('li'); $this->checkbox('rememberme', _('Remember me'), false, _('Automatically login in the future; ' . - 'not for shared computers!')); + 'not for shared computers!')); $this->elementEnd('li'); $this->elementEnd('ul'); $this->submit('submit', _('Login')); @@ -306,4 +282,31 @@ class LoginAction extends Action $nav = new LoginGroupNav($this); $nav->show(); } + + function redirectFromSSL($user, $returnto, $rememberme) + { + try { + $login_token = Login_token::makeNew($user); + } catch (Exception $e) { + $this->serverError($e->getMessage()); + return; + } + + $params = array(); + + if (!empty($returnto)) { + $params['returnto'] = $returnto; + } + + if (!empty($rememberme)) { + $params['rememberme'] = $rememberme; + } + + $target = common_local_url('otp', + array('user_id' => $login_token->user_id, + 'token' => $login_token->token), + $params); + + common_redirect($target, 303); + } } diff --git a/actions/otp.php b/actions/otp.php new file mode 100644 index 0000000000..acf84aee81 --- /dev/null +++ b/actions/otp.php @@ -0,0 +1,145 @@ +. + * + * @category Login + * @package StatusNet + * @author Evan Prodromou + * @copyright 2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3 + * @link http://status.net/ + */ + +if (!defined('STATUSNET')) { + exit(1); +} + +/** + * Allow one-time password login + * + * This action will automatically log in the user identified by the user_id + * parameter. A login_token record must be constructed beforehand, typically + * by code where the user is already authenticated. + * + * @category Login + * @package StatusNet + * @author Evan Prodromou + * @copyright 2010 StatusNet, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPLv3 + * @link http://status.net/ + */ + +class OtpAction extends Action +{ + var $user; + var $token; + var $rememberme; + var $returnto; + var $lt; + + function prepare($args) + { + parent::prepare($args); + + if (common_is_real_login()) { + $this->clientError(_('Already logged in.')); + return false; + } + + $id = $this->trimmed('user_id'); + + if (empty($id)) { + $this->clientError(_('No user ID specified.')); + return false; + } + + $this->user = User::staticGet('id', $id); + + if (empty($this->user)) { + $this->clientError(_('No such user.')); + return false; + } + + $this->token = $this->trimmed('token'); + + if (empty($this->token)) { + $this->clientError(_('No login token specified.')); + return false; + } + + $this->lt = Login_token::staticGet('user_id', $id); + + if (empty($this->lt)) { + $this->clientError(_('No login token requested.')); + return false; + } + + if ($this->lt->token != $this->token) { + $this->clientError(_('Invalid login token specified.')); + return false; + } + + if ($this->lt->modified > time() + Login_token::TIMEOUT) { + //token has expired + //delete the token as it is useless + $this->lt->delete(); + $this->lt = null; + $this->clientError(_('Login token expired.')); + return false; + } + + $this->rememberme = $this->boolean('rememberme'); + $this->returnto = $this->trimmed('returnto'); + + return true; + } + + function handle($args) + { + parent::handle($args); + + // success! + if (!common_set_user($this->user)) { + $this->serverError(_('Error setting user. You are probably not authorized.')); + return; + } + + // We're now logged in; disable the lt + + $this->lt->delete(); + $this->lt = null; + + if ($this->rememberme) { + common_rememberme($this->user); + } + + if (!empty($this->returnto)) { + $url = $this->returnto; + // We don't have to return to it again + common_set_returnto(null); + } else { + $url = common_local_url('all', + array('nickname' => + $this->user->nickname)); + } + + common_redirect($url, 303); + } +} diff --git a/classes/Login_token.php b/classes/Login_token.php index 746cd7f229..51dc61262e 100644 --- a/classes/Login_token.php +++ b/classes/Login_token.php @@ -40,6 +40,8 @@ class Login_token extends Memcached_DataObject /* the code above is auto generated do not remove the tag below */ ###END_AUTOCODE + const TIMEOUT = 120; // seconds after which to timeout the token + /* DB_DataObject calculates the sequence key(s) by taking the first key returned by the keys() function. In this case, the keys() function returns user_id as the first key. user_id is not a sequence, but @@ -52,4 +54,29 @@ class Login_token extends Memcached_DataObject { return array(false,false); } + + function makeNew($user) + { + $login_token = Login_token::staticGet('user_id', $user->id); + + if (!empty($login_token)) { + $login_token->delete(); + } + + $login_token = new Login_token(); + + $login_token->user_id = $user->id; + $login_token->token = common_good_rand(16); + $login_token->created = common_sql_now(); + + $result = $login_token->insert(); + + if (!$result) { + common_log_db_error($login_token, 'INSERT', __FILE__); + throw new Exception(sprintf(_('Could not create login token for %s'), + $user->nickname)); + } + + return $login_token; + } } diff --git a/lib/command.php b/lib/command.php index 67140c3485..f846fb823f 100644 --- a/lib/command.php +++ b/lib/command.php @@ -650,25 +650,17 @@ class LoginCommand extends Command $channel->error($this->user, _('Login command is disabled')); return; } - $login_token = Login_token::staticGet('user_id',$this->user->id); - if($login_token){ - $login_token->delete(); - } - $login_token = new Login_token(); - $login_token->user_id = $this->user->id; - $login_token->token = common_good_rand(16); - $login_token->created = common_sql_now(); - $result = $login_token->insert(); - if (!$result) { - common_log_db_error($login_token, 'INSERT', __FILE__); - $channel->error($this->user, sprintf(_('Could not create login token for %s'), - $this->user->nickname)); - return; + + try { + $login_token = Login_token::makeNew($this->user); + } catch (Exception $e) { + $channel->error($this->user, $e->getMessage()); } + $channel->output($this->user, sprintf(_('This link is useable only once, and is good for only 2 minutes: %s'), - common_local_url('login', - array('user_id'=>$login_token->user_id, 'token'=>$login_token->token)))); + common_local_url('otp', + array('user_id' => $login_token->user_id, 'token' => $login_token->token)))); } } diff --git a/lib/router.php b/lib/router.php index 287d3c79fd..4128741a84 100644 --- a/lib/router.php +++ b/lib/router.php @@ -88,7 +88,10 @@ class Router $m->connect('doc/:title', array('action' => 'doc')); - $m->connect('main/login?user_id=:user_id&token=:token', array('action'=>'login'), array('user_id'=> '[0-9]+', 'token'=>'.+')); + $m->connect('main/otp/:user_id/:token', + array('action' => 'otp'), + array('user_id' => '[0-9]+', + 'token' => '.+')); // main stuff is repetitive From 5ca41b68703e8d8e41325ab4dd9c798946fc7a10 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 9 Jan 2010 16:19:45 -0800 Subject: [PATCH 02/16] redirect to sitename.wildcard for SSL --- classes/Status_network.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/classes/Status_network.php b/classes/Status_network.php index b3117640d8..8dff879dfe 100644 --- a/classes/Status_network.php +++ b/classes/Status_network.php @@ -150,9 +150,18 @@ class Status_network extends DB_DataObject } if (!empty($sn)) { - if (!empty($sn->hostname) && 0 != strcasecmp($sn->hostname, $servername)) { - $sn->redirectToHostname(); + + // Redirect to the right URL + + if (!empty($sn->hostname) && + empty($SERVER['HTTPS']) && + 0 != strcasecmp($sn->hostname, $servername)) { + $sn->redirectTo('http://'.$sn->hostname.$_SERVER['REQUEST_URI']); + } else if (!empty($SERVER['HTTPS']) && + 0 != strcasecmp($sn->sitename.'.'.$wildcard, $servername)) { + $sn->redirectTo('https://'.$sn->sitename.'.'.$wildcard.$_SERVER['REQUEST_URI']); } + $dbhost = (empty($sn->dbhost)) ? 'localhost' : $sn->dbhost; $dbuser = (empty($sn->dbuser)) ? $sn->nickname : $sn->dbuser; $dbpass = $sn->dbpass; @@ -179,11 +188,8 @@ class Status_network extends DB_DataObject // (C) 2006 by Heiko Richler http://www.richler.de/ // LGPL - function redirectToHostname() + function redirectTo($destination) { - $destination = 'http://'.$this->hostname; - $destination .= $_SERVER['REQUEST_URI']; - $old = 'http'. (($_SERVER['HTTPS'] == 'on') ? 'S' : ''). '://'. From 6d66a28b3591b579f0230620339882e9ba8078ab Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 9 Jan 2010 16:23:41 -0800 Subject: [PATCH 03/16] Use OTP to set cookies from registration action --- actions/register.php | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/actions/register.php b/actions/register.php index 57f8e7bdf0..108d05f5a7 100644 --- a/actions/register.php +++ b/actions/register.php @@ -259,6 +259,16 @@ class RegisterAction extends Action // Re-init language env in case it changed (not yet, but soon) common_init_language(); + + if (common_config('ssl', 'sometimes') && // mixed environment + common_config('site', 'server') != common_config('site', 'sslserver')) { + $url = common_local_url('all', + array('nickname' => + $user->nickname)); + $this->redirectFromSSL($user, $url, $this->boolean('rememberme')); + return; + } + $this->showSuccess(); } else { $this->showForm(_('Invalid username or password.')); @@ -578,5 +588,32 @@ class RegisterAction extends Action $nav = new LoginGroupNav($this); $nav->show(); } + + function redirectFromSSL($user, $returnto, $rememberme) + { + try { + $login_token = Login_token::makeNew($user); + } catch (Exception $e) { + $this->serverError($e->getMessage()); + return; + } + + $params = array(); + + if (!empty($returnto)) { + $params['returnto'] = $returnto; + } + + if (!empty($rememberme)) { + $params['rememberme'] = $rememberme; + } + + $target = common_local_url('otp', + array('user_id' => $login_token->user_id, + 'token' => $login_token->token), + $params); + + common_redirect($target, 303); + } } From deb5ee61542d01d90c0b0a462d5be2fdf5b876bb Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 9 Jan 2010 16:31:25 -0800 Subject: [PATCH 04/16] correct superglobal variable name --- classes/Status_network.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/Status_network.php b/classes/Status_network.php index 8dff879dfe..dce3e0b8f5 100644 --- a/classes/Status_network.php +++ b/classes/Status_network.php @@ -154,10 +154,10 @@ class Status_network extends DB_DataObject // Redirect to the right URL if (!empty($sn->hostname) && - empty($SERVER['HTTPS']) && + empty($_SERVER['HTTPS']) && 0 != strcasecmp($sn->hostname, $servername)) { $sn->redirectTo('http://'.$sn->hostname.$_SERVER['REQUEST_URI']); - } else if (!empty($SERVER['HTTPS']) && + } else if (!empty($_SERVER['HTTPS']) && 0 != strcasecmp($sn->sitename.'.'.$wildcard, $servername)) { $sn->redirectTo('https://'.$sn->sitename.'.'.$wildcard.$_SERVER['REQUEST_URI']); } From e8d85a1ef5966ba89ea88a6d706a066986e1dceb Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 9 Jan 2010 22:48:05 -0800 Subject: [PATCH 05/16] use nickname, not sitename, in domain for SSL --- classes/Status_network.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/Status_network.php b/classes/Status_network.php index dce3e0b8f5..96212c4657 100644 --- a/classes/Status_network.php +++ b/classes/Status_network.php @@ -158,8 +158,8 @@ class Status_network extends DB_DataObject 0 != strcasecmp($sn->hostname, $servername)) { $sn->redirectTo('http://'.$sn->hostname.$_SERVER['REQUEST_URI']); } else if (!empty($_SERVER['HTTPS']) && - 0 != strcasecmp($sn->sitename.'.'.$wildcard, $servername)) { - $sn->redirectTo('https://'.$sn->sitename.'.'.$wildcard.$_SERVER['REQUEST_URI']); + 0 != strcasecmp($sn->nickname.'.'.$wildcard, $servername)) { + $sn->redirectTo('https://'.$sn->nickname.'.'.$wildcard.$_SERVER['REQUEST_URI']); } $dbhost = (empty($sn->dbhost)) ? 'localhost' : $sn->dbhost; From 3d723ed1ed0755a4ad30e1d3388d663f53193295 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sat, 9 Jan 2010 22:49:26 -0800 Subject: [PATCH 06/16] allow hostname with SSL --- classes/Status_network.php | 1 + 1 file changed, 1 insertion(+) diff --git a/classes/Status_network.php b/classes/Status_network.php index 96212c4657..1f0e602cf7 100644 --- a/classes/Status_network.php +++ b/classes/Status_network.php @@ -158,6 +158,7 @@ class Status_network extends DB_DataObject 0 != strcasecmp($sn->hostname, $servername)) { $sn->redirectTo('http://'.$sn->hostname.$_SERVER['REQUEST_URI']); } else if (!empty($_SERVER['HTTPS']) && + 0 != strcasecmp($sn->hostname, $servername) && 0 != strcasecmp($sn->nickname.'.'.$wildcard, $servername)) { $sn->redirectTo('https://'.$sn->nickname.'.'.$wildcard.$_SERVER['REQUEST_URI']); } From 304f3b4f188d92720848ae1e3ac85ee04bd5ef71 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 10 Jan 2010 00:18:17 -0800 Subject: [PATCH 07/16] correctly check for ssl enabled --- actions/login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/login.php b/actions/login.php index a2f853e3a4..ea9b96a46b 100644 --- a/actions/login.php +++ b/actions/login.php @@ -133,7 +133,7 @@ class LoginAction extends Action $url = common_get_returnto(); if (common_config('ssl', 'sometimes') && // mixed environment - common_config('site', 'server') != common_config('site', 'sslserver')) { + 0 != strcasecmp(common_config('site', 'server'), common_config('site', 'sslserver'))) { $this->redirectFromSSL($user, $url, $this->boolean('rememberme')); return; } From 06ed0bc7913e6af0a4aaab93459148c690be70f1 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 10 Jan 2010 00:19:46 -0800 Subject: [PATCH 08/16] correctly check for ssl enabled --- actions/register.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/actions/register.php b/actions/register.php index 108d05f5a7..ec6534eee0 100644 --- a/actions/register.php +++ b/actions/register.php @@ -260,8 +260,9 @@ class RegisterAction extends Action // Re-init language env in case it changed (not yet, but soon) common_init_language(); - if (common_config('ssl', 'sometimes') && // mixed environment - common_config('site', 'server') != common_config('site', 'sslserver')) { + if (common_config('site', 'ssl') == 'sometimes' && // mixed environment + 0 != strcasecmp(common_config('site', 'server'), common_config('site', 'sslserver'))) { + $url = common_local_url('all', array('nickname' => $user->nickname)); From e2dee5fedbedef69fbc825fcac39973f91f09c1a Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 10 Jan 2010 00:20:08 -0800 Subject: [PATCH 09/16] always set site/server to hostname if it exists --- classes/Status_network.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/classes/Status_network.php b/classes/Status_network.php index 1f0e602cf7..776f6abb03 100644 --- a/classes/Status_network.php +++ b/classes/Status_network.php @@ -170,7 +170,11 @@ class Status_network extends DB_DataObject $config['db']['database'] = "mysqli://$dbuser:$dbpass@$dbhost/$dbname"; - $config['site']['name'] = $sn->sitename; + $config['site']['name'] = $sn->sitename; + + if (!empty($sn->hostname)) { + $config['site']['server'] = $sn->hostname; + } if (!empty($sn->theme)) { $config['site']['theme'] = $sn->theme; From 8c6ec0b59ef282c5b2910689255b52de99d477a2 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 10 Jan 2010 00:23:26 -0800 Subject: [PATCH 10/16] fix check for ssl diff in login --- actions/login.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/actions/login.php b/actions/login.php index ea9b96a46b..8694de188e 100644 --- a/actions/login.php +++ b/actions/login.php @@ -132,7 +132,7 @@ class LoginAction extends Action $url = common_get_returnto(); - if (common_config('ssl', 'sometimes') && // mixed environment + if (common_config('site', 'ssl') == 'sometimes' && // mixed environment 0 != strcasecmp(common_config('site', 'server'), common_config('site', 'sslserver'))) { $this->redirectFromSSL($user, $url, $this->boolean('rememberme')); return; From 54d532e12f5dac8924d30d21c15f331ce5d16550 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 10 Jan 2010 22:58:33 -0800 Subject: [PATCH 11/16] remove redirect to OTP on login from login, register --- actions/login.php | 33 --------------------------------- actions/register.php | 37 ------------------------------------- 2 files changed, 70 deletions(-) diff --git a/actions/login.php b/actions/login.php index 8694de188e..9c47d88b14 100644 --- a/actions/login.php +++ b/actions/login.php @@ -132,12 +132,6 @@ class LoginAction extends Action $url = common_get_returnto(); - if (common_config('site', 'ssl') == 'sometimes' && // mixed environment - 0 != strcasecmp(common_config('site', 'server'), common_config('site', 'sslserver'))) { - $this->redirectFromSSL($user, $url, $this->boolean('rememberme')); - return; - } - if ($url) { // We don't have to return to it again common_set_returnto(null); @@ -282,31 +276,4 @@ class LoginAction extends Action $nav = new LoginGroupNav($this); $nav->show(); } - - function redirectFromSSL($user, $returnto, $rememberme) - { - try { - $login_token = Login_token::makeNew($user); - } catch (Exception $e) { - $this->serverError($e->getMessage()); - return; - } - - $params = array(); - - if (!empty($returnto)) { - $params['returnto'] = $returnto; - } - - if (!empty($rememberme)) { - $params['rememberme'] = $rememberme; - } - - $target = common_local_url('otp', - array('user_id' => $login_token->user_id, - 'token' => $login_token->token), - $params); - - common_redirect($target, 303); - } } diff --git a/actions/register.php b/actions/register.php index ec6534eee0..6339ea1171 100644 --- a/actions/register.php +++ b/actions/register.php @@ -260,16 +260,6 @@ class RegisterAction extends Action // Re-init language env in case it changed (not yet, but soon) common_init_language(); - if (common_config('site', 'ssl') == 'sometimes' && // mixed environment - 0 != strcasecmp(common_config('site', 'server'), common_config('site', 'sslserver'))) { - - $url = common_local_url('all', - array('nickname' => - $user->nickname)); - $this->redirectFromSSL($user, $url, $this->boolean('rememberme')); - return; - } - $this->showSuccess(); } else { $this->showForm(_('Invalid username or password.')); @@ -589,32 +579,5 @@ class RegisterAction extends Action $nav = new LoginGroupNav($this); $nav->show(); } - - function redirectFromSSL($user, $returnto, $rememberme) - { - try { - $login_token = Login_token::makeNew($user); - } catch (Exception $e) { - $this->serverError($e->getMessage()); - return; - } - - $params = array(); - - if (!empty($returnto)) { - $params['returnto'] = $returnto; - } - - if (!empty($rememberme)) { - $params['rememberme'] = $rememberme; - } - - $target = common_local_url('otp', - array('user_id' => $login_token->user_id, - 'token' => $login_token->token), - $params); - - common_redirect($target, 303); - } } From dd7195346c8fbf928ae7087fb7d342e62a4dce39 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 10 Jan 2010 22:59:32 -0800 Subject: [PATCH 12/16] Sever -> server in error message --- lib/util.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/util.php b/lib/util.php index 50bd0e2ac9..7093d4e439 100644 --- a/lib/util.php +++ b/lib/util.php @@ -809,14 +809,14 @@ function common_path($relative, $ssl=false) } else if (common_config('site', 'server')) { $serverpart = common_config('site', 'server'); } else { - common_log(LOG_ERR, 'Site Sever not configured, unable to determine site name.'); + common_log(LOG_ERR, 'Site server not configured, unable to determine site name.'); } } else { $proto = 'http'; if (common_config('site', 'server')) { $serverpart = common_config('site', 'server'); } else { - common_log(LOG_ERR, 'Site Sever not configured, unable to determine site name.'); + common_log(LOG_ERR, 'Site server not configured, unable to determine site name.'); } } From e0eb51e4bb51f17b0281b7ec4e3d4eca33240978 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Sun, 10 Jan 2010 23:51:57 -0800 Subject: [PATCH 13/16] add session ID to local URL when server parts differ --- lib/util.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/lib/util.php b/lib/util.php index 7093d4e439..90d4a6532e 100644 --- a/lib/util.php +++ b/lib/util.php @@ -820,6 +820,25 @@ function common_path($relative, $ssl=false) } } + if (common_have_session()) { + + $currentServer = $_SERVER['HTTP_HOST']; + + // Are we pointing to another server (like an SSL server?) + + if (!empty($currentServer) && + 0 != strcasecmp($currentServer, $serverpart)) { + // Pass the session ID as a GET parameter + $sesspart = session_name() . '=' . session_id(); + $i = strpos($relative, '?'); + if ($i === false) { // no GET params, just append + $relative .= '?' . $sesspart; + } else { + $relative = substr($relative, 0, $i + 1).$sesspart.'&'.substr($relative, $i + 1); + } + } + } + return $proto.'://'.$serverpart.'/'.$pathpart.$relative; } From ae7469a127a3d95237085335b46077460c536814 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 11 Jan 2010 08:39:02 +0000 Subject: [PATCH 14/16] accept session from --- lib/util.php | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/util.php b/lib/util.php index 90d4a6532e..a56a41a577 100644 --- a/lib/util.php +++ b/lib/util.php @@ -166,15 +166,27 @@ function common_ensure_session() if (common_config('sessions', 'handle')) { Session::setSaveHandler(); } + if (array_key_exists(session_name(), $_GET)) { + $id = $_GET[session_name()]; + common_log(LOG_INFO, 'Setting session from GET parameter: '.$id); + } else if (array_key_exists(session_name(), $_COOKIE)) { + $id = $_COOKIE[session_name()]; + common_log(LOG_INFO, 'Setting session from COOKIE: '.$id); + } + if (isset($id)) { + session_id($id); + setcookie(session_name(), $id); + } @session_start(); if (!isset($_SESSION['started'])) { $_SESSION['started'] = time(); - if (!empty($c)) { + if (!empty($id)) { common_log(LOG_WARNING, 'Session cookie "' . $_COOKIE[session_name()] . '" ' . ' is set but started value is null'); } } } + common_debug("Session ID = " . session_id()); } // Three kinds of arguments: @@ -820,8 +832,19 @@ function common_path($relative, $ssl=false) } } + $relative = common_inject_session($relative, $serverpart); + + return $proto.'://'.$serverpart.'/'.$pathpart.$relative; +} + +function common_inject_session($url, $serverpart = null) +{ if (common_have_session()) { + if (empty($serverpart)) { + $serverpart = parse_url($url, PHP_URL_HOST); + } + $currentServer = $_SERVER['HTTP_HOST']; // Are we pointing to another server (like an SSL server?) @@ -830,16 +853,16 @@ function common_path($relative, $ssl=false) 0 != strcasecmp($currentServer, $serverpart)) { // Pass the session ID as a GET parameter $sesspart = session_name() . '=' . session_id(); - $i = strpos($relative, '?'); + $i = strpos($url, '?'); if ($i === false) { // no GET params, just append - $relative .= '?' . $sesspart; + $url .= '?' . $sesspart; } else { - $relative = substr($relative, 0, $i + 1).$sesspart.'&'.substr($relative, $i + 1); + $url = substr($url, 0, $i + 1).$sesspart.'&'.substr($url, $i + 1); } } } - - return $proto.'://'.$serverpart.'/'.$pathpart.$relative; + + return $url; } function common_date_string($dt) From 5ec25a9691cac0f7bfa02fb2f6237f91fc1a2e82 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 11 Jan 2010 08:40:22 +0000 Subject: [PATCH 15/16] inject session before redirect for login --- actions/login.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/actions/login.php b/actions/login.php index 9c47d88b14..8ea3c800b7 100644 --- a/actions/login.php +++ b/actions/login.php @@ -103,6 +103,15 @@ class LoginAction extends Action // CSRF protection - token set in NoticeForm $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { + $st = common_session_token(); + if (empty($token)) { + common_log(LOG_WARNING, 'No token provided by client.'); + } else if (empty($st)) { + common_log(LOG_WARNING, 'No session token stored.'); + } else { + common_log(LOG_WARNING, 'Token = ' . $token . ' and session token = ' . $st); + } + $this->clientError(_('There was a problem with your session token. '. 'Try again, please.')); return; @@ -135,6 +144,7 @@ class LoginAction extends Action if ($url) { // We don't have to return to it again common_set_returnto(null); + $url = common_inject_session($url); } else { $url = common_local_url('all', array('nickname' => From 92deb35bc4dbd4203bce93bffec4cfb58eab032c Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Mon, 11 Jan 2010 08:40:41 +0000 Subject: [PATCH 16/16] inject session before redirect for openid finish login --- plugins/OpenID/finishopenidlogin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/OpenID/finishopenidlogin.php b/plugins/OpenID/finishopenidlogin.php index 987fa92138..d25ce696cf 100644 --- a/plugins/OpenID/finishopenidlogin.php +++ b/plugins/OpenID/finishopenidlogin.php @@ -363,6 +363,7 @@ class FinishopenidloginAction extends Action if ($url) { # We don't have to return to it again common_set_returnto(null); + $url = common_inject_session($url); } else { $url = common_local_url('all', array('nickname' =>