Commit fe195ddc authored by Lisa Seeto's avatar Lisa Seeto Committed by Robert Lyon

Bug 1794628: Clean up session duplication between auth/session and auth/saml

created auth_configure_session_handlers($sessiontype) in auth/lib to
house session handler checks, cleaned up code in auth/session and auth/saml/config/config.

behatnotneeded

Change-Id: Idc84da9122a50fe2a65a76420ce38c853005e69b
Signed-off-by: default avatarLisa Seeto <lisaseeto@catalyst.net.nz>
parent 1d2bad4e
......@@ -546,6 +546,232 @@ function auth_setup () {
}
}
/**
* Check that the session handlers are okay.
*
**/
function auth_configure_session_handlers($sessiontype) {
if ($sessiontype == 'site') {
$sessionhandler = get_config('sessionhandler');
}
else if ($sessiontype == 'saml') {
$sessionhandler = get_config('ssphpsessionhandler');
}
if (empty($sessionhandler)) {
if (is_memcache_configured()) {
$sessionhandler = 'memcached';
}
else {
require_once(get_config('docroot') . 'auth/saml/lib.php');
if (is_redis_configured()) {
$sessionhandler = 'redis';
}
else if (is_sql_configured()) {
$sessionhandler = 'sql';
}
}
}
switch ($sessionhandler) {
case 'memcache':
if ($sessiontype == 'site') {
throw new ConfigSanityException(get_string('memcacheusememcached', 'error'));
break;
}
case 'memcached':
if (is_memcache_configured()) {
if ($sessiontype == 'site') {
if (!extension_loaded(get_config('sessionhandler'))) {
throw new ConfigSanityException(get_string('nophpextension', 'error', get_config('sessionhandler')));
}
ini_set('session.save_handler', 'memcached');
$memcacheservers = get_memcache_servers(true);
ini_set('session.save_path', $memcacheservers);
$sess = new MemcachedSession();
session_set_save_handler($sess, true);
}
else if ($sessiontype == 'saml') {
if (is_memcache_configured()) {
return array(
'name' => 'memcached',
'config' => get_memcache_servers(),
);
}
}
}
else {
//something is wrong with the memcache config
throw new ConfigSanityException(get_string('nomemcacheserversdefined', 'error', get_config('sessionhandler')));
}
break;
case 'file':
if ($sessiontype == 'site') {
$sessionpath = get_config('sessionpath');
ini_set('session.save_path', '3;' . $sessionpath);
// Attempt to create session directories
if (!is_dir("$sessionpath/0")) {
// Create three levels of directories, named 0-9, a-f
Session::create_directory_levels($sessionpath);
}
}
break;
case 'redis':
if (!extension_loaded('redis')) {
throw new ConfigSanityException(get_string('nophpextension', 'error', get_config('sessionhandler')));
}
if (is_redis_configured()) {
if ($sessiontype == 'site') {
$master = get_redis_master();
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://' . $master->ip . ':' . $master->port . '?prefix=' . get_config('redisprefix'));
}
else if ($sessiontype == 'saml') {
return array(
'name' => 'redis',
'sessionhandler' => 'redis',
'config' => get_redis_config(),
);
}
}
else {
//something is wrong with the redis config
throw new ConfigSanityException(get_string('badsessionhandle', 'error', get_config('sessionhandler')));
}
break;
case 'sql':
if ($sessiontype == 'saml') {
if (is_sql_configured()) {
return array(
'name' => 'sql',
'config' => get_sql_config(),
);
}
else {
throw new AuthInstanceException(get_string('errornovalidsessionhandler', 'auth.saml'));
}
}
else {
throw new ConfigSanityException(get_string('wrongsessionhandle', 'error', get_config('sessionhandler')));
}
break;
default:
throw new ConfigSanityException(get_string('wrongsessionhandle', 'error', get_config('sessionhandler')));
break;
}
}
function is_memcache_configured() {
$is_configured = false;
if (!class_exists('Memcached')) {
return $is_configured;
}
foreach (get_memcache_servers() as $server) {
$memcached = new Memcached;
if (!empty($server['host']) && !empty($server['port'])) {
$host = $server['host'];
$port = $server['port'];
$memcached->addServer($host, $port);
// addServer doesn't make a connection to the server
// but if the server is added, but not running pid will be -1
$server_stats = $memcached->getStats();
if ($server_stats[$host . ':' . $port] <= 0) {
$server_version = $memcached->getVersion();
if (empty($server_version[$host . ':' . $port])) {
$is_configured = false;
}
}
else if ($server_stats[$host . ':' . $port]['pid'] > 0) {
$is_configured = true;
}
}
}
return $is_configured;
}
function get_memcache_servers($string = false) {
$memcache_servers = array();
$servers = get_config('memcacheservers');
if (!$servers) {
$servers = '127.0.0.1:11211';
}
if ($string) {
return $servers;
}
$servers = explode(',', $servers);
foreach ($servers as $server) {
$url = parse_url($server);
$host = !empty($url['host']) ? $url['host'] : $url['path'];
$port = !empty($url['port']) ? $url['port'] : 11211;
$memcache_servers[] = array('host' => $host, 'port' => $port);
}
return $memcache_servers;
}
function is_redis_configured() {
return (bool) get_redis_master();
}
function get_redis_master() {
$master = null;
foreach (get_redis_servers() as $server) {
if (!empty($server['server']) && !empty($server['mastergroup']) && !empty($server['prefix'])) {
require_once(get_config('libroot') . 'redis/sentinel.php');
$sentinel = new sentinel($server['server']);
$master = $sentinel->get_master_addr($server['mastergroup']);
}
}
return $master;
}
function get_redis_servers() {
$redissentinelservers = get_config('redissentinelservers');
$redismastergroup = get_config('redismastergroup');
$redisprefix = get_config('redisprefix');
$redis_servers[] = array(
'server' => $redissentinelservers,
'mastergroup' => $redismastergroup,
'prefix' => $redisprefix
);
return $redis_servers;
}
function get_redis_config() {
$servers = get_redis_servers();
$master = get_redis_master();
return array(
'host' => $master->ip,
'port' => (int)$master->port,
'prefix' => $servers[0]['prefix']
);
}
function is_sql_configured() {
$config = get_sql_config();
try {
$connection = new PDO($config['dsn'], $config['username'], $config['password']);
return true;
}
catch (PDOException $e) {
return false;
}
}
function get_sql_config() {
return array(
'dsn' => get_config('ssphpsqldsn'),
'username' => get_config('ssphpsqlusername'),
'password' => get_config('ssphpsqlpassword'),
'prefix' => get_config('ssphpsqlprefix'),
);
}
/**
* Allow auth plugins a chance to authenticate or redirect as needed.
*
......
......@@ -39,38 +39,30 @@ foreach ($metadata_files as $file) {
$memcache_config = array();
$redis_config = array('host' => '', 'port' => 6379, 'prefix' => '');
$sql_config = array('dsn' => '', 'username' => null, 'password' => null, 'prefix' => '');
if (empty(get_config('ssphpsessionhandler'))) {
if (PluginAuthSaml::is_memcache_configured()) {
$sessionhandler = 'memcache';
$memcache_config = PluginAuthSaml::get_memcache_servers();
}
else if (PluginAuthSaml::is_redis_configured()) {
$sessionhandler = 'redis';
$redis_config = PluginAuthSaml::get_redis_config();
}
else if (PluginAuthSaml::is_sql_configured()) {
$sessionhandler = 'sql';
$sql_config = PluginAuthSaml::get_sql_config();
}
else {
throw new AuthInstanceException(get_string('errornovalidsessionhandler', 'auth.saml'));
}
}
else {
$sessionhandler = get_config('ssphpsessionhandler');
if ($sessionhandler == 'memcached') {
$sessionhandler = 'memcache'; // set it to 'memcache' for correct store.type later
$memcache_config = PluginAuthSaml::get_memcache_servers();
}
else {
$method = 'get_' . $sessionhandler . '_config';
if (method_exists('PluginAuthSaml', $method)) {
${$sessionhandler . "_config"} = call_static_method('PluginAuthSaml', $method);
$sessionhandler = '';
$session_config = auth_configure_session_handlers('saml');
if ($session_config) {
if ($session_config['name']) {
if ($session_config['name'] == 'memcached') {
$sessionhandler = 'memcache'; // set it to 'memcache' for correct store.type later
// For mahara session the host is defined as 'host' but for ssphp it is defined as 'hostname'
// so we need to alter it
foreach ($session_config['config'] as $k => $v) {
$session_config['config'][$k]['hostname'] = $session_config['config'][$k]['host'];
unset($session_config['config'][$k]['host']);
}
$memcache_config = $session_config['config'];
}
else if ($session_config['name'] == 'redis') {
$sessionhandler = 'redis';
$redis_config = $session_config['config'];
}
else if ($session_config['name'] == 'sql') {
$sessionhandler = 'sql';
$sql_config = $session_config['config'];
}
}
}
/*
* Get the configured signature algorithm, falling back to SHA256 if no valid
* value is found
......
......@@ -908,27 +908,27 @@ class PluginAuthSaml extends PluginAuth {
throw new ConfigSanityException(get_string('memcacheusememcached', 'error'));
break;
case 'memcached':
if (self::is_memcache_configured()) {
if (is_memcache_configured()) {
$ishandler = true;
break;
}
case 'redis':
if (self::is_redis_configured()) {
if (is_redis_configured()) {
$ishandler = true;
break;
}
case 'sql':
if (self::is_sql_configured()) {
if (is_sql_configured()) {
$ishandler = true;
break;
}
default:
// Check Redis
$ishandler = self::is_redis_configured();
$ishandler = is_redis_configured();
// And check Memcache if no Redis
$ishandler = $ishandler ? $ishandler : self::is_memcache_configured();
$ishandler = $ishandler ? $ishandler : is_memcache_configured();
// And check Sql if no Memcache
$ishandler = $ishandler ? $ishandler : self::is_sql_configured();
$ishandler = $ishandler ? $ishandler : is_sql_configured();
}
return $ishandler;
......@@ -953,105 +953,6 @@ class PluginAuthSaml extends PluginAuth {
SimpleSAML_Configuration::init(get_config('docroot') . 'auth/saml/config');
}
public static function is_memcache_configured() {
$is_configured = false;
if (extension_loaded('memcached')) {
foreach (self::get_memcache_servers() as $server) {
$memcached = new Memcached;
if (!empty($server['hostname']) && !empty($server['port'])) {
$memcached->addServer($server['hostname'], $server['port']);
// addServer doesn't make a connection to the server
// but if the server is added, but not running pid will be -1
$server_stats = $memcached->getStats();
if ($server_stats[$server['hostname'] . ":" . $server['port']]['pid'] > 0) {
$is_configured = true;
break;
}
}
}
}
return $is_configured;
}
public static function get_memcache_servers() {
$memcache_servers = array();
$servers = get_config('memcacheservers');
if (empty($servers)) {
$servers = 'localhost';
}
$servers = explode(',', $servers);
foreach ($servers as $server) {
$url = parse_url($server);
$host = !empty($url['host']) ? $url['host'] : $url['path'];
$port = !empty($url['port']) ? $url['port'] : 11211;
$memcache_servers[] = array('hostname' => $host, 'port' => $port);
}
return $memcache_servers;
}
public static function is_redis_configured() {
return (bool) PluginAuthSaml::get_redis_master();
}
public static function get_redis_master() {
$master = null;
if (extension_loaded('redis')) {
foreach (self::get_redis_servers() as $server) {
if (!empty($server['server']) && !empty($server['mastergroup']) && !empty($server['prefix'])) {
require_once(get_config('libroot') . 'redis/sentinel.php');
$sentinel = new sentinel($server['server']);
$master = $sentinel->get_master_addr($server['mastergroup']);
}
}
}
return $master;
}
public static function get_redis_config() {
$servers = PluginAuthSaml::get_redis_servers();
$master = PluginAuthSaml::get_redis_master();
return array('host' => $master->ip,
'port' => (int)$master->port,
'prefix' => $servers[0]['prefix']
);
}
public static function get_redis_servers() {
$redissentinelservers = get_config('redissentinelservers');
$redismastergroup = get_config('redismastergroup');
$redisprefix = get_config('redisprefix');
$redis_servers[] = array('server' => $redissentinelservers,
'mastergroup' => $redismastergroup,
'prefix' => $redisprefix);
return $redis_servers;
}
public static function is_sql_configured() {
$config = PluginAuthSaml::get_sql_config();
try {
$connection = new PDO($config['dsn'], $config['username'], $config['password']);
return true;
}
catch (PDOException $e) {
return false;
}
}
public static function get_sql_config() {
return array('dsn' => get_config('ssphpsqldsn'),
'username' => get_config('ssphpsqlusername'),
'password' => get_config('ssphpsqlpassword'),
'prefix' => get_config('ssphpsqlprefix'),
);
}
public static function get_idps($xml) {
$xml = new SimpleXMLElement($xml);
......
......@@ -87,85 +87,7 @@ class Session {
}
// Now lets use the correct session handler
// Currently only deals with file and memcached
switch (get_config('sessionhandler')) {
case 'memcache':
throw new ConfigSanityException(get_string('memcacheusememcached', 'error'));
break;
case 'memcached':
$memcacheservers = get_config('memcacheservers');
if (!$memcacheservers) {
throw new ConfigSanityException(get_string('nomemcacheserversdefined', 'error', get_config('sessionhandler')));
}
if (!extension_loaded(get_config('sessionhandler'))) {
throw new ConfigSanityException(get_string('nophpextension', 'error', get_config('sessionhandler')));
}
// Because we only want memcached servers we need to strip off any 'tcp://' if accidentally added
$servers = preg_replace('#tcp://#', '', $memcacheservers);
foreach (explode(',', $servers) as $server) {
list($destination, $port) = explode(':', $server);
$memcached = new Memcached;
if (!empty($destination) && !empty($port)) {
$memcached->addServer($destination, $port);
// addServer doesn't make a connection to the server
// but if the server is added, but not running pid will be -1
$server_stats = $memcached->getStats();
if ($server_stats[$destination . ":" . $port]['pid'] <= 0) {
// can't reach the destination:port
$server_version = $memcached->getVersion();
if (empty($server_version[$destination . ":" . $port])) {
throw new ConfigSanityException(get_string('nomemcachedserver', 'error', $server));
}
}
}
else {
throw new ConfigSanityException(get_string('nomemcachedserver', 'error', $server));
}
}
ini_set('session.save_handler', 'memcached');
ini_set('session.save_path', $servers);
$sess = new MemcachedSession();
session_set_save_handler($sess, true);
break;
case 'file':
$sessionpath = get_config('sessionpath');
ini_set('session.save_path', '3;' . $sessionpath);
// Attempt to create session directories
if (!is_dir("$sessionpath/0")) {
// Create three levels of directories, named 0-9, a-f
Session::create_directory_levels($sessionpath);
}
break;
case 'redis':
if (!extension_loaded(get_config('sessionhandler'))) {
throw new ConfigSanityException(get_string('nophpextension', 'error', get_config('sessionhandler')));
}
else if (
($redissentinelservers = get_config('redissentinelservers')) &&
($redismastergroup = get_config('redismastergroup')) &&
($redisprefix = get_config('redisprefix'))
) {
require_once(get_config('libroot') . 'redis/sentinel.php');
$sentinel = new sentinel($redissentinelservers);
$master = $sentinel->get_master_addr($redismastergroup);
if (!empty($master)) {
ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://' . $master->ip . ':' . $master->port . '?prefix=' . $redisprefix);
}
else {
throw new ConfigSanityException(get_string('badsessionhandle', 'error', get_config('sessionhandler')));
}
}
else {
throw new ConfigSanityException(get_string('badsessionhandle', 'error', get_config('sessionhandler')));
}
break;
default:
throw new ConfigSanityException(get_string('wrongsessionhandle', 'error', get_config('sessionhandler')));
}
auth_configure_session_handlers('site');
}
public static function create_directory_levels($sessionpath) {
......
......@@ -251,6 +251,7 @@ if (isset($CFG->wwwroot)) {
}
}
require_once('auth/lib.php');
// Start up a session object, in case we need to use it to print messages
require_once('auth/session.php');
$SESSION = Session::singleton();
......@@ -390,9 +391,6 @@ if (!defined('CLI')) {
}
}
// Only do authentication once we know the page theme, so that the login form
// can have the correct theming.
require_once('auth/lib.php');
$USER = new LiveUser();
if (function_exists('local_init_user')) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment